语法分析
已知语言的文法,给定一个词素串,判定它是否符合文法,符合的话,得出语法分析树。
语法分析的期望:一次扫描,解决语法分析问题;
自顶向下的语法分析:最右推导,最左推导;
自底向上的语法分析;
基于自顶向下和最左推导的语法分析遇到的问题
问题一:左递归
什么是带左递归的文法:
输入串:
推导过程:
可以看出:推导是从输入串的最右端开始逆向逐一来匹配:不切合实际。
解决办法:消除左递归
好处:实现了队输入串从左至右逐一匹配;
代价:多引入了一个非终结符,语法树变得复杂,效率低
消除左递归的通用方法:
是指某个非终结符,有多个产生式,这些产生式分两类:
- 含左递归的产生式:一个或者多个;
- 不含左递归的产生式:一个或多个;
消除步骤:
消除间接左递归
消除步骤:
先带入,再消除
问题二:左公因子
文法:
输入串:
看到if时,选择第一个产生式,还是第二个产生式,并不好决策。不同的选择会导致不同的结果。
解决办法:提取左公因子
队提取左公因子的认识——要彻底
是指某个非终结符,它有多个产生式,其产生式体的左端有公因子,导致在推导时,有多个产生式匹配,不知道选哪个才对。
解决办法:把非公因式部分单独拿出来,引入一个非终结符,来表达它,注意ε。
策略:把差异部分,延后再来确定
代价:新引入了一个非终结符
提取左公因子的一般化表述:
例子:
问题三:选择哪个产生式进行推导
推导时,队一个非终结符,当有多个产生式供选择时,到底选择哪一个产生式呢?
需要观察与分析,寻求解决问题的突破口。
形式化处理
-
对于两个均不为空的产生式
-
对于其中一个为空的产生式
出现语法错误的表现形式
FIRST()和FOLLOW( )的求法
初始时:所有产生式:FIRST()=∅, 所有非终结符:FOLLOW( )=∅;
语法分析树推导完成,输入串的末尾符也已匹配完毕,当前输入 符自然为$
, 因此天然的已知: $ ∈ FOLLOW(S);
FIRST()求法:
- 对非终结符号,由低到高排序,逐一 扫描其产生式, 计算每一产生式的FIRST()
- 当一个非终结符号C有多个产生式时:
A
→
a
1
,
.
.
.
.
,
A
→
a
n
,
F
I
R
S
T
(
C
)
=
F
I
R
S
T
(
a
1
)
∪
.
.
.
∪
F
I
R
S
T
(
a
n
)
A→a_1,...., A→a_n,FIRST(C)=FIRST(a_1) ∪...∪FIRST(a_n)
A→a1,....,A→an,FIRST(C)=FIRST(a1)∪...∪FIRST(an)
FOLLOW()求法
- 对非终结符,从起始非终结符S开始,由高到低依次排序;
- 天然的已知:FOLLOW(S) 包含
$
这个终结符。 - 然后逐一计算每个非终结符的FOLLOW()。设当前非终结符为C,对右部含C的所有产生式,分别计算 F O L L O W ( C ) FOLLOW(C) FOLLOW(C).
算法: