04-语法分析
自顶向下
从文法的开始符号出发,通过推导和归纳,逐步推导出句子的结构
对应先序遍历:从根节点出发,先访问根节点,然后递归访问左右子树
递归下降
可能出现的问题
回溯:当一种匹配方式失败时,需要回溯到之前的状态,用其他方式解析
左递归:无限循环
A -> Aa | b
左递归的解决方案
变换公式:A→Aα1∣Aα2∣⋯∣Aαn∣β1∣β2∣⋯∣βm⇒
A→β1A′∣β2A′∣⋯∣βmA′
A′→α1A′∣α2A′∣⋯∣αnA′∣ϵ
A实际上是βi∣(αi)∗
任何语法都能转换为不包含环和ϵ production的等价语法
解决环:代入消除环
解决ϵ production
枚举ϵ的时候,S的格式
增加一个新的开始符号S′,S′→S∣ϵ
例:S→aSbS∣ϵ
S→aSbS∣aSb∣abS∣ab
S′→S∣ϵ
例:A→B∣a,B→A∣b
A→A∣b∣a
ightarrowA→b∣a (最左边无法匹配,可直接消除)
ightarrowB→a∣b
预测分析法
无需回溯
适用于:LL(1) 文法
L:从左到右扫描
L:从最左推导
1:使用 1 个符号的前瞻,决定使用哪个产生式
特点:没有左递归,没有歧义
可以对每一个输入字符,构建预测表
构建预测表
构建预测表需要 FIRST 和 FOLLOW 集合
FIRST(α):一系列能作为α开头的终结符
若X是终结符,FIRST(X)={X}
若X→ϵ,{ϵ}∈FIRST(X)
若X→Y1Y2⋯Yk,ϵ∈FIRST⋂j=1i−1(Yj)∧a∈FIRST(Yi)⇒a∈FIRST(X)
FOLLOW(α):一系列能跟在α后面的终结符
若S为开始符号,$∈FOLLOW(S)
A→αBβ⇒FIRST(β)−{ϵ}⊆FOLLOW(B)
A→αB或A→αBβ,ϵ∈FIRST(β)⇒FOLLOW(A)⊆FOLLOW(B)
构造规则:∀A→α
若a∈FIRST(α),填充M[A,a]=A→α
若ϵ∈FIRST(α)∧b∈FOLLOW(A),填充M[A,b]=A→α
根据表格匹配唯一的规则,若为空则匹配错误
LL(1) 文法的 正式定义
对于文法 A→α∣β
不能存在相同的首终结符:不存在a,使得α,β能同时推导出a开头的串(FIRST(α)⋂FIRST(β)=∅)
不能同时推导出空串
无二义性:如果β能推出空串,则α不能推导出FOLLOW(α) 里的终结符
递归/非递归预测分析
递归:递归下降
非递归:显式地维护一个栈,用于存储当前的状态,相当于 PDA
自底向上 非重点
使用后序遍历建立语法树
不断将输入符号入栈,直到产生产生式右侧的符号
一旦栈顶符号序列和某个产生式右侧相同时,就不断规约,直至无法规约,随后继续入栈
问题
应该规约还是继续入栈
如果有多条匹配的规则,如何选择
LR(0) 文法
在语法分析时不用做选择
定义
L:从左到右扫描符号流
R:从右到左规约
0:不需要向前看任何符号,即可完成规约
表达式右边:可以使用 DFA 表示
表达式左侧:初始状态
状态转移:右侧的每一个符号
可以用ϵ变换,连接和状态转移的非终结符相同的初始状态
最后更新于