1

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

4

1 回答 1

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

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

于 2015-04-21T10:48:02.760 回答