野牛减少/减少冲突

时间:2013-04-20 16:27:44

标签: bison context-free-grammar

我在下面的语法(摘录)

上得到减少/减少冲突
 declaration : type list_of_id

        list_of_id : ID                             
                   | list_of_id ',' ID              
                   ;

        type : PATH   
             | SCAL 
             ;

        assignment : ID ":=" param
                   | ID ":=" expr

        param :  point relative_param
              | ID relative_param   

        point : '(' expr ',' expr ')'
              | '(' expr  ':' expr ')'

         relative_param : /* empty rule */ 
                        | "--" '+' param
                        | "--" CYCLE relative_param     
                        | "--" param 

        expr : NB                          
             | ID                         ``                               
             | expr '+' expr              
             | expr '-' expr             
             | expr '*' expr                   
             | expr '/' expr                   
             | '(' expr ')'

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

  1. 勘定> ID“:=”param和param - > ID
  2. 勘定> ID“:=”expr和expr-> ID
  3. 我在语法中使用了两次ID,因为变量可以是path或scal类型。 如何在不使用glr-parser选项的情况下删除此冲突?

    我试图将ID分成两个可能的ID:ID_PATH和ID_SCAL,并将产品param和expr更改为:

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

    但在这种情况下,我如何区分词法分析器中的那两个(ID_SCAL和ID_PATH)?

1 个答案:

答案 0 :(得分:0)

好吧,正如你已经诊断出来的那样,问题是你的语法含糊不清 - 它有两种不同的解析输入方式,如Foo := Bar。所以你需要决定的第一件事是,它应该是什么?你怎么知道的?如果你(阅读代码的人)要用你试图解析的语言看到这个,你怎么知道Bar是一个表达式还是一个没有relative_param的param?

如果它取决于先前对Bar的一些声明,那么你需要解决这个问题。您需要在符号表中保留有关以前看到的声明的信息,然后在词法分析器中使用该符号表来查找它们被识别的标识符,以便确定词法分析器是否应该返回ID_PATH或{{1} }。

如果它取决于先前的ID_SCAL声明,那么你会做类似的事情,但你需要将语法改为更像:

Foo