5

你好,堆栈的流成员。

我正在学习编译器类。我确实理解 Top-Down Parser 应该避免左递归,并转换为右递归方式。

问题是,

a)我是否理解正确的 Top-Down Parser 等于 LL 而 Bottom-Up Parser 等于 LR ?

b) 我发现左递归是自称 ex) Expr :== Expr '+' Term | 可以导致无限循环查找 Expr 的项。但无论如何,任何考虑输入 C 或 Java 的示例代码?(我不想要解析器或扫描仪代码)我需要的是带有句子形式的案例代码示例,通过左递归发生无限循环。

c) 在自顶向下解析器中使用右递归实际上有什么不同?

ANS c) 无需回溯。但还有别的吗?

ANS b)x - 2 * y还有别的东西吗?因为这个适用于回溯的解析方式。

我发现了非左递归和左递归的案例示例。

左递归语法

A -> Ax

非左递归语法

A -> Bx
B -> Ay

两者都进入无限循环。

谢谢你,感谢你所有的专家。

4

1 回答 1

6

a)我是否理解正确的 Top-Down Parser 等于 LL 而 Bottom-Up Parser 等于 LR ?是的

自上而下的解析器进入一个带有左递归的无限循环,因为代码中的产品看起来像:

A() {
  A(); match(x);
}

A 永远调用自己,并且永远不会从输入流中删除任何内容。

左递归不必是立即的,因此您的“非左递归语法”仍然是左递归的:

A -> Bx | z
B -> Ay

如果将 B 替换为其产生式,则可以看到它是递归的:

A -> Ayx | z

下面是一个将左递归文法正确转换为右递归文法的示例: 左递归:

E -> E + T | T

右递归:

E -> T B
B -> + T B | Lambda

E -> TB 因为,在规则 E -> E + T | T,T 在完成规则应用后总是出现在最左边。由于最左边由 E -> TB 处理,我们可以自由地构造字符串的右边,就像我们用 B -> + T B 所做的那样。我们需要一个 lambda 产生式来为我们提供一个停止点递归。

A -> Ax 和 A -> xA 将是等效的语法,只有一个是左递归的,另一个是右递归的。

于 2010-10-24T22:24:00.763 回答