为函数原型和声明 bison 创建语法

Creating a grammar for function prototypes and declaration bison

我正在为一个学校项目构建一个编译器。一切正常,但我很难为函数定义语法。我必须检测是否有零个或多个参数,以及函数是原型还是定义。我不断收到 shift/reduce and/or reduce/reduce 错误。我尝试了很多变体但无济于事。这就是我所拥有的,只是在寻找另一个方向的指示或有关如何解决此问题的想法。

function   : parameters ';'   {free_ast(); $$ = ;}
           | parameters block {$$ = adopt1(, )}
           ;

parameters : paramlist ')'   {free_ast(); $$ = ;}
           | '(' identdecl ')' {free_ast(); $$ = adopt_func2(, );}
           ;

paramlist  : paramlist ',' identdecl {free_ast();
                                      $$ = adopt1(, );}
           | '(' identdecl           {$$ = adopt_func2(, );}

identdecl  : basetype TOK_ARRAY TOK_IDENT {$$ = adopt2(, ,
                                           change_symbol(
                                           , TOK_DECLID));}
           | basetype TOK_IDENT           {$$ = adopt1(,
                                           change_symbol(
                                           , TOK_DECLID));}
           ;

block      : stateseq '}'       {free_ast(); $$ = ;}
           | ';'                {free_ast();}
           ;

adopt_func2 采用了一个定义,所以我的部分问题是 adopt_proto 去哪里。谢谢你的时间。

据我所知,这个问题与 declaration/definition 相似度无关。问题是你有一个参数列表的特殊情况,只有一个参数,导致歧义:

parameters : paramlist ')'
           | '(' identdecl ')'
           ;

paramlist  : paramlist ',' identdecl 
           | '(' identdecl
           ;

所以 (type id) 可以使用第一个产生式减少 parameters,其中 paramlist 使用它的第二个产生式减少,或者可以直接使用第二个产生式减少parameters。我看不出有任何明显需要 parameters 的第二次制作,所以我建议直接删除它。

但是,那是(恕我直言)一种非常丑陋的语法编写方式,因为它隐藏了括号的对称性。它也不识别参数为零的参数列表。所以我建议:

parameters : '(' paramlist ')'
           | '(' ')'

paramlist  : identdecl
           | paramlist ',' identdecl

这个我觉得比较清楚