野牛转移减少冲突,我不知道在哪里

时间:2012-06-15 22:51:46

标签: parsing conflict bison reduce shift

语法:http://pastebin.com/ef2jt8Rg y.output:http://pastebin.com/AEKXrrRG

我不知道那些冲突在哪里,有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:7)

y.output文件确切地告诉您冲突的确切位置。第一个是状态4,所以如果你去看状态4,你会看到:

state 4

   99 compound_statement: '{' . '}'
  100                   | '{' . statement_list '}'

    IDENTIFIER      shift, and go to state 6
          :
    IDENTIFIER  [reduce using rule 1 (threat_as_ref)]
    IDENTIFIER  [reduce using rule 2 (func_call_start)]

这告诉你,在这种状态下(解析compound_statement,看到{),并查看下一个令牌是IDENTIFIER,它可能有3种可能do - 移动令牌(这将是statement_list的开头),减少threat_as_ref空制作,或减少func_call_start空制作。

括号告诉您它已经决定永远不会执行这些操作 - 默认的“更喜欢转换减少”冲突解决方案意味着它将始终进行转换。

你的语法问题是这些空的规则threat_as_reffunc_call_start - 在转移IDENTIFIER之前需要减少它们,但是为了知道它们是否有效,解析器需要在识别之后看到令牌。只有当这是函数调用的开始时才会减少func_call_start(这取决于IDENTIFIER之后是(。)因此解析器需要更多的前瞻来处理你的gramar。在你的特定情况下,你的语法是LALR(2)(2个令牌前瞻就足够了),但不是LALR(1),所以野牛不能处理它。

现在你可以通过删除那些空的规则来修复它 - func_call_start根本没有任何操作,threat_as_ref的操作可以移动到variable的操作中,但如果您希望将来这些规则可能存在问题。

答案 1 :(得分:0)

(1)我看到至少有一件看起来很奇怪的事情。您expression_statement的作品与postfix_statement的作品类似,但不完全相同。他们没有'('和')'代币:

expression_statement
    : ';'
    | expression ';'
    | func_call_start IDENTIFIER { ras_parse_variable_psh($2); aFree($2); } func_call_end ';'
    | func_call_start IDENTIFIER { ras_parse_variable_psh($2); aFree($2); } argument_expression_list func_call_end ';'
    ;

由于expression可以是primary_expression,可以是IDENTIFIER,因为func_call_startfunc_call_end是epsilon(null)制作,提供输入

foo;

解析器必须决定是否应用

expression_statement : expression ';'

expression_statement :  func_call_start IDENTIFIER { ras_parse_variable_psh($2); aFree($2); } func_call_end ';'

(2)另外,我不确定这一点,但我怀疑epsilon非终端threat_as_ref可能会给你带来一些麻烦。我没有追踪它,但可能有一种情况,解析器必须决定某些东西是variable_ref还是variable