这是一个 QML 语法(摘自 https://github.com/kropp/intellij-qml/blob/master/grammars/qml.bnf ):
/* 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) 吗?我的程序引发了闭包 I[n] 的归约/归约冲突,其中包含冲突项:
// other items here...
[item ::= identifier . , {] // -> ACTION[n, {] = reduce to item
[type ::= identifier . , {] // -> ACTION[n, {] = reduce to type
// other items here...
最佳答案
注意:
以下答案是根据问题中提供的信息编写的。事实上,QML 的实际实现只接受名称以大写字母开头的类型的用户声明,而属性名称必须以小写字母开头。 (许多内置类型的名称也以小写字母开头。因此,这并不像在词法扫描中根据首字母将标识符分为两类那么简单。内置类型和关键字仍然需要被认为是这样的。)
不幸的是,我无法找到明确的 QML 语法,甚至找不到该语法的正式描述。以上评论基于Qt's QML Reference .
感谢@mishmashru让我注意到上述内容。
语法不明确,因此解析器生成器可以正确识别归约/归约冲突。
特别是,考虑从语法中提取的以下简化产生式,其中大多数替代方案已被删除以重点关注冲突:
body ::= '{' attribute_assignment* '}'
attribute_assignment ::= attribute_value
attribute_value ::= method_body | item
method_body ::= '{' javascript '}'
item ::= object | identifier
object ::= type body
type ::= identifier
现在,考虑开始的body
{ x {
我们假设解析器刚刚看到x
,现在正在查看第二个{
,以找出要采取的操作。
如果x
是一个普通标识符(无论“普通”可能意味着什么,那么它可以解析为item
,这是attribute_value
的替代品) >。然后第二个 {
可能启动一个 method_body
,它也是 attribute_value
的替代方案。
另一方面,如果x
是一个类型
,那么我们正在寻找一个对象
,它以开头输入正文
。在这种情况下,第二个 {
是内部 body
的开始。
因此解析器需要决定是直接将x
变成attribute_value
,还是将其变成type
。此时无法做出决定,因为 {
前瞻标记未提供足够的信息。
所以很明显该文法不是 LR(1)。
如果不了解有关问题领域的更多信息,就很难提供好的建议。如果可以区分identifier
和type
,也许通过查阅符号表,那么您可以通过使用某种词法反馈来解决这个问题。
关于qml - QML 语法是 LALR(1) 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59303443/