用迭代重写递归BNF规则

时间:2015-04-20 22:32:49

标签: recursion matching parentheses bnf non-recursive

查看以下递归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} *是不好的,因为括号需要平衡。

1 个答案:

答案 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;
}

请注意,您必须将表达式声明为实例变量才能使其生效。