如何解决 bison 文件中的歧义?

问题描述 投票:0回答:1

我正在开发一个简单的解释器,我正在使用 bison 和 flex 作为我的词法分析器和解析器。当涉及到解析器时我遇到了问题:

progr          :decl_classes decl_gvars  decl_functions block {printf("The programme is correct!\n");}
               ;/*1. classes 2.global vars 3.functii 4.enetry point*/

decl_classes   :decl_class ';' decl_classes
                   |{cout<<"No more classes\n";}
               ;
decl_class     :CLASS ID '{' decl_gvars decl_functions '}'  {cout<<"We have a class :"<<$2<<"\n";}
               ;    

decl_functions :{cout<<"No more functions\n";}
               |decl_function ';' decl_functions
               ;
decl_function  :TYPE ID '('list_param')' '{'list'}' 
               
               ;
decl_gvars     :decl_gvar ';' decl_gvars 
               |{cout<<"No more gvars\n";}
               ;
decl_gvar      :typedecl list_ID  {cout<<"We have vars "<<endl;}
               ;


typedecl : TYPE {cout<<"Try to make a var\n";}
           ;

list_ID : ID '[' expr ']' 
        | ID 
        | ID ',' list_ID 
        ;
list_param :param ',' list_param
            |/*none*/
            ;
            
param     :typedecl ID
          |typedecl ID '['expr']'
          ; 
      

block : BGIN list END  
     ;
     

list :  statement ';' 
     | list statement ';'
     |/*none*/
     ;

解析器总是选择使用 decl_gvar 而不是 decl_function。任何帮助将不胜感激。

我测试了解析器是否会生成我的 decl_function(如果它是隔离的)并且确实如此。

c++ grammar bison bisonc++
1个回答
0
投票

基本问题是,在看到

TYPE
后,当下一个标记是
ID
时,它还不知道它是在查看 decl_function 还是 decl_gvar,但你的语法强制它将
typedecl
减少到识别 decl_gvar 或不简化它以识别 decl_function。由于默认情况下会优先于归约进行移位,因此解析器将始终尝试将其解析为 decl_function,即使它实际上是 decl_gvar (并且在这种情况下会出现语法错误。

最简单的解决方法是摆脱

typedecl : TYPE
规则(并在 decl_gvar 规则中将
typedecl
替换为
TYPE
。这样,您就不需要减少,事情将被推迟到
ID 之后) 
标记,因此它将能够看到
(
来识别函数,或者看到
,
;
来识别 gvar。

© www.soinside.com 2019 - 2024. All rights reserved.