换个角度看问题,可能取得更好的结果。

本次《编译原理》书面作业中,有一题让我们比较LL(0)分析和LR(0)分析,问LR(0)比LL(0)好在哪里

LL分析,意为从左到右读取输入串,生成最左推导

LR分析,意为从左到有读取输入串,生成最右推导

已知,一般而言LR分析的能力要强于LL分析,但这是为什么呢?

移进、推导、归约

LR分析器被称为移进-归约分析,因为它对输入串处理的逻辑是,先将输入串移进到栈上,再在到达特定的位置(句柄)时,根据栈上情况选择表达式来归约

类似地,LL分析器可以被称为推导-移进分析,因为它先对栈上的非终结符选择产生式进行推导,再逐步移进输入串来消除推导出的终结符

二者的最主要区别体现在:LL分析器在移进符号之前选择产生式,而LR分析器在移进符号之后选择产生式;因此后者可以有更多的已知信息来选择产生式

也是因为这个原因,LL(0)分析没有实际意义,因为在不向前察看的情况下,选择推导产生式就是盲猜

与语法分析树的关系

语法分析是生成语法分析树的过程,生成一棵树的过程,也是在遍历这棵树

注意到,语法分析树中的叶子节点对应终结符非叶子节点对应非终结符;于是,我们可以把移进符号当作是对叶子节点的遍历,把选择产生式进行推导/归约当作是对非叶子节点的遍历

于是,LL分析先推导再移进,是对AST的先序遍历;而LR分析先移进再归约,是对AST的后序遍历

在LR分析中起到第一步归约作用的句柄,也就是后序遍历序列中第一个出现的非叶子节点

与DPDA的关系

上一节中提到,LR(1)文法的语言一定是DPDA接受的语言,反之亦然

实际上,LR分析器本质上就是一个DPDA:

  • PDA有一个核心状态action,在此状态下,所有移进过程:ACTION[i, a] = sj以自转移边a|i → ji的形式完成
  • 对于所有归约过程,它从action状态开始,经过若干个辅助状态弹出产生式需要的符号后,再通过一条GOTO转移边回到action状态
  • 根据LR文法的定义(不能存在两种冲突),很容易证明上面得到的PDA是DPDA