野牛:特定数量的递归?

时间:2015-03-24 09:35:09

标签: parsing recursion bison flex-lexer bisonc++

我已经用flex和bison编写了一个解析器几个星期了,并且由于双递归而停止了,其定义与前几个规则相似。 Bison总是在一个特定阶段选择错误的路径并崩溃,因为语法不适合。野牛代码看起来有点像这样:

set : 
TOKEN_    /* token */
QString
QString
Integer  /* number of descrs (see below) */
M_op     /*'M' optional*/
alts;

alts  :
alt | alts alt ;

alt   :
QString
pName_op   /* empty | TOKEN1 QString */
deVal_op    /* empty | TOKEN2 Integer */
descrs
;

descrs  :   
descr | descrs descr ;
descr :
QString
QString_op   /* optional qstring */
Integer
D_op         /* optional 'D' */

Bison停留在descrs递归中,并且永远不会退出以进入下一个alt。但是,在初始块中读入的整数告诉我们将会有多少descr个实例。所以我的问题是:

有没有办法为特定数量的递归实例准备bison,以便他可以退出此递归并进入递归&#34;以上&#34;?我可以在C代码中访问此整数,但我不知道所述移动的语法,类似于descrs : {for (int i=0;i<n;++i){descr}}(我意识到这可能看起来很荒谬)

如果失败了,还有其他方法解决这个问题吗?

非常感谢任何输入。提前谢谢。

1 个答案:

答案 0 :(得分:1)

无上下文语法不能取决于语义信息。然而,这正是您所寻求的:您希望在表达式的语法中考虑数字标记的

作为请求,这不是不合理或不道德的;它只是在无上下文语法的范围之外。 bison旨在为无上下文语法创建解析器。所以它根本不是解决这个问题的正确工具。

话虽如此,如果您使用的bison合理的最新版本(包括对GLR语法的支持),以这种方式使用bison是可能。 Bison的GLR支持包括使用语义谓词来控制解析的选项。 (有关详细信息,请参阅bison manual。)基于该机制的解决方案是可行的,并且可能复杂。

如果语法允许的话,更容易使用自上而下的解析器。例如,在递归下降的解析器中解析一个数字然后该数量的descr s将是微不足道的。

在语法中自由使用FOO_op非终端表明自上而下的解析不会有问题,但是如果不看完整个语法就不可能肯定地说。人工非终端(如FOO_op)经常导致LR(1)语言中的移位减少冲突,因为它们迫使立即进行移位/减少决策。在LR(1)语言中,生成以下形式:A → ω B? χ 通常会将其呈现为一对作品A → ω B χ; A → ω χ,而不是替换Bop → B | ε; A → ω Bop χ,以避免与C → ω ζ FIRST(ζ) ∩ FIRST(B ∪ ω) ≠ ∅形式的其他作品产生冲突。