概览
- 短语、直接短语、素短语、最左素短语
- 算符优先文法
判断是否是算符优先文法- FIRSTVT集合
构造FIRSTVT集合 - LASTVT集合
构造
- FIRSTVT集合
- LR分析法
- 状态分析表
根据状态分析表进行归约 - ACTION[s,a]
- GOTO[]
- SLR分析
- 闭包
- 状态转换函数GO
- LR(0)文法
- 状态分析表
5.1 自下而上分析基本问题
5.1.1 归约
"移进-规约"法
用一个寄存符号的先进后出栈,把输入符号一个一个地移进到栈里,当栈顶形成某个产生式的一个候选式时,即把栈顶的这一部分替换成(归约为)该产生式的左部符号
中心问题:怎样判断栈顶的符号串的可归约性,以及如何归约
5.1.2 规范规约简述
令
G
G
G是一个文法,S是文法的开始符号,假定
α
β
δ
\alpha\beta\delta
αβδ是文法
G
G
G的一个句型,如果有
S
⇒
∗
α
A
δ
S\xRightarrow{*}\alpha A\delta
S∗αAδ 且
A
⇒
∗
β
A\xRightarrow{*}\beta
A∗β
则称
β
\beta
β是句型
α
β
δ
\alpha\beta\delta
αβδ相对于非终结符
A
A
A的短语。
特别是,如果有,
A
⇒
β
A\Rightarrow \beta
A⇒β,则称
β
\beta
β是句型
α
β
δ
\alpha\beta\delta
αβδ相对于规则
A
→
β
A\rightarrow \beta
A→β的直接短语,
一个句型的最左直接短语称为该句型的句柄。
- 短语
由一个非终结符产生的一串符号(以某个非终结符为根的树的叶节点序列,可以含非终结符) - 直接短语
由一个非终结符直接产生的一串符号 - 素短语
至少含有一个终结符,并且,除它自身之外不再含任何更小的素短语(从每种程度上来说,素短语与直接短语高度重合) - 最左素短语
处于句型最左边的那个素短语 - 句柄
最左侧由一个非终结符直接产生的一串符号(基本与最短素短语无异) - 规范归约/最左归约
序列 α n , α n − 1 , ⋯ , α 0 \alpha_n,\alpha_{n-1},\cdots,\alpha_0 αn,αn−1,⋯,α0是 α \alpha α的一个规范归约,当:- α n = α \alpha_n=\alpha αn=α
- α 0 \alpha_0 α0为文法的开始符,即 α 0 = S \alpha_0=S α0=S
- 对任何
i
i
i,
0
<
i
≤
n
0<i\leq n
0<i≤n,
α
i
−
1
\alpha_{i-1}
αi−1是从
α
i
\alpha_i
αi经把句柄替换为相应产生式的左部符号而得到的
就是由初始句逐步替换句柄直至返回开始符
- 规范推导
产生式的使用顺序调过来(最右推导)
⋆ \star ⋆ 文法无二义,则最右推导的逆过程必然为规范推导 - 规范句式
规范推导所得的句型
5.1.3 符号栈的使用与语法树的表示
“移进-归约”分析器:符号栈、输入缓冲区
- 以#作为栈底符,预先推进栈
- 将字符串首字符推入栈
- 发现可归约,进行归约,即弹出待归约字符串,压入归约后的非终结符
- 未发现可归约,继续
- 将所有可归约符号归约后
- 符号栈:#S,输入栈:#:归约成功
- 否则失败,说明存在语法错误
对于符号栈的四类操作:
- 移进
- 归约
- 接受
- 出错处理
⋆ \star ⋆ 可归约串必然出现在栈顶,不可能出现在栈的内部
5.2 算符优先分析
- 算符优先
定义算符之间(终结符之间)的某种优先关系- a ⋖ b a\lessdot b a⋖b: a a a的优先级低于 b b b
- a = b a=b a=b: a a a的优先级等于 b b b
-
a
⋗
b
a\gtrdot b
a⋗b:
a
a
a的优先级大于
b
b
b
⋆ \star ⋆ 算符优先分析法不是规范归约法
⋆ \star ⋆ 无二义文法是算符优先文法的充分条件
5.2.1 算符优先文法及优先表构造
- 算符文法
任意产生式的右部都不含两个相继(并列)的非终结符(例如 ⋯ Q R ⋯ \cdots QR\cdots ⋯QR⋯)
简单说就是任何两个非终结符之间必须夹至少一个终结符 - 算符优先文法
G G G是算符文法,且 G G G中的任意两终结符只满足 a ⋖ b a\lessdot b a⋖b、 a = b a=b a=b、 a ⋗ b a\gtrdot b a⋗b其中之一- a = b a= b a=b:存在 P → ⋯ a b ⋯ P\rightarrow \cdots ab\cdots P→⋯ab⋯ 或 P → ⋯ a Q b ⋯ P\rightarrow \cdots aQb\cdots P→⋯aQb⋯
-
a
⋖
b
a\lessdot b
a⋖b:存在
P
→
⋯
a
R
⋯
P\rightarrow \cdots aR\cdots
P→⋯aR⋯,且
R
⇒
+
b
⋯
R\xRightarrow{+}b\cdots
R+b⋯或
R
⇒
+
Q
b
⋯
R\xRightarrow{+}Qb\cdots
R+Qb⋯
因为要优先归约R,则R内的第一个终结符较外部开头最近终结符优先级高 -
a
⋗
b
a\gtrdot b
a⋗b:存在
P
→
⋯
R
b
⋯
P\rightarrow \cdots Rb\cdots
P→⋯Rb⋯,且
R
⇒
+
⋯
a
R\xRightarrow{+}\cdots a
R+⋯a或
R
⇒
+
⋯
a
Q
R\xRightarrow{+}\cdots aQ
R+⋯aQ
因为要优先归约R,则R内的最后一个终结符较外部结尾最近终结符优先级高
-
F
I
R
S
T
V
T
(
P
)
FIRSTVT(P)
FIRSTVT(P)
- 定义
F I R S T V T ( P ) = { a ∣ P ⇒ + a ⋯ 或 P ⇒ + Q a ⋯ , a ∈ V T 而 Q ∈ V N } FIRSTVT(P)=\{a|P\xRightarrow{+}a\cdots或P\xRightarrow{+}Qa\cdots,a\in V_T而Q\in V_N\} FIRSTVT(P)={a∣P+a⋯或P+Qa⋯,a∈VT而Q∈VN}
P句型第一个终结符的集合 - 应用
若后选型 ⋯ a P ⋯ \cdots aP\cdots ⋯aP⋯, b ∈ F I R S T V T ( P ) b\in FIRSTVT(P) b∈FIRSTVT(P),则: a ⋖ b a\lessdot b a⋖b - 构造
- 若有产生式 P → a ⋯ P\rightarrow a\cdots P→a⋯或 P → Q a ⋯ P\rightarrow Qa\cdots P→Qa⋯,则 a ∈ F I R S T V T ( P ) a\in FIRSTVT(P) a∈FIRSTVT(P)
- 若 a ∈ F I R S T V T ( Q ) a\in FIRSTVT(Q) a∈FIRSTVT(Q),且有产生式 P → Q ⋯ P\rightarrow Q\cdots P→Q⋯,则 a ∈ F I R S T V T ( P ) a\in FIRSTVT(P) a∈FIRSTVT(P)
- 定义
-
L
A
S
T
V
T
(
P
)
LASTVT(P)
LASTVT(P)
- 定义
L A S T V T ( P ) = { a ∣ P ⇒ + ⋯ a 或 P ⇒ + ⋯ a Q , a ∈ V T 而 Q ∈ V N } LASTVT(P)=\{a|P\xRightarrow{+}\cdots a或P\xRightarrow{+}\cdots aQ,a\in V_T而Q\in V_N\} LASTVT(P)={a∣P+⋯a或P+⋯aQ,a∈VT而Q∈VN}
P句型最后一个终结符的集合 - 应用
若后选型 ⋯ P b ⋯ \cdots Pb\cdots ⋯Pb⋯, a ∈ L A S T V T ( P ) a\in LASTVT(P) a∈LASTVT(P),则: a ⋗ b a\gtrdot b a⋗b - 构造
- 若有产生式 P → ⋯ a P\rightarrow\cdots a P→⋯a或 P → ⋯ a Q P\rightarrow\cdots aQ P→⋯aQ,则 a ∈ L A S T V T ( P ) a\in LASTVT(P) a∈LASTVT(P)
- 若 a ∈ L A S T V T ( Q ) a\in LASTVT(Q) a∈LASTVT(Q),且有产生式 P → ⋯ Q P\rightarrow\cdots Q P→⋯Q,则 a ∈ L A S T V T ( P ) a\in LASTVT(P) a∈LASTVT(P)
- 定义
- 优先表
横纵坐标均为终结符,内容为优先级,表示为:
纵坐标 ( 内容 , 如 ⋖ ) 横坐标 纵坐标 (内容,如\lessdot) 横坐标 纵坐标(内容,如⋖)横坐标
5.2.2 算符优先分析算法
- 最左素短语
最左子串 N j a j ⋯ N i a i N i + 1 N_ja_j\cdots N_ia_iN_{i+1} Njaj⋯NiaiNi+1- a j − 1 ⋖ a j a_{j-1}\lessdot a_j aj−1⋖aj
- a j = a j + 1 , ⋯ , a i − 1 = a i a_j=a_{j+1},\cdots,a_{i-1}=a_i aj=aj+1,⋯,ai−1=ai
- a i ⋗ a i + 1 a_i\gtrdot a_{i+1} ai⋗ai+1
- 算符优先分析算法
- 不断读入字符串,此时最靠近栈顶终结符为
a
a
a,待压入终结符为
b
b
b
- 若栈为空,压入字符
- 若 a ⋖ b a\lessdot b a⋖b,压入,记该 b b b为 α \alpha α(这里可以考虑将a的位置压入一个栈,因为可能有多层,但如果只是一个一个弹出的话,则完全没有必要,因为可以边弹边检查)
- 若 a = b a=b a=b,压入
- 若 a ⋗ b a\gtrdot b a⋗b,记该 a a aw为 β \beta β,逐步弹栈至弹出 α \alpha α,对 N i α ⋯ β N j N_i\alpha\cdots\beta N_j Niα⋯βNj进行归约,结果压入栈
- 字符串读完,栈内为
#
S
\#S
#S,字符串剩余
#
\#
#,则匹配成功
⋆ \star ⋆ 算符分析的结果不一定是语法树,算符优先分析并不等价于规范规约
⋆ \star ⋆ 算符优先分析较规范规约更快,但忽略了非终结符的作用,具有一定的危险性
- 不断读入字符串,此时最靠近栈顶终结符为
a
a
a,待压入终结符为
b
b
b
5.2.3 优先函数
上课没讲,简单看看
- 入栈优先函数
f
(
θ
)
f(\theta)
f(θ),比较优先函数
g
(
θ
)
g(\theta)
g(θ)
- 若 θ 1 ⋖ θ 2 \theta_1\lessdot \theta_2 θ1⋖θ2,则: f ( θ 1 ) < g ( θ 2 ) f(\theta_1)<g(\theta_2) f(θ1)<g(θ2)
- 若 θ 1 = θ 2 \theta_1=\theta_2 θ1=θ2,则: f ( θ 1 ) = g ( θ 2 ) f(\theta_1)=g(\theta_2) f(θ1)=g(θ2)
- 若 θ 1 ⋗ θ 2 \theta_1\gtrdot \theta_2 θ1⋗θ2,则: f ( θ 1 ) > g ( θ 2 ) f(\theta_1)>g(\theta_2) f(θ1)>g(θ2)
5.2.4 算符优先分析中的出错处理
略
5.3 LR分析法
5.3.1 LR分析器
关键问题:找句柄
基本思想:记住“历史”(已经移入与归约的符号串),“展望”未来(预测未来可能碰到的输入符号)
实质:一个带栈的确定有限自动机
-
分析表
LR分析器的核心部分- ACTION表(动作)
A C T I O N [ s , a ] ACTION[s,a] ACTION[s,a], s s s状态面临 a a a动作时进行的动作- 移进
把新的 s s s与 a a a压入栈 - 归约
根据某一产生式,弹出一段符号,归约成新的 a a a - 接受
分析成功 - 报错
出现非 A C T I O N ACTION ACTION表规定动作,即出错
- 移进
- GOTO表(状态转换)
G O T O [ s , X ] GOTO[s,X] GOTO[s,X],状态 s s s面临 X X X符号的下一步动作
组成:
- 纵坐标
状态 - 横坐标
- ACTION表
终结符 - GOTO表
非终结符
- ACTION表
- 内容
- ACTION表
纵坐标为目前状态栈顶的值- r
i
i
i
该符号压入栈后,根据 ( i ) (i) (i)规则弹出候选式并进行归约,得到的非终结符后,依照弹出后现有栈顶状态进行压入操作 - s
i
i
i
该符号压入栈后,压入状态 i i i - acc
仅出现在 # \# #一栏中,表示接受 - 【empty】
错误
- r
i
i
i
- GOTO表
纵坐标为执行弹栈操作后状态栈顶的值-
i
i
i
该符号压入栈后,压入状态 i i i - 【empty】
错误
-
i
i
i
- ACTION表
- ACTION表(动作)
-
LR文法
LR分析表入口唯一确定,即句柄一旦出现在栈顶就可以进行归约处理 -
非LR结构
例
S → i C i S ∣ i C t S e S S\rightarrow iCiS|iCtSeS S→iCiS∣iCtSeS
当可能是句柄的语句出现时无法判断是继续压入还是归约
⋆
\star
⋆ LR文法是无二义文法的真子集,但LR分析技术方法具有一定的二义文法分析能力
略
5.3.2 LR(0)项目集族和LR(0)分析表的构造
(只包含“历史”,不考虑“展望”)
5.3.2.1 定义
- 前缀
字的任意首部
例:
a b c abc abc的前缀有: ε \varepsilon ε、 a a a、 a b ab ab、 a b c abc abc - 活前缀
规范句型的一种前缀,不含句柄之后的任何符号(简单说就是最左素短语的前缀)
只要栈内是活前缀,则扫描部分没有出错
构造有限自动机识别文法的所有活前缀 - LR(0)项目/项目
例:
A → X Y Z A\rightarrow XYZ A→XYZ的项目:
A → ⋅ X Y Z A\rightarrow \cdot XYZ A→⋅XYZ
A → X ⋅ Y Z A\rightarrow X\cdot YZ A→X⋅YZ
A → X Y ⋅ Z A\rightarrow XY\cdot Z A→XY⋅Z
A → X Y Z ⋅ A\rightarrow XYZ\cdot A→XYZ⋅
⋆ \star ⋆ A → ε A\rightarrow\varepsilon A→ε的项目只有 A → ⋅ A\rightarrow\cdot A→⋅ - 分析表的产生过程
- 构造DFA,识别活前缀(该DFA以项目集位节点)
- 将DFA转化为分析表
- LR(0)项目规范族
构成识别一个文法活前缀的DFA的项目集(状态)的全体- 规约项目
A → α ⋅ A\rightarrow\alpha\cdot A→α⋅- 接受项目
S ′ → α ⋅ S'\rightarrow\alpha\cdot S′→α⋅
- 接受项目
- 移进项目
A → α ⋅ α β A\rightarrow\alpha\cdot\alpha\beta A→α⋅αβ - 待约项目
A → α ⋅ B β A\rightarrow\alpha\cdot B\beta A→α⋅Bβ
- 规约项目
5.3.2.2 LR(0)项目集规范族的构造
-
拓广
引入 S ′ → S S'\rightarrow S S′→S(原本文法中右侧生成可能包含S,会影响终态的判断,以S’代替S产生明确的接受态) -
拓广文法
接受态: S ′ → S ⋅ S'\rightarrow S\cdot S′→S⋅ -
C L O S U R E ( I ) CLOSURE(I) CLOSURE(I)
I I I是拓展文法的任意一项目集- I I I的任何项目都属于 C L O S U R E ( I ) CLOSURE(I) CLOSURE(I)
- 若 A → α ⋅ B β A\rightarrow\alpha\cdot B\beta A→α⋅Bβ属于 C L O S U R E ( I ) CLOSURE(I) CLOSURE(I),那么,对于任何关于 B B B的产生式 B → ⋅ γ B\rightarrow\cdot\gamma B→⋅γ也属于 C L O S U R E ( I ) CLOSURE(I) CLOSURE(I)
- 重复执行上述两步骤直至 C L O S U R E ( I ) CLOSURE(I) CLOSURE(I)不再增大为止
-
G O ( I , X ) = C L O S U R E ( J ) GO(I,X)=CLOSURE(J) GO(I,X)=CLOSURE(J)
X X X为一个文法符号
J = { 任何形如 A → α X ⋅ β ∣ A → α ⋅ X β 属于 I } J=\{任何形如A\rightarrow\alpha X\cdot\beta|A\rightarrow\alpha\cdot X\beta属于I\} J={任何形如A→αX⋅β∣A→α⋅Xβ属于I}
(GO函数描述了一个状态I经文法符号X转变为J)
(以CLOSURE(I)为节点,GO函数为方向,可构成DFA) -
有效的
某非待约项目对活前缀有效的前提是该项目归约的结果是活前缀所在项目的候选式的一部分
⋆ \star ⋆ 一个活前缀可能有多个有效项目,此时需要向后看(展望)- 有效项目
-
LR(0)文法
前提- 不含既移进又归约的项目
- 一个状态不含多归约项目
-
LR(0)表
构造方式
以DFA为参考- 终结符移进项目
I
x
→
α
I
y
I_{x}\xrightarrow{\alpha} I_{y}
IxαIy
ACTION表 ( α , x ) (\alpha,x) (α,x)置为 s y s_{y} sy - 非终结符移进项目
I
x
→
P
I
y
I_{x}\xrightarrow{P}I_{y}
IxPIy
GOTO表 ( P , x ) (P,x) (P,x)置为 y y y - 规约项目
I
x
I_{x}
Ix,且对应归约规则
(
m
)
(m)
(m)
ACTION表 ( ? , x ) (?,x) (?,x)置为 r m r_{m} rm - 项目
S
′
→
S
⋅
S'\rightarrow S\cdot
S′→S⋅为项目
I
x
I_{x}
Ix
ACTION表 ( # , x ) (\#,x) (#,x)置为acc - 其余均为报错
((x,y)的x为终结符/非终结符,y为状态)
- 终结符移进项目
I
x
→
α
I
y
I_{x}\xrightarrow{\alpha} I_{y}
IxαIy
-
LR(0)分析器
使用LR(0)表的分析器
5.3.3 SLR分析表的构造
(简单“展望”)
- SLR(1)解决办法
对于既有移进也有归约/多个归约的项目(移进-归约冲突),
考察比较待移进字符与下一个字符/FOLLOW集合,根据比较结果执行指令- 若 a a a是某个移进项目的 a i a_i ai,移进
- 若 a ∈ F O L L O W ( P ) a\in FOLLOW(P) a∈FOLLOW(P),执行 P → α P\rightarrow\alpha P→α归约
- 报错
- SLR表
构造- 终结符移进项目
I
x
→
α
I
y
I_{x}\xrightarrow{\alpha} I_{y}
IxαIy
ACTION表 ( α , x ) (\alpha,x) (α,x)置为 s y s_{y} sy - 非终结符移进项目
I
x
→
P
I
y
I_{x}\xrightarrow{P}I_{y}
IxPIy
GOTO表 ( P , x ) (P,x) (P,x)置为 y y y - 规约项目
I
x
I_{x}
Ix,且对应归约规则
(
m
)
(m)
(m),归约为
P
P
P(该处与LR(0)有所区别)
ACTION表 ( α i , x ) (\alpha_i,x) (αi,x)置为 r m r_{m} rm( α i ∈ F O L L O W ( P ) \alpha_i\in FOLLOW(P) αi∈FOLLOW(P))(简单说就是有这些文字出现即需要归约,当然,其他字符出现则可能意味着出错/移进,具体看是否会再填单词进去) - 项目
S
′
→
S
⋅
S'\rightarrow S\cdot
S′→S⋅为项目
I
x
I_{x}
Ix
ACTION表 ( # , x ) (\#,x) (#,x)置为acc - 其余均为报错
- 终结符移进项目
I
x
→
α
I
y
I_{x}\xrightarrow{\alpha} I_{y}
IxαIy
- SLR(1)文法
具有SLR表的文法G - SLR分析器
使用SLR分析表的分析器
(SLR分析表简单的将所有FOLLOW集合中的元素一股脑的当作允许归约的信号,实际上未考虑到活前缀对于归约动作的要求和规范)
5.3.4 规范LR分析表的构造
简单说,就是升级版的SLR,展望n位
- LR(k)项目
项目一般形式: [ A → α ⋅ β , a 1 a 2 ⋯ a k ] [A\rightarrow \alpha\cdot\beta,a_1a_2\cdots a_k] [A→α⋅β,a1a2⋯ak] - 搜索符串/展望串
a 1 a 2 ⋯ a k a_1a_2\cdots a_k a1a2⋯ak - 有效的
项目 [ A → α ⋅ β , a ] [A\rightarrow \alpha\cdot\beta,a] [A→α⋅β,a]对于活前缀 γ \gamma γ有效
S ⇒ ∗ δ A ω ⇒ δ α β ω S\xRightarrow{*}\delta A\omega\Rightarrow\delta\alpha\beta\omega S∗δAω⇒δαβω- γ = δ α \gamma=\delta\alpha γ=δα
- a ∈ F I R S T ( ω ) a\in FIRST(\omega) a∈FIRST(ω)或 a = # , ω = ε a=\#,\omega=\varepsilon a=#,ω=ε
- 规范LR闭包
C
L
O
S
U
R
E
(
I
)
CLOSURE(I)
CLOSURE(I)的构造(规范LR(k)(k>0)需要重新构造项目集,新的项目集中携带“展望”,该项目集也是随后LALR的基础)
- I I I的任何项目都属于 C L O S U R E ( I ) CLOSURE(I) CLOSURE(I)
- 若项目 [ A → α ⋅ B β , a ] [A\rightarrow\alpha\cdot B\beta,a] [A→α⋅Bβ,a]属于 C L O S U R E ( I ) CLOSURE(I) CLOSURE(I), B → ξ B\rightarrow\xi B→ξ是一个产生式,那么,对于 F I R S T ( β a ) FIRST(\beta a) FIRST(βa)中的每一个终结符 b b b,如果 [ B → ⋅ ξ , b ] [B\rightarrow\cdot\xi,b] [B→⋅ξ,b]原来不在 C L O S U R E ( I ) CLOSURE(I) CLOSURE(I)中,则把它加进去(通过以上方式“凭空”添加B)
- 重复执行步骤(2),直至 C L O S U R E ( I ) CLOSURE(I) CLOSURE(I)不再增大为止
5.3.4.1 LR(1)
- 项目集构造
[ S ′ → ⋅ S , # ] [S'\rightarrow \cdot S,\#] [S′→⋅S,#]为初始,与LR(0)、SLR项目集构造流程类似
⋆ \star ⋆ 展望串
由于读至形如 [ A → α ⋅ B β , a ] [A\rightarrow\alpha\cdot B\beta,a] [A→α⋅Bβ,a]而引入的 [ B → ⋅ ω , b ] [B\rightarrow\cdot\omega,b] [B→⋅ω,b]中的 b ∈ F I R S T ( β ) b\in FIRST(\beta) b∈FIRST(β),如果 β = ξ \beta=\xi β=ξ,则 b = a b=a b=a
其余基本不变 - DFA构造
与LR(0)、SLR基本一致,与项目集同步构造 - LR(1)表构造
- 终结符移进项目
I
x
→
α
I
y
I_{x}\xrightarrow{\alpha} I_{y}
IxαIy
ACTION表 ( α , x ) (\alpha,x) (α,x)置为 s y s_{y} sy - 非终结符移进项目
I
x
→
P
I
y
I_{x}\xrightarrow{P}I_{y}
IxPIy
GOTO表 ( P , x ) (P,x) (P,x)置为 y y y - 规约项目
I
x
I_{x}
Ix,且对应归约规则
(
m
)
(m)
(m),对应项目集为
[
P
→
α
⋅
,
a
]
[P\rightarrow\alpha\cdot,a]
[P→α⋅,a](此处区别于SLR分析表,将归约条件进一步细化)
ACTION表 ( a , x ) (a,x) (a,x)置为 r m r_{m} rm - 项目
S
′
→
S
⋅
S'\rightarrow S\cdot
S′→S⋅为项目
I
x
I_{x}
Ix
ACTION表 ( # , x ) (\#,x) (#,x)置为acc - 其余均为报错
- 终结符移进项目
I
x
→
α
I
y
I_{x}\xrightarrow{\alpha} I_{y}
IxαIy
L R ( 0 ) ⊂ S L R ⊂ L R ( 1 ) LR(0)\subset SLR \subset LR(1) LR(0)⊂SLR⊂LR(1)
5.3.5 LALR分析表的构造
SLR和LR(n)的折衷
- LALR(1)文法
(说白了,就是嫌仅展望不同项目集需要占用多个状态,浪费空间)
解决方式是将这些项目集(具有同心)合并
⋆ \star ⋆ 合并后的项目集失去了检查错误的功能,但是这些错误会在之后被检测出来
⋆ \star ⋆ 合并不会造成移进-归约冲突
5.3.6 二义文法的应用
略
5.3.7 LR分析中的出错处理
略
5.4 语法分析器的自动产生工具YACC
略