编译原理(1)——文法和语言
一、符号串与语言
1、字母表: 字母表 Σ \Sigma Σ是一个有穷符号集合
-
字母表的运算:
- 并集
- 乘积(交集):若 Σ 1 \Sigma_1 Σ1和 Σ 2 \Sigma_2 Σ2是两个字母表,则他们的乘积 Σ 1 Σ 2 = { a b ∣ a ∈ Σ 1 , b ∈ Σ 2 } \Sigma_1\Sigma_2=\{ab|a\in\Sigma_1,b\in\Sigma_2\} Σ1Σ2={ab∣a∈Σ1,b∈Σ2}
- 幂运算:字母表 Σ \Sigma Σ的幂运算( ϵ \epsilon ϵ代表空串)
{ Σ 0 = { ϵ } Σ n = Σ n − 1 Σ n > = 1 \begin{cases} \Sigma^0=\{\epsilon\}\\ \Sigma^n=\Sigma^{n-1}\Sigma\:\:\:\:n>=1 \end{cases} {Σ0={ϵ}Σn=Σn−1Σn>=1
- 正闭包运算: Σ + \Sigma^+ Σ+
Σ + = Σ ⋃ Σ 2 ⋃ Σ 3 ⋃ . . . . . . \Sigma^+=\Sigma\bigcup\Sigma^2\bigcup\Sigma^3\bigcup...... Σ+=Σ⋃Σ2⋃Σ3⋃......
例如:
{ a , b , c , d } + = { a , b , c , d , a a , a b , a c , a d , b a , b b , b c , b d . . . , a a a , a a b , a a c , a a d , a b a , a b b , a b c , . . . } \{a,b,c,d\}^+=\{a,b,c,d,\\aa,ab,ac,ad,ba,bb,bc,bd...,\\aaa,aab,aac,aad,aba,abb,abc,...\} {a,b,c,d}+={a,b,c,d,aa,ab,ac,ad,ba,bb,bc,bd...,aaa,aab,aac,aad,aba,abb,abc,...}
由此可见,字母表的正闭包指长度整数的符号串构成的集合- 闭包运算
Σ ∗ = Σ 0 ⋃ Σ ⋃ Σ 2 ⋃ Σ 3 ⋃ . . . . . . \Sigma^*=\Sigma^0\bigcup\Sigma\bigcup\Sigma^2\bigcup\Sigma^3\bigcup...... Σ∗=Σ0⋃Σ⋃Σ2⋃Σ3⋃......
由此可见,闭包是任意符号串构成的集合,这个符号串长度可以为0*
2、字符串: 设 Σ \Sigma Σ是一个字母表, ∀ x ∈ Σ ∗ \forall\:x\in\Sigma^* ∀x∈Σ∗,x称为是 Σ \Sigma Σ上的一个字符串;
-
串是字母表中的符号的一个有穷序列;
-
串s的长度通常记为|s|,值s中符号的个数
-
串的运算:
-
连接运算:若x和y是串,则x和y的连接时把y附加到x后面而形成的串,记作xy;要注意的是,空串是连接预算的单位元,即对任何字符串都有, ϵ s = s ϵ = s \epsilon s=s\epsilon=s ϵs=sϵ=s
若x,y,z是三个字符串,若x=yz,则称y是x的前缀,称z是x的后缀
-
幂运算:
{ s 0 = ϵ s n = s n − 1 s , n > = 1 \begin{cases} s^0=\epsilon\\ s^n=s^{n-1}s,n>=1 \end{cases} {s0=ϵsn=sn−1s,n>=1
例如: s 1 = s 0 s = ϵ s = s , s 2 = s s , s 3 = s s s , . . . s^1=s^0s=\epsilon s=s,s^2=ss,s^3=sss,... s1=s0s=ϵs=s,s2=ss,s3=sss,...
-
二、文法
文法的形式化定义:
文
法
G
=
(
V
T
,
V
N
,
P
,
S
)
其
中
:
V
T
表
示
终
结
符
集
合
,
终
结
符
是
文
法
所
定
义
的
语
言
的
基
本
符
号
V
N
表
示
非
终
结
符
集
合
,
非
终
结
符
是
用
来
表
示
语
法
成
分
的
符
号
,
可
以
用
来
进
一
步
推
导
出
其
他
的
语
法
成
分
P
表
示
产
生
规
则
,
描
述
了
将
终
结
符
和
非
终
结
符
组
合
成
串
的
方
法
产
生
式
的
一
般
形
式
:
α
→
β
其
中
:
α
∈
(
V
T
⋃
V
N
)
+
,
且
α
中
至
少
包
含
V
N
中
的
一
个
元
素
,
称
为
产
生
式
的
头
或
左
部
β
∈
(
V
T
⋂
)
V
N
)
∗
,
称
为
产
生
式
的
体
或
右
部
S
表
示
开
始
符
号
,
S
∈
V
N
,
开
始
符
号
表
示
的
是
该
文
法
中
最
大
的
句
法
成
分
V
T
⋂
V
N
=
Φ
V
T
⋃
V
N
=
文
法
符
号
集
\begin{aligned} &文法G=(V_T,V_N,P,S)\\ &其中:\\ & \:\:V_T表示终结符集合,终结符是文法所定义的语言的基本符号\\ & \:\:V_N表示非终结符集合,非终结符是用来表示语法成分的符号,可以用来进一步推导出其他的语法成分\\ & \:\:P表示产生规则,描述了将终结符和非终结符组合成串的方法\\ & \:\:\:\:\:产生式的一般形式:\alpha \to\beta\\ & \:\:\:\:\:其中:\\ & \:\:\:\:\:\alpha\in(V_T\bigcup V_N)^+,且\alpha中至少包含V_N中的一个元素,称为产生式的头或左部\\ & \:\:\:\:\:\beta\in(V_T\bigcap) V_N)^*,称为产生式的体或右部\\ & \:\:S表示开始符号,S\in V_N,开始符号表示的是该文法中最大的句法成分 & \:\:V_T\bigcap V_N=\Phi\\ & \:\:V_T\bigcup V_N=文法符号集 \end{aligned}
文法G=(VT,VN,P,S)其中:VT表示终结符集合,终结符是文法所定义的语言的基本符号VN表示非终结符集合,非终结符是用来表示语法成分的符号,可以用来进一步推导出其他的语法成分P表示产生规则,描述了将终结符和非终结符组合成串的方法产生式的一般形式:α→β其中:α∈(VT⋃VN)+,且α中至少包含VN中的一个元素,称为产生式的头或左部β∈(VT⋂)VN)∗,称为产生式的体或右部S表示开始符号,S∈VN,开始符号表示的是该文法中最大的句法成分VT⋃VN=文法符号集VT⋂VN=Φ
-
实例:
KaTeX parse error: No such environment: align at position 8: \begin{̲a̲l̲i̲g̲n̲}̲ &如G=(\{id,+,*,… -
此外在不引起歧义的情况下,可以将文法简写,只写产生式规则,例如上面的文法可以简写为
G : E → E + E E → E ∗ E E → ( E ) E → i d G:E\to E+E\\ \:\:E\to E*E\\ \:\:E\to (E)\\ \:\:E\to id\\ G:E→E+EE→E∗EE→(E)E→id -
产生式的简写:对一组有相同左部的 α \alpha α产生式 α → β 1 , α → β 2 , . . . , α → β n \alpha\to\beta_1,\alpha\to\beta_2,...,\alpha\to\beta_n α→β1,α→β2,...,α→βn,可以简写为: α → β 1 ∣ β 2 ∣ . . . ∣ β n \alpha\to\beta_1|\beta_2|...|\beta_n α→β1∣β2∣...∣βn
例如上面的产生式可以简写为: E → E + E ∣ E ∗ E ∣ ( E ) ∣ i d E\to E+E|E*E|(E)|id E→E+E∣E∗E∣(E)∣id
三、语言
1、推导和规约:
-
直接推导:给定文法 G = { V T , V N , P , S } G=\{V_T,V_N,P,S\} G={VT,VN,P,S},若 α → β ∈ P \alpha\to\beta\in P α→β∈P,则可以将符号串 γ α δ 中 的 α 替 换 为 β \gamma\alpha\delta中的\alpha替换为\beta γαδ中的α替换为β,也就是说,将 γ α δ 重 写 为 γ β δ , 记 作 γ α δ ⇒ γ β δ \gamma\alpha\delta重写为\gamma\beta\delta,记作\gamma\alpha\delta\Rightarrow\gamma\beta\delta γαδ重写为γβδ,记作γαδ⇒γβδ,此时,称文法中的符号串 γ α δ \gamma\alpha\delta γαδ直接推导出 γ β δ \gamma\beta\delta γβδ
简而言之,直接推导就是用产生式的右部替换产生式的左部
-
推导和归约:若 α 0 ⇒ α 1 , α 1 ⇒ α 2 , α 2 ⇒ α 3 , . . . , α n − 1 ⇒ α n \alpha_0\Rightarrow\alpha_1,\alpha_1\Rightarrow\alpha_2,\alpha_2\Rightarrow\alpha_3,...,\alpha_{n-1}\Rightarrow\alpha_n α0⇒α1,α1⇒α2,α2⇒α3,...,αn−1⇒αn,可以记作 α 0 ⇒ α 1 ⇒ α 3 ⇒ . . . ⇒ α n − 1 ⇒ α n \alpha_0\Rightarrow\alpha_1\Rightarrow\alpha_3\Rightarrow...\Rightarrow\alpha_{n-1}\Rightarrow\alpha_n α0⇒α1⇒α3⇒...⇒αn−1⇒αn,称符号串 α 0 \alpha_0 α0经过n步推导出 α n \alpha_n αn,可以简记为 α 0 ⇒ n α n \alpha_0\Rightarrow^n\alpha_n α0⇒nαn,或这可以称 α n \alpha_n αn可以归约到 α 0 \alpha_0 α0
- ⇒ + \Rightarrow^+ ⇒+表示经过正数步推导
- ⇒ ∗ \Rightarrow^* ⇒∗表示若干步(可以是0)推导
- 推导的每一步是用产生式的右部替换产生式的左部,而归约是用产生式的左部替换产生式的右部
-
最右推导:对于推导过程中的每一步 α ⇒ β \alpha\Rightarrow\beta α⇒β,其都是将 α \alpha α中最右侧的非终结符进行替换
-
最左推导:对于推导过程中的每一步 α ⇒ β \alpha\Rightarrow\beta α⇒β,其都是将 α \alpha α中最左侧的非终结符进行替换
2、句型和句子
-
句型:若 S ⇒ ∗ α , α ∈ ( V T ⋃ V N ) ∗ S\Rightarrow^*\alpha,\alpha\in(V_T\bigcup V_N)^* S⇒∗α,α∈(VT⋃VN)∗,则称 α \alpha α是文法G的一个句型
- 一个句型中可以包含终结符,也可以包含非终结符,也可能是空串
-
句子:若 S ⇒ ∗ w , w ∈ V T ∗ S\Rightarrow^*w,w\in V_T^* S⇒∗w,w∈VT∗,则称w是文法G的一个句子
-
句子是不包含非终结符的句型
例如在以下推导过程中,值由little boy eats apple才能说是句型,其他的每一步都是句型
KaTeX parse error: No such environment: align at position 8: \begin{̲a̲l̲i̲g̲n̲}̲ &<句子>\Rightarr…
-
3、语言的形式化定义: 由文法G的开始符号S推导出的所有句子构成的集合称为文法G生成的语言,记为L(G),即: 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∗}
4、语言的运算
-
并运算: L ⋃ M = { s ∣ s 属 于 L 或 s 属 于 M } L\bigcup M=\{s|s属于L或s属于M\} L⋃M={s∣s属于L或s属于M}
-
连接: L M = { s t ∣ 属 于 L 且 t 属 于 M } LM=\{st|属于L且t属于M\} LM={st∣属于L且t属于M}
-
幂运算:
{ L 0 = { ϵ } L n − 1 = L n − 1 L , n > = 1 \begin{cases} L^0=\{\epsilon\}\\ L^{n-1}=L^{n-1}L,n>=1 \end{cases} {L0={ϵ}Ln−1=Ln−1L,n>=1 -
闭包: L ∗ = ⋃ i = 0 ∞ L i L^*=\bigcup^\infty_{i=0}L^i L∗=⋃i=0∞Li
-
正闭包: L ∗ = ⋃ i = 1 ∞ L i L^*=\bigcup^\infty_{i=1}L^i L∗=⋃i=1∞Li
四、文法的分类
1、0型文法: 若文法G[Z]中的每一条产生式规则都如: α → β \alpha\rightarrow\beta α→β,其中 α ∈ ( V T ⋃ V N ) ∗ \alpha\in(V_T\bigcup V_N)^* α∈(VT⋃VN)∗且至少含有一个非终结符,则称G[Z]为0型文法。0型文法没有对文法做任何限制,故又称无限制文法。由0型文法生成的语言又称0型语言
2、1型文法: 若文法G[Z]中的每一条产生式规则都如: α A β → α v β \alpha A\beta\rightarrow\alpha v\beta αAβ→αvβ,其中 α , β ∈ ( V T ⋃ V n ) ∗ , A ∈ V N , v ∈ ( V T ⋃ V N ) + \alpha,\beta\in(V_T\bigcup V_n)^*,A\in V_N,v\in(V_T\bigcup V_N)^+ α,β∈(VT⋃Vn)∗,A∈VN,v∈(VT⋃VN)+,则称G[Z]为1型文法。或者我们可以这样理解: ( ∀ α → β ) ∈ P , ∣ α ∣ ⩽ ∣ β ∣ (\forall\alpha\rightarrow\beta)\in P,|\alpha|\leqslant|\beta| (∀α→β)∈P,∣α∣⩽∣β∣。1型文法又称上下文有关文法。1型文法中不包含空产生式
3、2型文法: 若文法G[Z]中的每一条产生式规则都如: A → v A\rightarrow v A→v,其中 A ∈ V N , v ∈ ( V T ⋃ V n ) ∗ A\in V_N,v\in(V_T\bigcup V_n)^* A∈VN,v∈(VT⋃Vn)∗,则称G[Z]为2型文法。即2型文法的右部都不包含非终结符。2型文法又称上下文无关文法
4、3型文法: 3型文法分为右线性文法和左线型文法,在3型文法中,产生式的右部最多只有一个非终结符,且总在同一侧。3型文法又称正则文法
-
右线性文法: 若文法G[Z]中的每一个产生式规则都如: A → α B 或 A → α A\rightarrow\alpha B或A\rightarrow\alpha A→αB或A→α,其中 A , B ∈ V N , α ∈ ( V T ⋃ V N ) ∗ A,B\in V_N,\alpha\in(V_T\bigcup V_N)^* A,B∈VN,α∈(VT⋃VN)∗,则称文法G[Z]为右线性文法
-
左线型文法: 若文法G[Z]中的每一个产生式规则都如: A → B α 或 A → α A\rightarrow B\alpha或A\rightarrow\alpha A→Bα或A→α,其中 A , B ∈ V N , α ∈ ( V T ⋃ V N ) ∗ A,B\in V_N,\alpha\in(V_T\bigcup V_N)^* A,B∈VN,α∈(VT⋃VN)∗,则称文法G[Z]为左线型文法
在不考虑空串的情况下,四种文法之间是逐级限制的关系,0型文法没有任何限制,在0型文法的基础上使产生式左部的长度适中小于等于产生式右部的长度得到1型文法,在1型文法的基础上使产生式的左部均为非终结符得到2型文法,在2型文法的基础上,对产生式右部进行限制得到3型文法
五、语法分析树
1、语法分析树:
- 根节点:为文法的开始符号
- 内部节点:表示对一个产生式 A → B A\rightarrow B A→B的应用该节点表示对应的产生式的左部,而该节点的子节点从左到右构成了对应产生式的右部
- 叶子节点:既可以是非终结符也可以是终结符,从左到右排列叶子节点得到的字符串称为该分析树的产出或边缘
给定一个推导 S ⇒ α 1 ⇒ α 2 ⇒ . . . ⇒ α n S\Rightarrow\alpha_1\Rightarrow\alpha_2\Rightarrow...\Rightarrow\alpha_n S⇒α1⇒α2⇒...⇒αn,对于推导过程中得到每一个句型 α i \alpha_i αi,都可以构造出一个产出为 α i \alpha_i αi的分析树
例如对于文法G[E]:
E
→
E
+
E
E
→
E
∗
E
E
→
−
E
E
→
(
E
)
E
→
i
d
E\rightarrow E+E\\ E\rightarrow E*E\\ E\rightarrow -E\\ E\rightarrow (E)\\ E\rightarrow id
E→E+EE→E∗EE→−EE→(E)E→id
通过推导过程:
E
⇒
−
E
⇒
−
(
E
)
⇒
−
(
E
+
E
)
⇒
−
(
i
d
+
E
)
⇒
−
(
i
d
+
i
d
)
E\Rightarrow-E\Rightarrow-(E)\Rightarrow-(E+E)\Rightarrow-(id+E)\Rightarrow-(id+id)
E⇒−E⇒−(E)⇒−(E+E)⇒−(id+E)⇒−(id+id),可以得到如下分析树:
E
↙
↘
−
E
↙
↓
↘
(
E
)
↙
↓
↘
E
+
E
↓
↓
i
d
i
d
E\\ \swarrow\searrow\\ -\ \ \ \ \ \ \ E\\ \ \ \ \ \ \ \ \ \ \swarrow\downarrow\searrow\\ \ \ \ \ \ \ \ \ \ \ (\ \ \ \ E\ \ \ \ )\\ \ \ \ \ \ \ \ \ \ \ \swarrow\downarrow\searrow\\ \ \ \ \ \ \ \ \ \ \ \ E\ +\ E\\ \ \ \ \ \ \ \ \ \ \ \downarrow\ \ \ \ \ \ \ \ \ \downarrow\\ \ \ \ \ \ \ \ \ \ id\ \ \ \ \ \ id
E↙↘− E ↙↓↘ ( E ) ↙↓↘ E + E ↓ ↓ id id
2、短语、直接短语与句柄
给定一个句型,其分析树中的每一颗子树的产出称为该句型的一个短语,若子树只有父子两代节点,即分析树的高度为2,那么这颗子树的产出称为该句型的一个直接短语,一个句型的最左直接短语称为该句型的句柄。例如下面的这颗分析树,它的短语包括:-(E+E),(E+E),E+E,它的直接短语是E+E,它的句柄是E+E
E
↙
↘
−
E
↙
↓
↘
(
E
)
↙
↓
↘
E
+
E
E\\ \swarrow\searrow\\ -\ \ \ \ \ \ \ E\\ \ \ \ \ \ \ \ \ \ \swarrow\downarrow\searrow\\ \ \ \ \ \ \ \ \ \ \ (\ \ \ \ E\ \ \ \ )\\ \ \ \ \ \ \ \ \ \ \ \swarrow\downarrow\searrow\\ \ \ \ \ \ \ \ \ \ E\ +\ E\\
E↙↘− E ↙↓↘ ( E ) ↙↓↘ E + E
3、文法的二义性
若一个文法存在某个句子对应的两颗不同的语法树,则称该文法是二义的。例如以下文法:
E
→
i
∣
E
+
E
∣
E
∗
E
∣
(
E
)
E\rightarrow i|E+E|E*E|(E)
E→i∣E+E∣E∗E∣(E)
其可以构造出这样的句型:
i
∗
i
+
i
i*i+i
i∗i+i,而该句型可以构造出如下两种语法树:
E
↙
↓
↘
E
+
E
↙
↓
↘
↓
E
∗
E
i
↓
↓
i
i
\ \ \ \ \ \ \ \ \ E\\ \ \ \ \ \ \ \ \ \ \swarrow\downarrow\searrow\\ \ \ \ \ \ \ \ \ \ E\ +\ E\\ \ \ \ \ \swarrow\downarrow\searrow\ \ \ \ \ \ \downarrow\\ \ \ \ E\ \ *\ \ E\ \ \ \ i\\ \downarrow\ \ \ \ \ \ \ \ \ \ \ \downarrow\ \ \ \\ i\ \ \ \ \ \ \ \ \ \ \ \ i\ \ \ \
E ↙↓↘ E + E ↙↓↘ ↓ E ∗ E i↓ ↓ i i
E ↙ ↓ ↘ E ∗ E ↓ ↙ ↓ ↘ i E + E ↓ ↓ i i E\\ \swarrow\downarrow\searrow\\ E\ \ *\ \ E\\ \ \ \ \downarrow\ \ \ \ \ \ \swarrow\downarrow\searrow\\ \ \ \ \ \ \ i\ \ \ \ \ E\ +\ E\\ \ \ \ \ \ \ \ \ \ \ \ \ \downarrow\ \ \ \ \ \ \ \ \ \ \downarrow\\ \ \ \ \ \ \ \ \ \ \ i\ \ \ \ \ \ \ \ \ \ \ i E↙↓↘E ∗ E ↓ ↙↓↘ i E + E ↓ ↓ i i
因此该文法是二义的
-
二义性的消除:
-
不改变文法,仅附加一些限制性条件,以此生成确定的语法树,例如上面的文法,可以规定*优先级高于+,且他们都服从左结合
-
改变文法,构造一个等价的新文法,把排除二义性的规则合并到元文法中,例如上面的文法,可以改写成:
E → E + T ∣ T T → T ∗ F ∣ F F → ( E ) ∣ i E\rightarrow E+T|T\\ T\rightarrow T*F|F\\ F\rightarrow(E)|i E→E+T∣TT→T∗F∣FF→(E)∣i
-