我目前正在编写一个类似Visual Basic的LALR(1)语法,并面对这个特殊的转换/减少冲突,我不知道如何正确解决它。由于括号冲突/减少LALR(1)冲突
语法的问题的部分是(请参见EDIT 1和EDIT 2澄清):
Expression
: IndexExpression
| /* other expressions */
IndexExpression
: MemberExpression
| MemberExpression '(' ArgumentList ')'
MemberExpression
: ParenthesizedExpression
| Identifier
ParenthesizedExpression
: '(' Expression ')'
ArgumentList
: Expression
| Expression ',' ArgumentList
| ',' ArgumentList
和移位/减少冲突是这样的:
State 109
237 ParenthesizedExpression: '(' Expression ')' .
$default reduce using rule 237 (ParenthesizedExpression)
...
State 295
231 IndexExpression: MemberExpression '(' . ArgumentList ')'
237 ParenthesizedExpression: '(' . Expression ')'
...
Expression go to state 352
...
State 352
182 ArgumentList: Expression .
183 | Expression . ',' ArgumentList
237 ParenthesizedExpression: '(' Expression . ')'
...
')' shift, and go to state 109
')' [reduce using rule 182 (ArgumentList)]
换句话说,解析器在面对由圆括号包装的表达式时不确定,无论是具有单个expre的ArgumentList ssion或括号表达式。
有什么办法可以解决这个冲突,同时把语法保持为LALR(1)?
谢谢。
编辑1:
/*其他表达式* /在表达其实不是一个空的表情,我只是写它为简洁的方式。实际上它具有其它替代的表达式:
Expression
: IndexExpression
| Expression '+' Expression
| ...
编辑2:
以下是其中@rici指出可能是有问题的语法(尤其声明的第一右手规则的附加部分):
Statement
: MemberExpression ArgumentList
| MemberExpression '=' Expression
| MemberExpression '(' ArgumentList ')' '=' Expression
| ...
你需要展示更多的语法。或者,更好的是,创建一个具有相同问题但只有少数几部作品的可重新编译的语法。顺便说一下,'argument_list'语法很奇怪。为什么你觉得用左递归编写它是有用的,在LALR(1)解析器中通常应该避免使用左递归?多重缺失的观点意味着什么?如果所有其他参数都可以省略,为什么最后一个不能呢? – rici
您是否允许在不带圆括号的情况下调用带有一个参数的函数的VB语法?如果是这样,那很可能是你的问题。 – rici
@rici **缺少参数**:在这个特定的VB语言中,它允许参数列表具有空参数,除了最后一个。由于我不想让_Expression_变为空,我最终将_ArgumentList_中的第三条规则放置了。 **括号括起来的一个参数**:是的!事实上,在昨天更深入地寻找根本原因之后,我得出结论认为这可能是原因。你有关于如何包含这个语法的建议吗? –