野牛解析器:我什么时候需要'return',什么时候不需要?

Bison parser: When do I need 'return' and when I don't?

本文关键字:什么时候 return 不需要      更新时间:2023-10-16

现在我正在用Bison parser(一个计算器)编写我的第一个作品。

我注意到,对于以下规则:

expr_double: expr_double '+' expr_double          { $$ = $1 + $3; }
        | expr_double '-' expr_double           { $$ = $1 - $3; }
        .
        .
        .
        etc...

我不需要用"return 0"指定解析的结束,解析器知道何时停止并完成作业。这适用于打印double_expr:5、10+10 等输入......

但是,对于以下规则,我需要在最后写"return 0",否则它不起作用:

print_expr: PRINT expr_int      { cout<<$2<<endl; return 0; }
        | PRINT expr_double     { printf("%.3fn", $2); return 0; }
        .
        .
        .
        etc...

我没有提供任何进一步的代码,因为我认为它不相关。如果需要,我会发布更多的代码,但我认为差异在这里显示。

知道为什么我在后面的规则中需要"返回",但在第一个规则中不需要吗?

编辑:添加了我程序的第一条和第二条规则...

program: command 'n'
        ;
command: print_expr
        | define_var
        | assign_var
        ;

在野牛的正常使用中,你根本不会回来。相反,"开始"规则会减少,然后yyparse()正常返回。

我怀疑你是否想在你的任何行动中return

也就是说,我已经看到以这种方式使用返回。它只会导致yyparse()过早返回。"开始"规则尚未减少,因此此时您的输入与整个语法不匹配。

将返回规则视为短路您的语法。一旦操作中返回的规则减少,yyparse()将立即返回,并将在此时停止解析。可能不是你想要的。

换句话说,一旦您的解析器看到 print 语句,它就会停止解析。


更新:您可能想要的是一个接一个地解析许多命令。语法如下所示:

program: commands 'n'
        ;
commands : command
         | commands command
         ;
command: print_expr
        | define_var
        | assign_var
        ;

不要尝试直接从解析器return,你可能会泄漏,因为您将跳过清理堆栈的所有代码。 如果您想成功退出,请使用 YYACCEPT ,否则YYABORT