Parsing 基于表的LL解析器是否可以在没有正确递归的情况下处理重复?

Parsing 基于表的LL解析器是否可以在没有正确递归的情况下处理重复?,parsing,parser-generator,ll,Parsing,Parser Generator,Ll,我理解LL递归下降解析器如何处理这种形式的规则: A = B*; 使用一个简单的循环,根据前瞻令牌是否匹配第一组B中的终端来检查是否继续循环。然而,我对基于表的LL解析器感到好奇:这种形式的规则在那里如何工作?据我所知,在一个实例中处理这种重复的唯一方法是通过右递归,但在不需要右关联解析树的情况下,这会打乱关联性 我很想知道,因为我目前正在尝试编写一个基于LL(1)表的解析器生成器,我不知道如何在不更改预期的解析树形状的情况下处理这样的情况。语法 让我们将EBNF语法扩展为简单的BNF,并假设

我理解LL递归下降解析器如何处理这种形式的规则:

A = B*;
使用一个简单的循环,根据前瞻令牌是否匹配第一组B中的终端来检查是否继续循环。然而,我对基于表的LL解析器感到好奇:这种形式的规则在那里如何工作?据我所知,在一个实例中处理这种重复的唯一方法是通过右递归,但在不需要右关联解析树的情况下,这会打乱关联性

我很想知道,因为我目前正在尝试编写一个基于LL(1)表的解析器生成器,我不知道如何在不更改预期的解析树形状的情况下处理这样的情况。

语法 让我们将EBNF语法扩展为简单的BNF,并假设
b
是一个终端,
是一个空字符串:

A -> X
X -> BX
X -> <e>
B -> b
跟戏
Follow(A)
是可以 立即出现在非终结符
a
的右侧

Follow(A) : $
Follow(X) : $
Follow(B) : b$
桌子 我们现在可以基于集合构建表,
$
是输入结束标记

+---+---------+----------+
|   |    b    |    $     |
+---+---------+----------+
| A | A -> X  | A -> X   |
| X | X -> BX | X -> <e> |
| B | B -> b  |          |
+---+---------+----------+
结论 如您所见,可以毫无问题地解析形式为
A=B*
的规则。为input
bb
生成的具体解析树是:


是的,这绝对是可能的。重写为BNF并构造解析表的标准方法对于计算解析器应该如何工作非常有用——但据我所知,您要问的是如何避免递归部分,这意味着您将得到AST的倾斜二叉树/链表形式

如果您手工编写解析器,您可以简单地使用一个循环,使用解析表中的lookaheads指示一个递归调用,以决定再次循环。(也就是说,您可以只使用
而使用那些lookahead作为条件。)然后对于每个迭代,您只需将构造的子树作为当前父树的子树追加。在您的情况下,
A
将得到几个直接的
B
-子级


现在,据我所知,您正在构建一个解析器生成器,通过plan BNF遵循标准过程可能是最简单的。然而,这并不是一个真正的问题;毕竟,迭代和递归之间没有实质性的区别。您只需要有一类“助手规则”,它们不引入新的AST节点,而是将它们的结果附加到触发它们的非终端的节点。因此,当将重复转换为
X->BX
时,而不是构造
X
节点,您可以使用
X
规则通过自己的子节点扩展
A
X
的子列表。您最终仍然会看到
A
有几个
B
子节点,并且看不到
X
节点。

此答案使用标准的右递归过程。问题是如何避免正确的递归,以及生成的AST与EBNF不匹配。
+---+---------+----------+
|   |    b    |    $     |
+---+---------+----------+
| A | A -> X  | A -> X   |
| X | X -> BX | X -> <e> |
| B | B -> b  |          |
+---+---------+----------+
+-------+-------+-----------+
| Stack | Input |  Action   |
+-------+-------+-----------+
| A $   | bb$   | A -> X    |
| X $   | bb$   | X -> BX   |
| B X $ | bb$   | B -> b    |
| b X $ | bb$   | consume b |
| X $   | b$    | X -> BX   |
| B X $ | b$    | B -> b    |
| b X $ | b$    | consume b |
| X $   | $     | X -> <e>  |
| $     | $     | accept    |
+-------+-------+-----------+