前言:《编译原理》是计算机科学与技术专业的一门重要的专业课。此课程不仅学习编译的基本原理,还会学到具体的编译技术和方法,这些技术和方法也可以应用在普通的软件开发中。
第一章 编译概述
一、编译程序与解释程序
编译程序是一个语言处理程序,它把一个高级语言程序翻译成某个机器的汇编语言程序或二进制代码程序。它是整个程序全部翻译完成之后,再一次性执行。
解释程序是接受某个语言的程序并立即运行这个源程序,不需要在运行时先把源程序翻译成目标代码,也可以实现在某台机器上运行程序并生成结果。解释程序是一个个的获取,分析,并执行源代码语句,一旦一个语句分析结束,源代码可以开始运行并生成代码。
二、编译程序的八个组成部分
词法分析程序—对构成的源程序的字符流进行扫描和分解,从而识别出每个单词。
语法分析程序—判断输入的字符串在语法上是否正确。
语义分析程序—审查源程序有无语义错误,为代码生成阶段收集类型信息。
中间代码生成程序—为优化代码做准备。
优化代码程序—对前一阶段产生的中间代码进行变换或进行改造,使目标代码更为高效。
目标代码生成程序—将中间代码变换成机器上的绝对指令代码。
表格管理程序—对符号表进行维护管理,登记,查找,分析,释放空间。
出错处理程序—对程序中错误的代码进行处理。
第二章 文法和语言
2.1符号和符号串
2.1.1 字母表
字母表是元素的非空有穷集合。通常由大小写字母,数字和希腊字母表示。
eg:A={1,3} Σ={e,f,g}
2.1.2符号串
1.符号串是是由字母表中的符号组成的任何有穷序列。
eg:001110是字母表A={0,1}上的字符串
a,b,c,ab,aaca是Σ={a,b,c}上的字符串
2.符号串的长度:如果某符号串x中有n个符号,则|x| = n 表示其符号串的长度为n
3.空符号串:用ε表示,长度为0,|ε| = 0;
4.子符号串:一个非空符号串中若干连续符号组成的部分。
eg:对于x=ABC表示“x是符号A,B,C,并按此顺序组成的字符串”,其中A,AB,ABC都是其子串,BA,ε都不是 。
5.符号串的一些常见运算
(1)符号串的头尾,固有头和固有尾
如果z=xy是一符号串,x是z的头,y是z的尾,如果x是非空的,则y是固有头;如果y是非空的x是固有尾。
(2)符号串的连接
如果a和·b为符号串,x=AB,y=CDEF,则它们的连接xy=ABCDEF,|x| = 2,|y|=4, |xy|=6。
(3)符号串的方幂(表示符号串时书写方便)
若x是符号串·,把x自身连接m次得到字符串y,即y = xx……xx,称为符号串x的方幂。
(4)符号串的集合
闭包:集合的若干次幂(可以为0次)
A*= A^0UA^1UA^2U……A^n……
正闭包:集合的若干次幂次(至少为一次·)
A+= A^1UA^2U……A^n……
2.2文法和语言的形式定义
文法是一个规则的集合,用来描述另外一个集合(具有一定的特征)。
语言是文法描述的对象,是该文法中一切句子的集合·。
1.产生式规则
定义:一个产生式规则是一个有序对(a,b)。通常写作a→b或a::=b,其中a称为规则的左部,b成为规则的右部(a,b可以为多个符号),定义为可用“→”和“::=”表示。
2.文法
文法G定义为四元组(VN,VT,P,S),其中VN为非终结符集,VT为终结符,P为规则(a→b)的集合,a属于(VNUVT)*且至少含有一个非终结符(至少有一个大写字母),b属于(VNUVT)*,S为起始符,它是一个非终结符,至少在一条规则中作为左部出现。
一般规定,第一条产生式的左部为识别符;用大写字母表示非终结符,用非大写字母表示为终结符。
eg:G[S]:S→0S1
S→01
3.推导
(1)直接推导:在某个文法中,从起始符开始推导到具体的符号。
(2)归约(逆推导):在某个文法中,从具体的符号推导到起始符。
仍用上述例子:
G[S]:S→aB
B→bB|C
直接推导序列:S⇒aB⇒abB⇒abbB⇒abbc
归约:abbc⇒abbB⇒abB⇒aB⇒S
4.句型和句子
句型:如果G[S]是一个文法,从起始符开始经若干步推导出来的所有符号是该文法的句型
句子:在某句型的前提下,仅由终结符组成的符号(不能继续往下推导)。
eg:
G[S]:S→aB
B→bB|c
S⇒aB⇒abB⇒abbB⇒abbc,
如aB, abB,abbB,abc是字符串,bB不是句型,abbc为句子。
2.3文法的类型
1. 0型文法(短语文法)
若文法G[S]=(VN,VT,P,S),如果它的每个产生式形式为:α→β,其中α∈(VN∪VT)*且至少含有一个非终结符号,而β∈(VN∪VT)*,则G为一个0型文法(符合文法的最基本定义)。
eg:G[S]
S→bB|CS|d
d→Bb|A|a
A→aA|a
上述不是一个文法·
改为:G[S]
S→bB|CS|d
dA→Bb|A|a
A→aA|a
是一个0型文法(左边至少含有一个非终结符,用大写字母表示)
2. 1型文法(上下文有关文法)
若文法G[S]=(VN,VT,P,S),,P中的每个产生式α→β(长度右边大于左边),均满足|α|>|β|,则G[S]为1型文法。
3. 2型文法(上下文无关文法)
若文法G[S]=(VN,VT,P,S), ,P中的每个产生式α→β满足而α是一个非终结符(α的数量为一个),β∈(VN∪VT)*, 则G[S]为2型文法。
eg :G={{S,A,B},{a,b},P,S},P由下列产生式组成:
S→aB|bA
A→a|aS|bAA
B→b|bS|aBB
4. 3型语言(正规文法)
若文法G[S]=(VN,VT,P,S),P中的每个产生式的形式为:A→αB或A→α,其中A,B都是非终结符,α∈VT*,则G[S]为3型文法。
eg :G={{S,A,B},{0,1},P,S},P由下列产生式组成:
S→0A|1B|0
A→0A|0S|1B
B→1B|1|0
G是正规文法
2.3上下文无关文法及其语法树
1.语法树(推导树)是一种描述上下文无关文法的句型推导的直观工具。
eg:G={{S,A},{a,b},P,S},其中P为
1. S→aAS
2. A→SbA
3. A→SS
4. S→a
5. A→ba
S⇒aAS⇒aSbA⇒aabAS⇒aabbaS⇒aabbaa
2.最左(最右)推导:α,β都是句型,在推导的任何一步推导α⇒β,都是对α中的最左(最右)非终结符进行替换,最右 推导常被称为规范推导。
eg:文法G[E]
E→E+E|E*E|(E)i
推导写出i*i+i是否为其句子
最左推导(不唯一)
E⇒E+E⇒E*E+E⇒i*E+E⇒i*i+E⇒i*i+i
最左推导的语法树
最右推导(不唯一)
E⇒E*E⇒i*E⇒i*E+E⇒i*i+E⇒i*i+i
最右推导的语法树
3.二义性:如果一个文法存在某个句子对应两颗不同的语法树或一个文法中存在某个句子,他有两个最左(最右)推导,则说这个文法是二义的
2.4句型的分析
设G[Z]是一个文法,假定αβδ是文法G的一个句型。
短语:若存在S⇒+ αAδ且A ⇒+ β,则称β是句型αβδ相对于非终结符A的短语(该句型中可以归约的子串,且能够整体归约成功)。
直接短语:若存在S ⇒+ αAδ且A⇒β,则称β是句型αβδ相对于产生式规则A→β的直接短语(在该句型中经过一步就可归约成功)。
句柄:一个句型的最左直接短语称为该句型的句柄。
eg:G[E]
E→T|E+T
T→F|T*F
F→(E)|i
构造一个语法树
短语:i(相对F), T*i(相对T),T*i(相对E),F(相对T),T*i+F(相对E)
直接(简单)短语:i(相对F),F(相对T)
句柄:i(相对F)