2017-02-23 65 views
0

我目前正在编写一个类似Visual Basic的LALR(1)语法,并面对这个特殊的转换/减少冲突,我不知道如何正确解决它。由于括号冲突/减少LALR(1)冲突

语法的问题的部分是(请参见EDIT 1EDIT 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 
    | ... 
+0

你需要展示更多的语法。或者,更好的是,创建一个具有相同问题但只有少数几部作品的可重新编译的语法。顺便说一下,'argument_list'语法很奇怪。为什么你觉得用左递归编写它是有用的,在LALR(1)解析器中通常应该避免使用左递归?多重缺失的观点意味着什么?如果所有其他参数都可以省略,为什么最后一个不能呢? – rici

+1

您是否允许在不带圆括号的情况下调用带有一个参数的函数的VB语法?如果是这样,那很可能是你的问题。 – rici

+0

@rici **缺少参数**:在这个特定的VB语言中,它允许参数列表具有空参数,除了最后一个。由于我不想让_Expression_变为空,我最终将_ArgumentList_中的第三条规则放置了。 **括号括起来的一个参数**:是的!事实上,在昨天更深入地寻找根本原因之后,我得出结论认为这可能是原因。你有关于如何包含这个语法的建议吗? –

回答

2

的错误是因为Expression允许为空,因为评论规则/* other expressions */,一nd被假定不是空的。

下面显示了其中在两个等效规则使用Expression结果:

ArgumentList 
    : Expression 
    | Expression ',' ArgumentList /* degenerates into "',' ArgumentList" */ 
    | ',' ArgumentList 
    ; 

移位的数目/减少冲突是用于次ArgumentList被引用的数目(一次在IndexExpression和两次在ArgumentList本身)

要删除冲突要么修复ArgumentList一个空Expression的情况下:

ArgumentList 
    : Expression 
    | ArgumentList ',' Expression 
    ; 

或确保Expression永不为空(删除注释的规则)。

+0

您好kdhp,请参阅我的编辑1进行澄清。对不起,我原来的帖子不明确。 –

+1

@SamTatasurya没有看到表达式列表我只能猜测或者有另一个空值,一个运算符没有被声明为'%left' /'%right',或者有另一个规则''('Expression' )''(也通过'IndexExpression-> MemeberExpression-> ParenthesizedExpression'出现) – kdhp