我为学校项目构建了一个编译器。一切正常,但我很难定义函数的语法。我必须检测是否有零个或多个参数,以及函数是原型还是定义。我不断改变/减少和/或减少/减少错误。我尝试了很多变化但无济于事。这就是我所拥有的,只是寻找另一个方向的指针或如何解决这个问题的想法。
function : parameters ';' {free_ast($2); $$ = $1;}
| parameters block {$$ = adopt1($1, $2)}
;
parameters : paramlist ')' {free_ast($2); $$ = $1;}
| '(' identdecl ')' {free_ast($3); $$ = adopt_func2($1, $2);}
;
paramlist : paramlist ',' identdecl {free_ast($2);
$$ = adopt1($1, $2);}
| '(' identdecl {$$ = adopt_func2($1, $2);}
identdecl : basetype TOK_ARRAY TOK_IDENT {$$ = adopt2($1, $2,
change_symbol(
$3, TOK_DECLID));}
| basetype TOK_IDENT {$$ = adopt1($1,
change_symbol(
$2, TOK_DECLID));}
;
block : stateseq '}' {free_ast($2); $$ = $1;}
| ';' {free_ast($1);}
;
adopt_func2采用了一个定义,所以我的问题的一部分将是adopt_proto。谢谢你的时间。
答案 0 :(得分:2)
据我所知,这个问题与声明/定义的相似性无关。问题是你有一个参数列表的特殊情况,只有一个参数,导致歧义:
parameters : paramlist ')'
| '(' identdecl ')'
;
paramlist : paramlist ',' identdecl
| '(' identdecl
;
因此可以使用(type id)
的第一个作品减少parameters
,其中paramlist
减少第二次制作,或者可以使用第二个作品parameters
直接减少parameters
1}}。我看不出对parameters : '(' paramlist ')'
| '(' ')'
paramlist : identdecl
| paramlist ',' identdecl
的第二次制作有任何明显的需求,所以我建议删除它。
然而,这是(imho)编写语法的一种非常丑陋的方式,因为它隐藏了括号的对称性。它也无法识别零参数的参数列表。所以我建议:
$scope
我认为更清楚。