野牛解析器:我什么时候需要'return',什么时候不需要?
Bison parser: When do I need 'return' and when I don't?
现在我正在用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
。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 什么时候在C++中返回常量引用是个好主意
- 什么时候调用析构函数
- boost odeint什么时候真正调用观测者
- 编译器对数组声明大小的计算。什么时候发生?
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 您应该在什么时候创建自己的异常类型
- 我什么时候会默认(而不是删除)基类中的复制和移动操作
- 什么时候可以使用常量装饰调用我的重载函数?
- unordered_map什么时候返回 -1?
- QCoreApplication什么时候有效?
- sizeof(size_t) 和 sizeof(ptrdiff_t) 什么时候会有所不同?
- 什么时候用指针调用C++类构造函数
- 我不明白在这个例子中什么时候调用构造函数
- 如果真的需要std::move,我们应该什么时候声明右值refs
- P1008("prohibit aggregates with user-declared constructors")在实践中什么时候有用?
- 程序什么时候会创建多个堆
- 调用boost.asio的异步函数时,线程是什么时候创建的
- Swig/python : 什么时候需要 SWIG_init() ?
- 野牛解析器:我什么时候需要'return',什么时候不需要?