Bison 野牛减少/减少冲突

Bison 野牛减少/减少冲突,bison,context-free-grammar,Bison,Context Free Grammar,我在以下语法上遇到了reduce/reduce冲突(excerp) 我看到当输入为:foo:=bar时,有两种可能的派生: 分配->标识“:=“参数和参数->标识 分配->标识“:=“expr和expr->标识 我在语法中使用了两次ID,因为变量的类型可以是path或scal。 如何在不使用glr解析器选项的情况下删除此冲突 我尝试将ID拆分为两种可能性:ID_PATH和ID_SCAL,并将productions param和expr更改为: param : point relative_par

我在以下语法上遇到了reduce/reduce冲突(excerp)

我看到当输入为:foo:=bar时,有两种可能的派生:

  • 分配->标识“:=“参数和参数->标识
  • 分配->标识“:=“expr和expr->标识
  • 我在语法中使用了两次ID,因为变量的类型可以是path或scal。 如何在不使用glr解析器选项的情况下删除此冲突

    我尝试将ID拆分为两种可能性:ID_PATH和ID_SCAL,并将productions param和expr更改为:

    param : point relative_param
            | ID_PATH relative_param
            ;
    
      expr : NB
           | ID_SCAL
           | expr '+' expr
           | expr '-' expr
           | expr '/' expr
           | '(' expr ')'
    

    但是在这种情况下,我如何区分lexer中的这两个(ID\u SCAL和ID\u PATH)?

    好吧,正如您所诊断的,问题是您的语法不明确——它有两种不同的方式解析输入,如
    Foo:=Bar
    。所以你需要决定的第一件事是,应该是哪一件?你怎么知道的?如果你(阅读代码的人)在你试图解析的语言中看到了这一点,你怎么知道
    Bar
    是一个表达式还是一个没有相对参数的参数

    如果它依赖于先前的
    Bar
    声明,那么这就是您需要解决此问题的方法。您需要在符号表中保留有关先前看到的声明的信息,然后在lexer中使用该符号表来查找它们被识别的标识符,以便决定lexer是否应该返回
    ID\u PATH
    ID\u SCAL

    如果它依赖于前面的
    Foo
    声明,那么您可以执行类似的操作,但需要将语法更改为类似于:

    assignment: ID_PATH ":=" param
              | ID_SCAL ":=" expr
              ;
    

    事实上,赋值:
    foO:=bar
    取决于先前的bar声明。谢谢你@奇斯多德
    assignment: ID_PATH ":=" param
              | ID_SCAL ":=" expr
              ;