总结
针对递归下降语法分析做总结,准确地说,针对LL1文法。
文法定义
基本符号 语法成分
定义
G
=
(
V
T
,
V
N
,
P
,
S
)
G=(V_{T},V_{N},P,S)
G=(VT,VN,P,S)
集合 | 文法成分 | ||
---|---|---|---|
V T V_{T} VT | 终结符集合 | 基本符号/token | |
V N V_{N} VN | 非终结符集合 | 语法成分/语法变量 | |
P | 产生式集合 | 终结符与非终结符的组合方法 | |
S | 开始符号 | 最大的语法成分 |
举例
G
=
(
{
i
d
,
+
,
∗
,
(
,
)
}
,
{
E
}
,
P
,
E
)
G=(\{id,+,*,(,)\},\{E\},P,E)
G=({id,+,∗,(,)},{E},P,E)
P
=
{
E
→
E
+
E
,
E
→
E
∗
E
,
E
→
(
E
)
,
E
→
i
d
}
P=\{E \to E+E,E\to E*E,E\to(E),E\to id\}
P={E→E+E,E→E∗E,E→(E),E→id}
简写
G
:
E
→
E
+
E
∣
E
∗
E
∣
(
E
)
∣
i
d
G:E \to E+E|E*E|(E)|id
G:E→E+E∣E∗E∣(E)∣id
符号约定
终结符:
a
,
b
,
c
a,b,c
a,b,c;串:
u
,
v
,
.
.
.
,
z
u,v,...,z
u,v,...,z
非终结符:
A
,
B
,
C
,
E
,
T
,
F
A,B,C,E,T,F
A,B,C,E,T,F
文法符号:
X
,
Y
,
Z
X,Y,Z
X,Y,Z;串:
α
,
β
,
.
.
.
\alpha,\beta,...
α,β,...
语言定义
推导
用产生式的右部,替换产生式的左部。
直接推导
间接推导
a经过n步推导出b简记为:
a
⇒
n
b
a\Rightarrow^n b
a⇒nb
归约
用产生式的左部,替换产生式的右部。
句型
S
⇒
∗
α
S\Rightarrow^*\alpha
S⇒∗α,
α
\alpha
α即该语言的一个句型
句子
S
⇒
∗
w
S\Rightarrow^*w
S⇒∗w,
w
w
w即该语言的一个句子
语言的形式化定义:
L
(
G
)
=
{
w
∣
S
⇒
∗
w
,
w
∈
V
T
∗
}
L(G)=\{w|S\Rightarrow^*w,w\in V_{T}^*\}
L(G)={w∣S⇒∗w,w∈VT∗}
文法分类
0型文法:无限制文法(Unrestricted Grammar)/短语结构文法(Phrase Structure Grammar,PSG)
1型文法:上下文有关文法(Context-Sensitive Grammar,CSG)
2型文法:上下文无关文法(Context-Free Grammar,CFG)
3型文法:正则文法(Regular Grammar,RG)包含左线性文法(
A
→
w
B
A\to wB
A→wB或
A
→
w
A\to w
A→w)和右线性文法(
A
→
B
w
A\to Bw
A→Bw或
A
→
w
A\to w
A→w)
CFG的分析树
边缘
树的边缘
(句型的)短语
子数的边缘
直接短语
只有两级的子树的边缘(产生式的右部)
二义性
如果一个文法可以为某个句子生成多棵分析树,则称该文法是二义性的。
文法需要为句子生成唯一的分析树。
可通过消歧规则消除二义性。
可通过充分条件判断文法无二义性。
正则
有穷自动机
定义
M
=
(
S
,
Σ
,
δ
,
s
0
,
F
)
M=(S,\Sigma,\delta,s_0,F)
M=(S,Σ,δ,s0,F)
状态集
输入集
转换集
开始状态
接收状态
转换表
确定有穷自动机(Deterministic finite automata,DFA)
非确定有穷自动机(Nondeterministic finite automata,NFA)
NFA更直观、DFA计算机更容易实现
转化
正则文法 <=> 正则表达式 <=> 不确定有穷自动机 <=> 确定有穷自动机
从正则表达式到NFA
从NFA到DFA
自顶向下的分析方法
最左推导
最右归约
最右(规范)推导
最左(规范)规约
自顶向下的分析方式采用最左推导的方式
递归下降分析
- 由一组过程组成,每个过程对应一个非终结符
- 从文法开始符号S开始,递归得调用文法中其它非终结符对应的过程。如果S对应的过程恰好扫描了整个输入串,则成功完成语法分析。
递归下降分析会产生回溯。
预测分析
递归下降分析的一个特例,通过在输入中向前看固定个数(通常为1)符号来选择正确的产生式。
预测分析不需要回溯,它是一种确定的自顶向下的分析方法。
文法转换
不是所有文法都适合自顶向下的分析,我们要清楚可能遇到的问题,以及如何改造文法,使它们适合自顶向下的分析。
同一非终结符候选式存在共同前缀
产生回溯
例如:
S
→
a
a
∣
a
b
S\to aa|ab
S→aa∣ab
处理方法:
提取公共前缀
直接/间接左递归
陷入无限循环
例如:
A
⇒
+
A
α
A\Rightarrow^+A\alpha
A⇒+Aα
处理方法:
消除直接左递归
将左递归转换为右递归
将
A
→
A
α
∣
β
A\to A\alpha|\beta
A→Aα∣β 替换为:
A
→
β
A
′
;
A
′
→
α
A
′
∣
ε
A\to \beta A';A'\to \alpha A'|\varepsilon
A→βA′;A′→αA′∣ε
消除间接左递归
先代入,再消除直接左递归
消除左递归算法
LL1文法
FIRST集(非终结符的串首终结符集)
FIRST(X)
可以从X推导出的所有串首终结符构成的集合,如果
X
⇒
∗
ε
X\Rightarrow^*\varepsilon
X⇒∗ε,那么
ε
∈
F
I
R
S
T
(
X
)
\varepsilon \in FIRST(X)
ε∈FIRST(X)
FOLLOW集(非终结符的后继符号集)
FOLLOW(A)
可能在某个句型中紧跟在A后边的终结符a的集合:
F
O
L
L
O
W
(
A
)
=
a
∣
S
⇒
∗
α
A
a
β
,
a
∈
V
T
α
,
β
∈
(
V
T
⋃
V
N
)
∗
FOLLOW(A)={a|S\Rightarrow^*\alpha Aa\beta,a\in V_T \space\space \alpha,\beta\in (V_T\bigcup V_N)^*}
FOLLOW(A)=a∣S⇒∗αAaβ,a∈VT α,β∈(VT⋃VN)∗
如果A是某个句型的最右符号,则将结束符$添加到FOLLOW(A)中
SELECT集(产生式的可选集)
如果
ε
∉
F
I
R
S
T
(
a
)
\varepsilon \notin FIRST(a)
ε∈/FIRST(a),则
S
E
L
E
C
T
(
A
→
a
)
=
F
I
R
S
T
(
a
)
SELECT(A\to a)=FIRST(a)
SELECT(A→a)=FIRST(a)
如果
ε
∈
F
I
R
S
T
(
a
)
\varepsilon \in FIRST(a)
ε∈FIRST(a),则
S
E
L
E
C
T
(
A
→
a
)
=
(
F
I
R
S
T
(
a
)
−
ε
)
⋃
F
O
L
L
O
W
(
A
)
SELECT(A\to a)=(FIRST(a)-{\varepsilon})\bigcup FOLLOW(A)
SELECT(A→a)=(FIRST(a)−ε)⋃FOLLOW(A)
S_文法(简单的确定性文法)
- 每个产生式的右部都以终结符开始
- 同一非终结符的各个候选式的首终结符都不同
S_文法不包含空产生式
q_文法
- 每个产生式的右部都以终结符开始
- 同一非终结符的各个候选式具有不相交的可选集
q_文法不含右部以非终结符打头的产生式
LL1文法
同一非终结符的各个产生式的可选集互不相交
第一个L表示从左向右扫描,
第二个L表示最左推导,
1表示向前看一个输入来决定分析动作
LL1文法含右部以非终结符打头的产生式
预测分析表
递归的预测分析法
语法制导翻译
语义的表示
为上下文无关文法中的文法符号设置语义属性,用来表示语法成分对应的语义信息
语义属性的计算
文法符号的语义属性是用与文法符号所在的产生式(语法规则)相关联的语义规则来计算的
对于给定的输入串x,构建x的语法分析树,并利用与产生式(语法规则)相关联的语义规则来计算分析树中各结点对应的语义属性值
语法制导定义(SDD)
对上下文无关文法的推广
语法制导翻译方案(SDT)
语法指导翻译方案是在产生式右部嵌入了程序片段的上下文无关文法,这些程序片段称为语义动作
综合属性
通过子结点或本身的属性来定义的
继承属性
通过父结点、兄弟结点、本身的属性来定义的
S-属性定义
仅仅使用综合属性的SDD称为S属性的SDD,或S-属性定义、S-SDD
L-属性定义
也称作L属性的SDD或L-SDD
直观含义:在一个产生式所关联的各属性间,依赖图的边仅可以从左到右(继承属性仅从左到右传递)
结点满足:
- 父结点的继承属性
- 左侧结点的属性
- 本身的属性,并无环路
语法制导翻译方案SDT
语法指导翻译方案是在产生式右部嵌入了程序片段的上下文无关文法,这些程序片段称为语义动作
SDT可以看作是SDD的具体实施方案
两类重要的SDD:
- LR分析技术,SDD是S属性的
- LL分析技术,SDD是L属性的
将L-SDD转换为SDT
将计算某个非终结符A的继承属性的动作插入到产生式右部紧靠在A本次出现之前的位置
将计算一个产生式左部符号综合属性的动作,放置到产生式的最右端
L-属性的SDT实现可以在以下过程中实现:
- 非递归预测分析语义翻译
- 递归预测分析语义翻译
- LR分析语义翻译
在递归预测分析过程中进行翻译
- 为每个非终结符A构造一个函数,A的每个继承属性对应该函数的一个形参,函数的返回值是A的综合属性,对出现在A产生式右部中的每个文法符号的每个属性都设置一个局部变量
- 非终结符A的代码根据当前的输入决定使用哪个产生式
- 与每个产生式有关的代码执行如下动作:从左到右考虑产生式右部的词法单元、非终结符及语义动作
- 对于带有综合属性x的词法单元X,把x的值保存在局部变量X.x中;然后产生一个匹配X的调用,并继续输入
- 对于非终结符B,产生一个右部带有函数调用的赋值语句 c : = B ( b 1 , b 2 , . . . b k ) c:=B(b_1,b_2,...b_k) c:=B(b1,b2,...bk),其中, b 1 , b 2 , . . . , b k b_1,b_2,...,b_k b1,b2,...,bk是代表B的继承属性的变量,c是代表B的综合属性的变量
- 对于每个动作,将其代码复制到语法分析器,并把对属性的引用改为对相应的变量的引用
总结(续)
LR1
LR分析法概述
- 自底向上分析的关键问题
如何正确识别句柄 - 句柄是逐步形成的,用“状态”表示句柄识别的进展程度
LR分析器基于这样一些状态来构造自动机进行句柄的识别
LR分析表
LR(0)项目
右部某位置标有圆点的产生式称为相应文法的一个LR(0)项目,简称项目
项目描述了句柄的状态
例如:
S
′
−
>
⋅
b
B
B
S' -> ·bBB
S′−>⋅bBB <- 移进/待约状态
S
′
−
>
b
⋅
B
B
S' -> b·BB
S′−>b⋅BB <- 待约状态
S
′
−
>
b
B
⋅
B
S' -> bB·B
S′−>bB⋅B <- 待约状态
S
′
−
>
b
B
B
⋅
S' -> bBB·
S′−>bBB⋅ <- 归约状态
LR分析器基于这样一些状态构造自动机进行句柄的识别
增广文法
添加
S
′
→
S
S'\to S
S′→S,使分析器只有一个接受状态
S
′
→
S
⋅
S'\to S·
S′→S⋅
后继项目
等价项目
等价项目组成项目集(I)闭包,每个项目集闭包对应自动机的一个状态
编译原理视频学习笔记
编译原理
1.2 编译器的结构
字符流 -> [词法分析器] -> 词法单元流 -> [语法分析器] -> 语法树 -> [语义分析器] -> 语法树 -> [中间代码生成] -> 中间表示形式 -> [机器无关代码优化器] -> 中间表示形式 -> [目标代码生成器] -> 目标机器语言 -> [机器相关代码优化器] -> 目标机器语言
前端:字符流 -> [词法分析器] -> 词法单元流 -> [语法分析器] -> 语法树 -> [语义分析器] -> 语法树 -> [中间代码生成]
中间表示:中间表示形式 -> [机器无关代码优化器] -> 中间表示形式
后端:[目标代码生成器] -> 目标机器语言 -> [机器相关代码优化器] -> 目标机器语言
语法制导翻译:[语法分析器] + [语义分析器] + [中间代码生成] 直接生成中间表示的编译方法
1.3 词法分析/扫描(Scanning)
词法单元(Token):种别码 + 属性值
单词类型 | 种别 | 种别码 |
---|---|---|
关键字 | if,else | 一词一码 |
标识符 | - | 多词一码 |
常量 | 整数、浮点数、字符串、布尔 | 一型一码 |
运算符 | 算术 | 一词一码/一型一码 |
^ | 关系 | ^ |
^ | 逻辑 | ^ |
界限符 | 😭){} | 一词一码 |
1.4 语法分析(Parsing)
语法分析器(Parser):从词法单元(Token)序列中识别出各类短语,并构造语法分析树(Parse Tree)
文法
1.5 语义分析
符号表(Symbol Table)
1.6 中间代码生成和编译器后端
语法结构树/语法树(Syntax Trees)(与语法分析树不同)
2 语言及其文法
2.1 基本概念
字母表上的运算
乘积(product)
n次幂(power)
正闭包(positive closure)
克林闭包(Kleene closure):空串( ε \varepsilon ε)+正闭包
s的长度: ∣ s ∣ |s| ∣s∣;例如: ∣ a b c ∣ = 3 |abc|=3 ∣abc∣=3, ∣ ε ∣ = 0 |\varepsilon|=0 ∣ε∣=0
连接(concatenation):x和y的连接= x y xy xy;例如:如果x=dog,y=house,则xy=doghouse; ε s = s ε = s \varepsilon s=s\varepsilon = s εs=sε=s;如果 x = y z x=yz x=yz,则y是x的前缀,z是x的后缀
幂; s 0 = ε s^0=\varepsilon s0=ε; s n = s n − 1 s , n ≥ 0 s^n=s^{n-1}s,n \ge 0 sn=sn−1s,n≥0
2.2 文法定义
文法: G = ( V T , V N , P , S ) G=(V_{T},V_{N},P,S) G=(VT,VN,P,S)
集合 | 文法成分 | |
---|---|---|
V T V_{T} VT | 终结符(terminal symbol) | 基本符号/token |
V N V_{N} VN | 非终结符(nonterminal) | 语法成分/语法变量 |
P P P | 产生式(production) | 终结符与非终结符的组合方法 |
S S S | 开始符号(start symbol) | 最大的语法成分 |
V T ⋂ V N = Φ V_{T}\bigcap V_{N}=\Phi VT⋂VN=Φ; V T ⋃ V N V_{T}\bigcup V_{N} VT⋃VN:文法符号集
产生式(production): α → β \alpha \to \beta α→β(读作 α \alpha α定义为 β \beta β)
候选式(candidate);举例: α → β 1 ∣ β 2 ∣ . . . \alpha \to \beta _ 1 | \beta _ 2 | ... α→β1∣β2∣...; β 1 \beta _ 1 β1等称为 α \alpha α的候选式
举例:
G = ( { i d , + , ∗ , ( , ) } , { E } , P , E ) G=(\{id,+,*,(,)\},\{E\},P,E) G=({id,+,∗,(,)},{E},P,E)
P = { E → E + E , E → E ∗ E , E → ( E ) , E → i d } P=\{E \to E+E,E\to E*E,E\to(E),E\to id\} P={E→E+E,E→E∗E,E→(E),E→id}
简写:
G : E → E + E ∣ E ∗ E ∣ ( E ) ∣ i d G:E \to E+E|E*E|(E)|id G:E→E+E∣E∗E∣(E)∣id
符号约定:
终结符: a , b , c a,b,c a,b,c;串: u , v , . . . , z u,v,...,z u,v,...,z
非终结符: A , B , C A,B,C A,B,C
文法符号: X , Y , Z X,Y,Z X,Y,Z;串: α , β , . . . \alpha,\beta,... α,β,...
2.3 语言的定义
推导(Derivations)和规约(Reductions)
推导:用产生式的右部替换产生式的左部;规约:用产生式的左部替换产生式的右部
推导:文法->非终结符串,记作 ⇒ ∗ \Rightarrow^* ⇒∗
规约:非终结符串->文法
句型:包含非终结符的文法符号串
句子:不包含非终结符的句型
短语:句型子串或句子子串
语言的形式化定义: L ( G ) = { w ∣ S ⇒ ∗ w , w ∈ V T ∗ } L(G)=\{w|S\Rightarrow^*w,w\in V_{T}^*\} L(G)={w∣S⇒∗w,w∈VT∗}
2.4 文法的分类
分类体系(Chomsky Hierarchy):
- 0型文法(Type-0 Grammar)(无限制文法)(Unrestricted Grammar/Phrase-Structure Grammar,PSG)
- 1型文法(Type-1 Grammar)(上下文有关文法)(Context-Sensitive Grammar,CSG)
- 2型文法(Type-2 Grammar)(上下文无关文法)(Context-Free Grammar,CFG)
- 3型文法(Type-3 Grammar)(正则文法)(Regular Grammar,RG)
- 左线性文法(Left-Linear Grammar): A → a B ∣ a A \to aB|a A→aB∣a
- 右线性文法(Right-Linear Grammar): A → B a ∣ a A \to Ba|a A→Ba∣a
2.5 CSG的分析树
分析树是推导的图形表示
边缘(frontier)(树的产出,yield):从左到右的叶子结点的符号串
短语:子树的边缘
直接短语:只有父子两代的短语(一定是某产生式的右部;产生式的右部不一定是直接短语)
二义性文法
如果一个文法可以为某个句子构造出两棵不同的分析树,则称该文法是二义性的。
判断非二义性文法的充分条件:…
词法分析
3.1 正则表达式(Regular Expression,RE)
正则表达式是一种用来描述正则语言的更紧凑的表示方法。
正则表达式和正则文法是等价的:对于任何正则文法G,存在定义同一语言的正则表达式r;反之,对于任何正则表达式r,存在定义同一语言的正则文法G。
3.2 正则定义
3.3 有求自动机(Finite Automata,FA)
FA模型
输入带(input tape):用来存放输入符号串
读头(read head):从左到右逐个读取输入符号串的字符,不能修改、不能往返移动
有穷控制器(finite control):具有有限个状态,根据当前状态和当前输入字符决定下一状态
FA的表示
转换图(transition graph)
FA定义(接收)的语言
最长子串匹配原则
3.4 有穷自动机的分类
有穷自动机定义: M = ( Q , Σ , δ , q 0 , F ) M=(Q,\Sigma,\delta,q_0,F) M=(Q,Σ,δ,q0,F)
可以用转换表(transition table)表示有穷自动机
确定有穷自动机(Deterministic finite automata,DFA)
转换图:
非确定有穷自动机(Nondeterministic finite automata,NFA)
转换图:
非确定的有穷自动机的转换表中对于同一个输入字符,可能存在多个状态转换
DFA和NFA的等价性
对于任何NFA M,存在定义同一语言的DFA M’,使得 L ( M ) = L ( M ′ ) L(M)=L(M') L(M)=L(M′)
对于任何DFA M,存在定义同一语言的NFA M’,使得 L ( M ) = L ( M ′ ) L(M)=L(M') L(M)=L(M′)
正则文法 ⇔ 正则表达式 ⇔ F A 正则文法 \Leftrightarrow 正则表达式 \Leftrightarrow FA 正则文法⇔正则表达式⇔FA
带有 ε \varepsilon ε转换的NFA
带有 ε \varepsilon ε转换的NFA可以转换为不带有 ε \varepsilon ε转换的NFA
3.5 从正则表达式到NFA
3.6 从NFA到DFA
DFA的每个状态都是由NFA的状态构成的集合,即NFA状态集合的一个子集
方法:子集构造法(subset construction)
4 语法分析
4.1 自顶向下分析(Top-Down Parsing)
最左推导(left-most derivation):总是选择每个句型的最左非终结符进行替换
最右推导(right-most derivation):总是选择每个句型的最右非终结符进行替换
最左推导的反向是最右规约
最右推导的反向是最左规约
在自底向上的分析中,总是采用最左归约的方式,因此把最左归约称为规范归约,而最右推导称为规范推导。
最左推导和最右推导的唯一性
自顶向下的语法分析采用最左推导方式
递归下降分析(Recursive-Descent Parsing):由一组过程组成,每个过程对应一个非终结符
需要回溯的分析器叫做不确定的分析器
预测分析(Predictive Parsing):递归下降分析的特例,通过在输入中向前看固定个数(通常是一个)符号来决定当前应该使用哪个产生式;不需要回溯,是一种确定的自顶向下分析方法
**LL(K)**文法:可以构造出向前看K个符号的预测分析器
4.2 文法转换
问题1:同一非终结符的多个候选式存在共同前缀,将导致回溯现象
问题2:含有 A → A α A\to A\alpha A→Aα形式的产生式的文法称为直接左递归的(immediately left recursive);如果一个文法中有一个非终结符A使得 A ⇒ + A α A\Rightarrow^+A\alpha A⇒+Aα,则称该文法是左递归的;经过两步或两步以上推导产生的左递归称为间接左递归
消除直接左递归:把左递归转换成右递归;会引入一些非终结符和 ε \varepsilon ε产生式
消除间接左递归:把间接左递归转换成直接左递归,然后消除直接左递归
消除公共前缀:提取左公因子(Left Factoring):通过改写产生式来推迟决定,等读入了足够多的输入,获得足够信息后再做出正确的选择
4.3 LL(1)文法
S_文法(简单的确定性文法)
- 右部都以终结符开始
- 非终结符候选式首终结符都不同
什么时候使用 ε \varepsilon ε产生式:如果当前某个非终结符A与当前输入符a不匹配时,若存在 A → ε A\to \varepsilon A→ε,可以通过检查a是否可以出现在A的后面来决定是否使用 ε \varepsilon ε产生式(若文法中无 A → ε A\to \varepsilon A→ε,则应报错)
非终结符的后继符号集
可能在某个句型中紧跟在非终结符A后的终结符a的集合,记为 F O L L O W ( A ) FOLLOW(A) FOLLOW(A):
F O L L O W ( A ) = { a ∣ S ⇒ ∗ α A a β , a ∈ V T , α , β ∈ ( V T ⋃ V N ) ∗ } FOLLOW(A)=\{a|S\Rightarrow^*\alpha A a \beta, a\in V_{T}, \alpha,\beta \in (V_{T}\bigcup V_{N})^* \} FOLLOW(A)={a∣S⇒∗αAaβ,a∈VT,α,β∈(VT⋃VN)∗}
如果A是某个句型的最右符号,则结束符" " 添加到 "添加到 "添加到FOLLOW(A)$中
产生式的可选集
产生式 A → β A\to \beta A→β的可选集是指可以选用该产生式进行推导的输入符号串的集合,记为 S E L E C T ( A → β ) SELECT(A\to \beta) SELECT(A→β):
S E L E C T ( A → a β ) = { a } SELECT(A\to a\beta)=\{a\} SELECT(A→aβ)={a}
S E L E C T ( A → ε ) = F O L L O W ( A ) SELECT(A\to \varepsilon)=FOLLOW(A) SELECT(A→ε)=FOLLOW(A)
q_文法
- 每个产生式右部为 ε \varepsilon ε或以终结符开始
- 具有相同左部的产生式有不相交的可选集,产生式右部需要非终结符开始
串首终结符集
串首终结符:串首第一个符号,并且是终结符。简称首终结符
给定一个文法符号串 α \alpha α,串首终结符集 F I R S T ( α ) FIRST(\alpha) FIRST(α)定义为可以从 α \alpha α推导出的所有串首终结符构成的集合,如果 α ⇒ ε \alpha \Rightarrow \varepsilon α⇒ε,则 ε \varepsilon ε也在 F I R S T ( α ) FIRST(\alpha) FIRST(α)中
对 ∀ α ∈ ( V T ⋃ V N ) + \forall \alpha \in (V_{T}\bigcup V_{N})^+ ∀α∈(VT⋃VN)+: F I R S T ( α ) = { a ∣ α ⇒ a β , a ∈ V T , β ∈ ( V T ⋃ V N ) ∗ } FIRST(\alpha)=\{a| \alpha \Rightarrow a\beta, a\in V_{T}, \beta \in (V_{T}\bigcup V_{N})^* \} FIRST(α)={a∣α⇒aβ,a∈VT,β∈(VT⋃VN)∗};
如果 α ⇒ ε \alpha \Rightarrow \varepsilon α⇒ε,则 ε \varepsilon ε也在 F I R S T ( α ) FIRST(\alpha) FIRST(α)中
如果 ε ∉ F I R S T ( α ) \varepsilon \notin FIRST(\alpha) ε∈/FIRST(α), S E L E C T ( A → α ) = F I R S T ( α ) SELECT(A\to \alpha)=FIRST(\alpha) SELECT(A→α)=FIRST(α)
如果 ε ∈ F I R S T ( α ) \varepsilon \in FIRST(\alpha) ε∈FIRST(α), S E L E C T ( A → α ) = ( F I R S T ( α ) − { ε } ) ⋃ F O L L O W ( A ) SELECT(A\to \alpha)=(FIRST(\alpha)-\{\varepsilon\})\bigcup FOLLOW(A) SELECT(A→α)=(FIRST(α)−{ε})⋃FOLLOW(A)
LL(1)文法
文法G是LL(1)文法,当且仅当 G G G的任意两个具有相同左部的产生式 A → α ∣ β A\to \alpha | \beta A→α∣β满足下面的条件:
- 如果 α \alpha α或 β \beta β不能推导出 ε \varepsilon ε,则 F I R S T ( α ) ⋂ F I R S T ( β ) = ∅ FIRST(\alpha) \bigcap FIRST(\beta)=\emptyset FIRST(α)⋂FIRST(β)=∅
- α \alpha α和 β \beta β至多有一个能推导出 ε \varepsilon ε
- 如果 α ⇒ ε \alpha \Rightarrow \varepsilon α⇒ε,则 F I R S T ( β ) ⋂ F O L L O W ( A ) = ∅ FIRST(\beta) \bigcap FOLLOW(A)=\emptyset FIRST(β)⋂FOLLOW(A)=∅
- 如果 β ⇒ ε \beta \Rightarrow \varepsilon β⇒ε,则 F I R S T ( α ) ⋂ F O L L O W ( A ) = ∅ FIRST(\alpha) \bigcap FOLLOW(A)=\emptyset FIRST(α)⋂FOLLOW(A)=∅
目的:同一非终结符的各个产生式的可选集互不相交
可以为LL(1)文法构造预测分析器
LL1:
第一个L表示从左向右扫描;
第二个L表示最左推导;
1表示向前看一个输入来决定分析动作
4.4 FIRST集和FOLLOW集的计算
4.5 递归的预测分析法
4.6 非递归的预测分析法
根据预测分析表构造一个自动机,也叫做表驱动的预测分析或下推自动机(Push Down Automata, PDA)。
利用栈,其实思想和递归是一样的
预测分析法的实现步骤
- 构造文法
- 改造文法:消除二义性、消除左递归、消除回溯
- 求每个变量的FIRST集和FOLLOW集,从而求得每个候选式的SELECT集
- 检查是不是LL(1)文法,若是,则构造预测分析表
- 对于递归的预测分析,根据预测分析表为每个非终结符编写一个过程;对于非递归的预测分析,实现表驱动的预测分析法
4.7 预测分析中的错误检测
4.8 自底向上的语法分析
…,后面就不做记录了