Recursion 用迭代重写递归BNF规则

Recursion 用迭代重写递归BNF规则,recursion,matching,parentheses,bnf,non-recursive,Recursion,Matching,Parentheses,Bnf,Non Recursive,看看下面的递归BNF规则 (1) X = Xa | b (3) X = { X } | b 这会产生如下句子 X = b X = ba X = baa X = baaa ... X = b X = {b} X = {{b}} X = {{{b}}} ... 这可以写成 (2) X = b a* 其中右侧不是递归的 现在看看下面的递归BNF规则 (1) X = Xa | b (3) X = { X } | b 这会产生如下句子 X = b X = ba X = baa X = baa

看看下面的递归BNF规则

(1) X = Xa | b
(3) X = { X } | b
这会产生如下句子

X = b
X = ba
X = baa
X = baaa
...
X = b
X = {b}
X = {{b}}
X = {{{b}}}
...
这可以写成

(2) X = b a*
其中右侧不是递归的

现在看看下面的递归BNF规则

(1) X = Xa | b
(3) X = { X } | b
这会产生如下句子

X = b
X = ba
X = baa
X = baaa
...
X = b
X = {b}
X = {{b}}
X = {{{b}}}
...
是否有某种方法可以以非递归的方式重写规则(3),就像我们将规则(1)重写为规则(2)时所做的那样


注意X={*b}*是不好的,因为括号需要平衡

我不知道上述问题是否可以回答。上面这个问题的原因是我想避免解析器中的无限循环(用Java编写)。一种方法是确保BNF规则不是递归的,因此我的问题是。但另一种方法是使用递归规则,但要避免我的(Java)程序中的无限循环。事实证明,您可以通过延迟实例化来避免循环

例如,请看以下规则:

expression = term ('+' term)*;
term       = factor ('*' factor)*;
factor     = '(' expression ')' | Num;
expression()调用term(),term()调用factor(),factor()调用expression(),因此我们可以得到无限循环。为了避免这种情况,我们可以使用惰性实例化,而不是编写如下内容:

public Parser expression() {
    expression = new ...
    return expression;
}
我们改写:

public Parser expression() {
    if (expression == null) {
        expression = new ...
    }
    return expression;
}

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

这有点猜测,但:x=(,ab)*aBTW:对于规则(3):x={ab,我不确定它是否好。@AdamOcsvari,您没有括号。并且没有逗号。@helpYou:True!更简单:x=ab*ah他想要这样的东西。
{(ab)*a(}
({ab)*{a}(})*
但具有更多控制-在两侧具有相同的编号作为
*
的替代物。(开放括号的数量应等于封闭括号的数量)也许我错了,但解析器中的无限循环意味着给定规则在不使用任何输入的情况下反复调用自身。这是使用递归下降方法实现左递归规则时发生的情况。这不是上述语法的情况,因为解析器必须使用“(”在它再次调用empression之前。没有无限循环。(编辑:打字错误)