【问题标题】:LALR(1) empty list of parameters for functionsLALR(1) 函数的空参数列表
【发布时间】:2010-01-16 17:05:00
【问题描述】:

我有一个简单的 LALR(1) 语法,但我遇到了问题。

start ::= spec.
spec ::= MOD STRING top_stmt.
spec ::= top_stmt.
top_stmt ::= stmt.
top_stmt ::= conditional.
stmt ::= expr.
stmt ::= assignment.
conditional ::= IF stmt_list.
expr ::= retval.
expr ::= NOT retval.
retval ::= access.
retval ::= invoke.
access ::= ns_identifier OBJECT_OPERATOR property_chain.
access ::= ns_identifier.
ns_identifier ::= identifier.
ns_identifier ::= ns_identifier NS_SEPARATOR identifier.
ns_identifier ::=.
property_chain ::= property_chain OBJECT_OPERATOR identifier.
property_chain ::= identifier.
identifier ::= VARIABLE.
identifier ::= STRING.
assignment ::= access ASSIGN expr. [ASSIGN]
stmt_list ::= stmt.
stmt_list ::= stmt_list COMMA stmt. [COMMA]
invoke ::= access LPAREN empty_stmt_list RPAREN.
empty_stmt_list ::=.
empty_stmt_list ::= stmt.
empty_stmt_list ::= empty_stmt_list COMMA stmt. [COMMA]

点标记规则的结束,括号之间的终端具有关联性:ASSIGN 是右关联的,COMMA 是左关联的。

但是lemon 说它不能减少规则“empty_stmt_list ::=”。因为它没有连接到开始符号。我敢打赌是:-)

“invoke”也存在解析冲突,当empty_stmt_list确实是一个empy语句列表时,它无法在RPAREN和COMMA之间做出决定。

我想要实现的是能够解析没有(void)参数的函数调用。

其他一切都按预期工作。

谢谢

编辑:我已经编辑了我的原始帖子并发布了整个精简的语法。

【问题讨论】:

  • 你的符号并不完全是传统的——它是受 ANTLR 启发的吗?括号中的“(A)”和“(B)”是什么?孤独的'。'有什么意义?在符号?它似乎是一个表示规则结束的元字符,接下来是动作。

标签: parsing grammar lalr lemon


【解决方案1】:

你的第一个问题是我不认为这个位能达到你想要的效果:

invoke ::= access LPAREN empty_stmt_list RPAREN.
empty_stmt_list ::=.
empty_stmt_list ::= stmt.
empty_stmt_list ::= empty_stmt_list COMMA stmt. [COMMA]

invoke 生产将匹配 access LPAREN COMMA stmt RPAREN,我认为这是不可取的(并且是 LPAREN/COMMA 冲突的来源)。

您可以像这样使用现有的stmt_list 规则来解决此问题:

invoke ::= access LPAREN maybe_empty_stmt_list RPAREN.
maybe_empty_stmt_list ::= .
maybe_empty_stmt_list ::= stmt_list.

这仍然报告冲突(但现在只有 1 个)并且仍然抱怨 maybe_empty_stmt_list ::=. 无法减少。所以,查看 XXX.out 文件看看它是什么:

State 2:
...
     (16) ns_identifier ::= *
...
     (25) maybe_empty_stmt_list ::= *
...
                        RPAREN reduce 25  ** Parsing conflict **
....
                     {default} reduce 16

...看来问题出在ns_identifier ::=. 规则上。回顾所涉及的产品,不难看出空的@9​​87654330@ 可以简化为stmt_list(通过ns_identifier -> access -> retval -> expr -> @987654336 @ -> stmt_list)。

这解释了冲突;事实上,ns_identifier ::=. 规则在这种情况下受到青睐,因为它出现在语法的较早部分(请参阅documentation 中解决减少-减少冲突的规则)解释了为什么它抱怨 maybe_empty_stmt_list ::=. 规则永远不能减少。

【讨论】:

  • 非常感谢,我完全修复了它,包括删除空的 ns_identfier 规则,这实际上是解决另一个旧问题的人工制品。自我注释:设计语言解析器需要小心和“做对”的心态。接受的答案。
【解决方案2】:

您可以尝试为 LPAREN/COMMA 添加优先规则,并检查它是否会影响其他地方的语义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多