首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QML语法LALR(1)?

QML语法LALR(1)?
EN

Stack Overflow用户
提问于 2019-12-12 11:20:50
回答 1查看 228关注 0票数 2

下面是一个QML语法(从https://github.com/kropp/intellij-qml/blob/master/grammars/qml.bnf中提取):

代码语言:javascript
复制
/* identifier, value, integer and float are terminals */

qml ::= object  /* Simplified */

object ::= type body
body ::= '{' (property_definition|signal_definition|attribute_assignment|method_attribute)* '}'
type ::= 'double'|'real'|identifier

attribute_assignment ::= (attribute ':')? attribute_value ';'?
item ::= list|object|string|boolean|number|identifier|value
attribute_value ::= method_call|method_body|item|value+

property_definition ::= 'default'? 'readonly'? 'property' ('alias'|'var'|type) property (':' attribute_value)?
signal_definition ::= 'signal' signal ('(' (signal_parameter ',')* signal_parameter? ')')?
signal_parameter ::= ('var'|type) parameter

method_attribute ::= 'function' method '(' (parameter ',')* parameter? ')' method_body

method_call ::= method '(' (argument ',')* argument? ')'

method_body ::= '{' javascript '}'
javascript ::= ('{' javascript '}'|'var'|'['|']'|'('|')'|','|':'|';'|string|identifier|number|value)*

list ::= '[' item? (',' item)* ']'

property ::= identifier
attribute ::= identifier
signal ::= identifier
parameter ::= identifier
method ::= identifier
argument ::= string|boolean|number|identifier|value

number ::= integer|float
boolean ::= 'true'|'false'

是LALR(1)吗?我的程序为包含冲突项的闭包引发了一个减少/减少冲突:

代码语言:javascript
复制
// other items here...
[item ::= identifier . , {]  // -> ACTION[n, {] = reduce to item  
[type ::= identifier . , {]  // -> ACTION[n, {] = reduce to type  
// other items here...
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-12 15:13:41

注意:

以下答复是根据问题中提供的资料编写的。实际上,QML的实际实现只接受以大写字母开头的类型的用户声明,而属性的名称必须以小写字母开头。(许多内置类型的名称也以小写字母开头。因此,这并不像在词法扫描中根据第一个字母将标识符分为两类那么简单。内建类型和关键字仍然需要被确认为这样。)

不幸的是,我还没有找到确定的QML语法,甚至没有对语法的正式描述。以上评论是基于Qt的QML参考的。

感谢@mishmashru让我注意到了这一点。

语法是模棱两可的,因此解析器生成器正确地识别了一个减少/减少冲突。

特别是,考虑从语法中提取的以下简化结果,其中大多数可供选择的内容已被移除,以侧重于冲突:

代码语言:javascript
复制
body ::= '{' attribute_assignment* '}'
attribute_assignment ::= attribute_value
attribute_value ::= method_body | item
method_body ::= '{' javascript '}'
item ::= object | identifier
object ::= type body
type ::= identifier

现在,考虑一下启动的body

代码语言:javascript
复制
{ x {

我们假设解析器刚刚看到了x,现在正在查看第二个{,以确定要采取什么操作。

如果x是一个普通标识符(不管“普通”是什么意思),那么它可以解析为item,这是attribute_value的另一种选择。然后,第二个{可能启动一个method_body,这也是attribute_value的一个替代方案。

另一方面,如果x是一个type,那么我们将看到一个object,它启动type body。在这种情况下,第二个{是内部body的开始。

因此,解析器需要决定是直接将x变成attribute_value,还是将其变成type。此时不能作出决定,因为{前瞻性令牌没有提供足够的信息。

所以很明显语法不是LR(1)。

如果不对问题领域有更多的了解,就很难给出好的建议。如果有可能区分identifiertype,也许可以参考符号表,那么您可以使用某种词汇反馈来解决这个问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59303443

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档