2013-04-20 149 views
0

我收到一个降低/减少以下语法(excerp)冲突野牛减少/减少冲突

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:=酒吧,有两种可能的派生:

  1. 勘定> ID “:=” 参数和param - > ID
  2. 勘定> ID “:=” EXPR和expr-> ID

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

我试图以两种possibilies分裂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 ')' 

但在这种情况下,我怎样才能在词法分析器differenciate这两个(ID_SCAL和ID_PATH) ?

回答

0

那么,正如你所诊断的那样,问题在于你的语法是不明确的 - 它有两种不同的方式来解析输入,如Foo := Bar。所以你需要决定的第一件事是,它应该是什么?你怎么知道?如果你(阅读代码的人)看到你想要解析的语言,你会怎么知道Bar是一个表达式还是一个没有relative_param的参数?

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

如果它取决于Foo先前的声明,那么你做同样的事情,但你需要改变的语法是更多的东西一样:

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

事实上的分配:'FOO:=酒吧'依赖于之前的bar声明。谢谢! @ChisDodd – 2013-04-20 19:25:29