0

我在以下语法上遇到了减少/减少冲突(摘录)

 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 ":=" 参数和参数-> ID
  2. assignment-> ID ":=" expr 和 expr-> ID

我在语法中使用了两次 ID,因为变量可以是 path 类型或 scal 类型。如何在不使用 glr-parser 选项的情况下消除此冲突?

我试图将 ID 拆分为两种可能性: ID_PATH 和 ID_SCAL 并将产品参数和 expr 更改为:

param : point relative_param
        | ID_PATH relative_param
        ;

  expr : NB
       | ID_SCAL
       | expr '+' expr
       | expr '-' expr
       | expr '/' expr
       | '(' expr ')'

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

4

1 回答 1

0

好吧,正如您所诊断的那样,问题在于您的语法是模棱两可的——它有两种不同的方式来解析输入,例如Foo := Bar. 因此,您需要决定的第一件事是,应该是哪一个?你怎么知道?如果您(阅读代码的人)在您尝试解析的语言中看到这一点,您怎么知道Bar是表达式还是没有 relative_param 的参数?

如果它依赖于之前的一些声明Bar,那么这就是你需要解决的方法。您需要将有关先前看到的声明的信息保存在符号表中,然后在词法分析器中使用该符号表来查找它们被识别的标识符,以确定词法分析器是否应该返回ID_PATHID_SCAL

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

assignment: ID_PATH ":=" param
          | ID_SCAL ":=" expr
          ;
于 2013-04-20T18:20:56.687 回答