有没有办法在yacc中获取在堆栈中解析的当前数量的令牌

时间:2014-04-22 00:22:27

标签: yacc lex

我在yacc中遇到了解析器堆栈溢出。我不确定当前的解析器堆栈大小是如何确定的。有没有办法获得当前的解析器堆栈大小,以便一旦令牌数达到最大堆栈深度,就可以报告错误? yacc中是否有一个包含此信息的变量?

1 个答案:

答案 0 :(得分:1)

没有标准的方法来获取解析器堆栈大小,尽管显然它是内部可用的,因为解析器能够产生堆栈溢出错误(没有segfaulting或以其他方式调用未定义的行为)。你不需要自己检查;您只需打印提供给yyerror的错误消息;如果堆栈溢出,错误消息将提到这一事实。

有几种方法可以最终得到一个不会调整堆栈大小的yàcc版本。一个是使用公共领域Berkeley yacc,通常称为byacc;我所使用的版本(从1993年开始)将默认堆栈大小设置为500。

另一种可能性是使用Gnu bison,用C ++编译器编译结果;默认情况下,这将使堆栈不可重定位,因为bison不知道语义值联合是否可以轻易复制。 (较新版本的野牛可能没有此限制。)默认情况下,初始野牛堆栈大小为200.

炸毁堆栈的常用方法是对长列表使用正确的递归。以下是一个特别糟糕的变体:

program: /* empty */
       | statement program
       ;

如果“程序”太长,将导致解析器堆栈溢出。将其更改为左递归通常就足够了:

program: /* empty */
       | program statement
       ;
相关问题