查看以下递归BNF规则
(1) X = Xa | b
这会产生像
这样的句子X = b
X = ba
X = baa
X = baaa
...
这可以写成
(2) X = b a*
右侧不递归
现在看一下下面的递归BNF规则
(3) X = { X } | b
这会产生像
这样的句子X = b
X = {b}
X = {{b}}
X = {{{b}}}
...
是否有某种方式以非递归方式重写规则(3),类似于我们将规则(1)重写为规则(2)时所做的。
观察到X = {* b} *是不好的,因为括号需要平衡。
答案 0 :(得分:0)
我不知道上面的问题是否可以回答。上面问题的原因是我想在我的解析器中避免无限循环(用Java编写)。一种方法是确保BNF规则不是递归的,因此我的问题。但另一种方法是使用递归规则,但避免我的(Java)程序内的无限循环。事实证明,您可以通过延迟实例化来避免循环。
例如,请查看以下规则:
expression = term ('+' term)*;
term = factor ('*' factor)*;
factor = '(' expression ')' | Num;
expression()调用term(),它调用factor(),调用expression(),因此我们最终会得到无限循环。为了避免这种情况,我们可以使用延迟实例化,而不是编写类似的东西:
public Parser expression() {
expression = new ...
return expression;
}
我们反而写:
public Parser expression() {
if (expression == null) {
expression = new ...
}
return expression;
}
请注意,您必须将表达式声明为实例变量才能使其生效。