编译原理期末复习

文章深入探讨了编译原理,包括翻译程序的类型、编译程序的五个阶段,详细阐述了词法分析、语法分析理论及其实现,特别是LR分析家族(SLR、LR(1)、LALR)等自底向上分析法。同时,介绍了语法制导翻译的基本概念和应用。
摘要由CSDN通过智能技术生成

编译原理

第一章 编译概述

1.1.翻译程序的三种方式

  1. 编译:将高级语言编写的源程序翻译成等价的机器语言或汇编语言。(生成文件,等价)
  2. 解释:将高级语言编写的源程序翻译一句执行一句,不生成目标文件,直接执行源代码文件。(一句一句,不生成为文件)
  3. 汇编:用汇编语言编写的源程序翻译成与之等价的机器语言。

2.1.编译程序的五个阶段

  1. 词法分析:对源程序的字符串进行扫描和分解,识别出每个单词符号。
  2. 语法分析:根据语言的语法规则,把单词符号分解成各类语法单位。
  3. 语义分析与中间代码生成:对各种语法范畴进行静态语义检查,若正确则进行中间代码翻译。
  4. 代码优化:遵循程序的等价变换规则。
  5. 目标代码生成:将中间代码变换成特定机器上的低级语言代码。

第二章 文法与语言

2.1 符号串和语言

2.1.1 字母表

  1. 定义:字母表是有穷非空的符号集合。
  2. 表示:通常用字母表大写字母A,B,…Z和希腊字母Σ表示。
    eg:A={0,1},Σ={a,b,c,d}
  3. 说明
    1)字母表包含了语言中所允许出现的一切符号。
    2)字母表中的符号也称字符。

2.1.2 符号串

  1. 定义:由字母表中的符号组成的有穷序列
  2. 表示:通常由t,u,v,w,x,y,z等小写英文字母来表示。
  3. 说明
    1)符号串由构成的符号的种类、数量、顺序共同决定。
    2)不包含任何符号的符号串称为空符号串,简称空串,用ε表示。
  4. 对于给定的字母表Σ,符号串的递归定义如下:
    1)ε是Σ上的一个符号串。
    2)若x是Σ上的符号串,a是Σ的符号,则xa是Σ上的符号串。并规定εa=a,aε=a。
    3)y是Σ上的符号串,当且仅当y由1)和2)导出。
  5. 子符号串:一个非空符号串中若干连续符号组成的部分。
  6. 字符串的前缀和后缀
    若z=abd是字母表Σ={a,b,c,d}上的符号串,则ε,a,ab,abd都是z的前缀;ε,d,bd,abd都是z的后缀
  7. 符号串之间的运算
    1)连接:符号串x,y的连接xy就是把符号串y写在x后面得到的字符串。
    eg:若x=ab,y=cd,则xy=abcd,yx=cdab。
    2)方幂:若x是符号串,xn表示n个按顺序连接。当n=0时,x0是空符号串ε。
术语示例
|S||abc| = 3
ε|ε| = 0
S1S2abc def = abcdef
Sn(abc)3 = abcabcabc
S 的前缀 Xabc 的前缀有:ε, a, ab, abc
S 的后缀 Xabc 的后缀有:ε, c, bc, abc
S 的子串 Xabc 的子串有:ε, a, b, c, …
S 的真前缀abc 的真前缀有:a, ab(去掉空和全)
S 的真后缀(去掉空和全)
S 的真子串(去掉空和全)
S 的子序列 Xabdf 是 abcdef 的一个子序列(和原序列顺序相同,可去掉一些字母)
术语意义
Φ空集合
{ ε }空串是唯一元素
X = L ∪ M并: X = { s| s∈L or S ∈M }
X = L ∩ M交:X = { s | s∈L and S ∈M }
X = LM连接: X = { st|s∈L and t ∈ M }
X = L*(星)闭包:X= L0∪L1∪L2∪…
X = L+正闭包:X= L1∪L2∪L3∪…

2.1.3 语言

  1. 定义:由字母表上的一些符号串组成的集合
  2. 说明
    空集Ø是一个语言,仅含一个空符号串的集合{ε}也是一个语言。Ø和{ε}是不同的语言。
  3. 符号串集合之间的运算
    1)并集
    设A和B是符号串的集合,则A和B的并集定义为
    A∪B = {x | x∈A or x∈B}。
    2)乘积
    设A和B是符号串的集合,则A和B的乘积定义为
    AB = {xy | x∈A and y∈B}。
    eg:若A={a,b},B={b,c},则AB = {ab,ac,bb,bc}。
    对任意符号串集合A,有{ε}A = A{ε} = A。
    3)幂运算
    设A是符号串的集合,则A的幂运算定义为
    A0 = {ε}
    A1 = A
    An = AAn-1(n>0)
    eg:若A={0,1},则A0={ε},A1={0,1},A2={00,01,10,11}。
    4)正闭包与闭包
    设A是符号串的集合,则集合A的正闭包A+和闭包A定义为
    A+ = A1∪A2∪…∪An∪…
    A
    = A0∪A1∪…∪An∪…
    eg:若A={0,1},则A+={0,1,00,01,10,11,000,001,…},A*={ε,0,1,00,01,10,11,000,001,…}。

2.2 文法和语言的形式化定义

2.2.1 文法的形式化定义

  1. 产生式规则
    1)定义:一个产生式规则是一个有序对(A,α)。通常写作A→α或A::=α。
    ”→"或”::=”表示“定义为”、“由…组成”、“生成”。
    2)含义: A→α表示左部符号A生成右部符号串α。
    3)若A→α;A→β,则可以写成A→α|β。”|”表示“或”。
    4)非终结符号:产生式规则左部出现的符号。
    5)终结符号:不是非终结符号的符号。
    6)非终结符号既可以出现在产生式规则的左部,也可以出现在产生式规则的右部。终结符号不能出现在产生式规则的左部。(终结符号不能再生成产生式的右部)
    7)非终结符号通常用大写字母或尖括号括起来的部分表示
  2. 文法(产生式规则的集合)
    1)定义:产生式规则的非空有穷集合。由四元组G=(VN,VT,P,Z)组成。
    2)VN:是一个非空有穷集合。它的每个元素称为非终结符号。且VN∩VT=Ø
    3)VT:是一个非空有穷集合。它的每个元素称为终结符号。
    4)P:是文法规则(产生式规则)的非空有穷集合,每个产生式规则的形式是A→α或A::=α,其中A∈VN,α∈(VN∪VT)
    5)Z:是一个非终结符号。称为开始符号或识别符号。它至少要在一条产生式规则的左部出现。由它开始识别定义的语言。(开始符号Z必须是非终结符号,并且至少在一条产生式规则左部出现,用于生成开始符号后的下一条语句
    6)通常不必将文法的四元组显式地表示出来,而仅需给出文法的
    产生式规则集P(由此即能知道Z,Vn,Vt)*。
    7)对于两个不同的文法G[Z]和G’[E],若这两个文法生成的语言相同(结果集相同,具有相同的句型以及句子),则称这两个文法是等价的

2.2.2 语言的形式化定义

  1. 直接推导与推导(直接推导是一步,推导是任意步
    1)直接推导:令G=(VN,VT,P,Z),若A→γ∈P,且α,β∈(VN∪VT),则称αAβ直接推导出αγβ,表示成αA ⇒ βαγβ(这是上下文有关文法,1型文法)
    2)推导:若存在一个直接推导序列: a 0 {a}^{0} a0 a 1 {a}^{1} a1 a 2 {a}^{2} a2⇒…⇒ a n {a}^{n} an,则称这个序列是一个从 a 0 {a}^{0} a0 a n {a}^{n} an的长度为n的推导。
    当n>0时, a 0 {a}^{0} a0 a n {a}^{n} an的推导记为 a 0 {a}^{0} a0 + a n { +a}^{n} +an,表示从 a 0 {a}^{0} a0出发,经过1步或者若干步可推导出 a n {a}^{n} an
    当n≥0时, a 0 {a}^{0} a0 a n {a}^{n} an的推导记为 a 0 {a}^{0} a0
    a n {a}^{n} an,表示从 a 0 {a}^{0} a0出发,经过0步或者若干步可推导出 a n {a}^{n} an
  2. 句型和句子(句子是树根,为终结符集,可以推导出来的则都为句型
    设有文法G[Z],Z是文法G的开始符号。
    1)句型:若Z ⇒* x,x∈(VN∪VT),则称符号串x为文法G[Z]的句型。(非空终结或者非终结符集
    2)句子:若Z ⇒
    x,x∈VT*,则称符号串x为文法G[Z]的句子。(非空终结符集
    3)句子一定是句型,句型不一定是句子。
  3. 语言(语言是句子的集合,并且每个句子都能从开始符号推导得来,是终结符集的闭包的子集
    1)定义:文法G[Z]产生的所有句子的集合(注意是句子不是句型)称为文法G所定义的语言,记为L(G[Z]),简写为L(G)。L(G)={x| Z ⇒+ x且x∈VT*}
    2)语言L(G)是VT*的子集。
    3)L(G)中的每一个符号串均由终结符号组成,且该符号串能由开始符号Z推导出来。
  4. 递归规则(直接递归)
    1)定义:一个产生式规则中,出现在左部的非终结符也出现在其右部。
    2)种类:左递归、右递归、递归。
    3)左递归:A→A…(非终结符在左侧)
    4)右递归:A→…A (非终结符在右侧)
    5)递归:A→…A…(非终结符在中间)
  5. 文法递归(任一非终结符,推导可得该非终结符本身
    1)定义:对于文法中的任一非终结符,若能建立一个推导过程,在推导所得的符号串中又出现该终结符本身,则称文法是递归的。
    2)种类:左递归、右递归、递归。
    3)左递归:A ⇒+ A…
    4)右递归:A ⇒+ …A
    5)递归:A ⇒+ …A…

2.2.3 短语、直接短语、句柄

  • 直接短语一定是一个产生式的右部,但是产生式的右部不一定是当前句型的直接短语
  • 高人,民生,活水则都不是当前句型的直接短语
    在这里插入图片描述

在这里插入图片描述

设G[Z]是一个文法,假定αβδ是文法G的一个句型。
1)短语:若存在Z ⇒+ αAδ且A ⇒+ β,则称β是句型αβδ相对于非终结符A的短语。(即子树的边缘
2)直接短语:若存在Z ⇒+ αAδ且A⇒β,则称β是句型αβδ相对于产生式规则A→β的直接短语。(高度为2的子树的边缘
3)句柄:一个句型的最左直接短语称为该句型的句柄。

2.2.4规范推导和规范归约

  1. 最左推导:对一个推导序列中的每一步直接推导α⇒β,都是对α中的最左非终结符进行替换
  2. 最右推导(规范推导):对一个推导序列中的每一步直接推导α⇒β,都是对α中的最右非终结符进行替换
  3. 规范句型:由规范推导得到的句型。
  4. 最左归约(规范归约):规范推导的逆过程

2.3 语法分析树与文法的二义性

2.3.1 语法分析树

  1. 语法分析树:一个句型推导过程的树形表示称为语法分析树,简称语法树。
  2. 满足条件:设G=( V N {V}^N VN V T {V}^T VT,P,Z)是一个上下文无关文法(CFG)。
    1)根节点的标记为Z。
    2)根节点外的每个节点也有一个标记,它是 V N {V}^N VN V T {V}^T VT∪{ε}中的符号。
    3)每一个内部节点(非终结符,所以标记在 V N {V}^N VN)的标记A必在VN中。
    4)若某个内部节点标记为A,其子节点的标记从左到右分别为X1,X2,…,Xn,则A→X1X2…Xn必为P中的一条产生式规则。
    5)若节点有标记ε,则该节点为叶子,且是它父亲唯一的孩子(子节点存在标记ε,则是其父节点的唯一子节点,即其无兄弟节点)。
  3. 构造步骤:已知文法G[Z],对于w,若Z ⇒* w,则
    1)以开始符号Z为标记的根节点。
    2)对每一步推导,根据使用的产生式规则生成一颗子树,直到所有叶子节点从左到右的标记符号连接为w为止。
    若产生式规则为A→X1X2…Xn,则生成以A为根节点的子树,其孩子节点从左到右分别为X1,X2,…,Xn。
    eg:设文法G[E]:
    E→E+T|E-T|T
    T→TF|T/F|F
    F→(E)|i
    推导句型T+i
    (F-i)的语法树。

在这里插入图片描述

2.3.2 文法的二义性

  1. 定义:若一个文法存在某个句子对应两棵不同的语法树,则称这个文法是二义的。
  2. 特点:为编译程序的执行带来不确定性

2.3.3 二义性的消除

  1. 不改变文法:通过附加限制性条件(增加消歧规则,例如:每个if跟最近的尚未匹配的else匹配)消除二义性。
    寻找充分不必要条件,当文法满足这些条件时可确保文法是无二义性的。(即满足就是二义性,不满足也不一定是无二义性
    2.改变文法:改写原有文法(增加 V N {V}^N VN或者空产生式),把排除二义性的规则合并到原文法消除二义性。

2.4 文法的化简

  1. 若一个非终结符不能推导出终结字符串,则该非终结符是无用的,删除所有包括该非终结符的产生式规则。
  2. 若一个符号不能出现在文法的任何句型中,则该符号是无用的,删除所有包括该符号的产生式规则。

2.5 语言的分类

二型识别程序设计语言,三型定义程序设计语言

  • 0型文法(短语文法,上下文无关文法),每个产生式的左边α∈( V N {V}^N VN V T {V}^T VT)*且至少含有一个非终结符号
    1)定义:若文法G[Z]=( V N {V}^N VN V T {V}^T VT,P,Z)中的每个产生式规则的形式为:α→β,其中α∈( V N {V}^N VN V T {V}^T VT)且至少含有一个非终结符号,而β∈( V N {V}^N VN V T {V}^T VT),则G[Z]为0型文法。
    2)特点:0型文法的能力相当于图灵机,识别能力最强
  • 1型文法(上下文敏感文法)
    1)定义:若文法G[Z]=( V N {V}^N VN V T {V}^T VT,P,Z)中的每个产生式规则的形式为:αAβ→αvβ,其中α,β∈( V N {V}^N VN V T {V}^T VT),A∈ V N {V}^N VN,v∈( V N {V}^N VN V T {V}^T VT)+,则G[Z]为1型文法。
  • 2型文法(上下文无关文法)
    1)定义:若文法G[Z]=( V N {V}^N VN V T {V}^T VT,P,Z)中的每个产生式规则的形式为:A→v,其中A∈ V N {V}^N VN,v∈( V N {V}^N VN V T {V}^T VT)*,则G[Z]为2型文法。
    2)特点:语法结构上下文无关,一般用于识别程序设计语言的语法结构
  • 3型语言(正规文法)
    1)种类:右线性文法、左线性文法
    正则文法 左(右)线性文法
    2)右线性文法:若文法G[Z]=( V N {V}^N VN V T {V}^T VT,P,Z)中的每个产生式规则的形式为:A→αB或A→α,其中A,B∈ V N {V}^N VN,α∈( V N {V}^N VN V T {V}^T VT),则G[Z]为右线性文法。(非终结部分永远在右部
    3)左线性文法:若文法G[Z]=( V N {V}^N VN V T {V}^T VT,P,Z)中的每个产生式规则的形式为:A→Bα或A→α,其中A,B∈ V N {V}^N VN,α∈( V N {V}^N VN V T {V}^T VT)
    ,则G[Z]为左线性文法。(非终结部分永远在左部
    4)特点:作为定义程序设计语言规则的文法
    5)正规语言:3型文法定义的语言。

2.6课后问题

在这里插入图片描述

第三章 词法分析与有限自动机

3.0正则表达式

3.0.1概念

  1. 正则表达式 是一种用来描述正则语言的更紧凑的表示方法
  2. 用正则表达式表示的语言叫做正则语言或者正则集合
    比如某个语言L = {a}{a, b} * ( {ε} ∪ ( { . , _ } {a , b} { a, b }* ) )
    利用正则表达式:
    r = a (a | b) * (ε | (. | _) (a | b) (a | b)* )
  3. 正则表达式可以由较小的正则表达式按照特定规则递归地构建 , 每个正则表达式r 定义一个语言, 记为 L (r).这个语言也是根据r的子表达式所表示的语言递归定义的.

3.0.2定义

  • ε 是一个正则表达式(RE) L (ε) = { ε }
  • 如果a ∈ ∑ , 则a是一个RE, L(a) = {a}
  • 假设r 和 s都是RE, 表示的语言分别是 L(r) 和 L (s) , 则:

r | s 是一个RE, L(r | s) = L (r) ∪ L(s)
r s是一个RE, L(rs) = L(r)L(s)
r* 是一个RE, L(r*) = (L(r))*
( r ) 是一个正则表达式 L( (r) ) = L(r)

优先级: * , 连接, |
例:
∑ = {a, b}, 则:

L(a | b) = L(a) ∪ L(b) = {a} ∪ {b} = {a, b}
L( (a | b) (a | b) ) = L(a | b) L (a | b) = {a, b} {a, b} = {aa, ab, ba, bb}

L(a*) = (L(a))* = {a}* = {ε, a, aa, aaa, .....}
L((a | b) *) = (L(a | b))* = {ε, a, b, aa, ab, ba, bb, .......} 

L(a | a* b) = {a, b, ab, aab, aaab , .....}

十进制整数
(1 | … | 9) (0 | … | 9)* | 0

八进制整数:
0 (1 | …| 7) (0 | …| 7)*

十六进制整数:
0x (1 | … | 9 | a | …| f) (0 | …| 9 | a | … | f)*



3.0.3正则文法与正则表达式等价

任何正则文法G 存在定义同一语言的正则表达式r
任何正则表达式r, 存在生成同一语言的正则文法G

3.0.4正则定义

  1. 正则定义是具有以下形式的定义序列
  • 他们给一些RE命名, 并在之后的RE 中像使用字母表中符号一样使用这些名字
    d1 -> r1
    d2 -> r2

    dn -> rn
    每个di都是一个新符号, 他们都不在字母表∑中,并且各不相同
    每个ri是字母表∑∪ {d1, d2, …di-1}上的正则表达式
C语言中的标识符正则定义
digit  -> 0 | 1 | 2 | .... | 9
letter_  -> A | B | ...| Z | a | b | ...| z | _
id -> letter_ (letter_ | dight) *
(整数或者浮点数) 无符号数的正则定义
digit -> 0 | 1 | 2 | … | 9
digits -> digit digit *
小数部分 -> .dights | ε
指数部分 -> ( E(+|-|ε)digits ) | ε
数字 -> digits 小数部分 指数部分

3.0.5有穷自动机FA

FA分为DFA(确定的有穷自动机)以及NFA(不确定的有穷自动机)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.1 词法分析器的设计

3.1.1 词法分析器的任务

  1. 功能:输入源程序,输出单词符号。

3.1.2 词法分析器的输出格式

单词是程序的基本语言单位
通常,输出的单词符号表示成二元式:(单词种类,单词符号的属性值)
单词种类:关于单词种类的整数编码。
单词符号的属性值:反应单词符号特性或特征的值。

  1. 单词的种类
    1)关键字:eg:while、if、else
    2)标识符:eg:变量名、数组名、函数名…
    3)常数:eg:80、1.23、“Hello“…
    4)运算符:eg:算术运算符、逻辑运算符、关系运算符…
    5)界限符:eg:,、:、[、]、{、}…
    除了五类单词,还包括空格符、回车符、换行符等

3.2 词法分析器的手工构造

3.2.1 确定的有限自动机

  1. 定义:一个确定的有限自动机(DFA)
    M是一个五元组:M=(S,Σ,δ,s0,F),其中:
    1)S是一个有限集,它的每一个元素称为一个状态。
    2)Σ是一个有穷字母表(不包含空),它的每个元素称为一个输入字符。
    3)δ是一个从S×Σ到S的单值部分映射。δ(s,a)=s’表示在目前状态s下输入字符为a时,将转换到下一个状态s’。s’被称为s的一个后继状态。
    4)s0∈S,s0是唯一的初态(start)
    5)F ⊆S,F是一个终态集,可以为空

  2. DFA的状态转移矩阵(转换表
    DFA可用一个二维矩阵表示,矩阵的行表示状态,列表示输入字符,矩阵元素表示δ(s,a)的值。

  3. DFA的状态转换图
    若设DFA M含有m个状态和n个输入字符,则这个图含有m个状态结点,每个结点至多有n条箭弧射出与其它的状态结点相连接,每个箭弧用Σ中的一个不同输入字符作为标记。整张图含有唯一的初态结点和若干终态结点

  4. DFA识别字符串
    1)对Σ上的任何符号串w∈Σ*,若存在一条从初态结点到某一终态结点的通路,且该通路上所有弧的标记符连接成的字符串等于w,则称w可被DFA M所识别。若M的初态结点同时又是终态结点,则空字符串ε被M所识别
    2)DFA与语言的关系:DFA M所能识别的符号串的全体记为L(M)。
    eg:设DFA M=({0,1,2,3},{a,b},δ,{3}),其中,δ定义为:
    δ(0,a)=1,δ(0,b)=2,δ(1,a)=3,δ(1,b)=2,δ(2,a)=1,δ(2,b)=3,δ(3,a)=3,δ(3,b)=3。
    在这里插入图片描述

  5. δ的递归扩展定义(递归
    对一个DFA M,其识别的语言L(M)={w|w∈Σ*,若存在Z∈F,使δ(s0,w)=Z},其中:w=ua∈Σ*,则δ(s,ε)=s,δ(s,ua)= δ(δ(s,u),a)。

3.3 有限自动机及其化简

有限自动机包括确定有限自动机和不确定有限自动机。

3.3.1 不确定有限自动机

  1. 定义:一个不确定有限自动机(NFA) M是一个五元组:M=(S,Σ,δ, S 0 S_0 S0,F),其中:
    1)S是一个有限集,它的每一个元素称为一个状态。
    2)Σ是一个有穷字母表,它的每个元素称为一个输入字符。
    3)δ是一个从S×Σ到S的子集的映射,即δ:S×Σ*→ 2 S 2^S 2S即从状态S输入Σ,所能到达的所有状态
    4) S 0 S_0 S0⊆S, S 0 S_0 S0是一个非空初态集。
    5)F ⊆S,F是一个终态集,可以为空。
  2. NFA的状态转换图
    若设NFA M含有n个状态和m个输入符号,则这个图含有n个状态结点,每个结点可射出若干箭弧与其它的状态结点相连接。对于w∈{ε}∪Σ,若δ(q0,a)={q1,q2,…,qk}(k≥0),则从q0出发,分别到q1,q2,…,qk的k条弧,弧上均标记为a。整张图含有唯一的初态结点和若干终态结点。
  3. NFA识别字符串
    1)对Σ上的任何符号串,若存在一条从某一初态结点到某一终态结点的通路,且该通路上所有弧的标记符号依次连接成的字符串等于w,则称w可被NFA M所识别。若M的某些结点同时又是终态结点,则空字符串ε被M所识别。
    2)NFA与语言的关系:Σ
    中所有可被NFA M所识别的符号串的集合记为L(M)。
  4. DFA和NFA的关系
    1)DFA是NFA的特例(确定),NFA是DFA概念的推广。
    2)NFA能识别的语言都能被一个DFA识别。
    3)DFA相对NFA的识别程序更容易实现。
    4)DFA更快复杂且精确,NFA更小简易,一个时间一个空间
    5)DFA:一个状态关于给定的输入符号只有一个转移
    NFA:一个状态关于给定的输入符号可以由任意多个转移

下图NFA与DFA等价,都是接受以abb结尾的串,NFA更加直观,DFA更容易实现
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  1. 从正则表达式到NFA
    在这里插入图片描述

3.3.2 不确定有限自动机的化简

  1. NFA的确定化:对任给的NFA M。都能相应地构造一个DFA M‘,使得L(M’)=L(M)。

  2. NFA的化简思路:DFA的每一个状态代表NFA状态集合的某个子集,构造的DFA使用它的状态去记录NFA读入输入符号之后可能到达的所有状态的集合。
    在这里插入图片描述
    在这里插入图片描述

  3. 闭包:若q为一初始状态s0,让a为ε,则δ(s0,a)={q1,q2,…,qk}为所有等价的状态结点构成的集合,这个集合被称为s0的ε闭包。记为ε-Closure(s0)。
    在这里插入图片描述

  4. 推广:集合I的ε-Closure(I)
    设I是NFA M的状态集的子集,定义I的ε闭包ε-Closure(I):
    1)若q∈I,则q∈ε-Closure(I)。
    2)若q∈I,则从q出发经过任意条ε弧而能到达的任何状态q’,有q’∈ ε-Closure(I)。
    在这里插入图片描述
    eg:将下图NFA M确定化。
    在这里插入图片描述

    生成DFA M的初态ε-Closure({0})={0,2,3}。重新命名生成的各个状态:{0,2,3}为0,{1}为1,{2,3}为2,{3}为3。由于{0,2,3}、{2,3}和{3}中均包含M中的终态3,因此0、2、3为M’的终态。
    在这里插入图片描述

3.3.3 确定有限自动机的化简

  1. 化简的目的:去除多余或等价的状态,降低存储代价,提高句子识别的效率。
  2. 有限自动机的多余状态:从初态出发,任何可识别的输入串也不能到达的状态。
  3. 状态等价:设DFA M=(S,Σ,δ,s0,F),对s,t∈S,若对任何α∈Σ*,均有δ(s,α)∈F当且仅当δ(t,α)∈F,则称状态s和t是等价的。若状态s和t是不等价的,则称状态s和t是可区别的。
  4. DFA M的化简
    1)定义:对一个DFA M,若能找到一个状态比M少的DFA M’,使得L(M)=L(M’),且M’满足两个条件:i)M’中没有多余的状态。ii)M’的状态集中,没有两个状态是互相等价的。则称DFA M‘是一个最小化的DFA。也称DFA M的化简。
    2)最小化的方法:把DFA M的状态Q划分成一些不相交的子集,使每个子集中任何两个状态是等价的,而任何两个属于不同子集的状态是可区别的。然后在每个子集中任取一个状态作为代表删除子集中的其余状态并把射向其余状态的箭弧都改为射向代表的状态
    3)最小化的具体步骤:
    i)将DFA M的状态集S划分为两个子集;终态集F和非终态集F ̃,形成初始划分Π。
    ii)对Π建立新的划分Πnew。对Π中的每个状态子集G进行如下变换:
    a)把G划分成新的子集,使G的两个状态s和t属于同一个子集,当且仅当对任何输入符号a,状态s和t转换到的状态都属于Π的同一子集。
    b)用G划分出的所有新子集替换G,形成新的划分Πnew。
    iii)若Πnew和Π相等,则执行第iv)步,否则,令Π=Πnew,重复第ii)步。
    iv)划分结束后,对划分中的每个状态子集,选出一个状态作为代表,删去其它一切等价的状态,并把射向其它状态的箭弧改为射向这个代表的状态。

3.3.4 识别单词的DFA

  1. 识别标识符的DFA

在这里插入图片描述

  1. 无符号数
    在这里插入图片描述

在这里插入图片描述

  1. 无符号整数
    在这里插入图片描述
  2. 注释
    在这里插入图片描述
  3. 识别token
    在这里插入图片描述

3.3.6 词法分析阶段的错误处理

  1. 词法分析阶段可检测错误的类型
  • 单词拼写错误 例:int i = 0x3G; float j =1.05e;
  • 非法字符 例:~ @
  1. 词法错误检测
    如果当前状态与当前输入符号在转换表对应项中的信息为空,而当前状态又不是终止状态,则调用错误处理程序

  2. 错误处理
    查找已扫描字符串中最后一个对应于某终态的字符

  • 如果找到了,将该字符与其前面的字符识别成一个单词。
    然后将输入指针退回到该字符,扫描器重新回到初始状
    态,继续识别下一个单词
  • 如果没找到,则确定出错,采用错误恢复策略
  1. 错误恢复策略
    最简单的错误恢复策略:“恐慌模式 (panic mode)”恢复
    :从剩余的输入中不断删除字符,直到词法分析器能够在剩余输入的开头发现一个正确的字符为止

3.3.5 化简DFA

eg:化简DFA
在这里插入图片描述

根据终态和非终态划分为两个子集:Π1={A,B,F},Π2={C,D,E,G}。

  • 对Π1,输入b,状态A、B经过b可到达终态,而F经过b不能到达终态。因此Π1划分为两个子集Π11={A,B}和Π12={F}。
  • 对Π11,输入bb,A经过bb可到达终态,而B不能,所以A和B是可区别的两个状态。
    故Π1划分为{A}、{B}、{F}三个子集。
  • 对Π2,输入b,划分成两个子集Π21={C,E}和Π¬22={D,G}。
  • 对Π21,输入a,划分成两个子集{C}和{E}。
    故Π2划分成{C}、{E}、{D,G}。
  • 最终状态集合划分成:{A}、{B}、{F}、{C}、{E}、{D,G}。
    在这里插入图片描述

3.4 正规文法、正规式和自动机之间的关系

3.4.1 正规式与正规集

  1. 定义:设字母表Σ:
    1)ε和Ø都是Σ上的一个正规式,它们所表示的正规集为{ε}和Ø。
    2)任何a∈Σ,a是Σ上的一个正规式,它所表示的正规集为{a}。
    3)假设e1和e2是Σ上的正规式,它们所表示的正规集分别为L(e1)和L(e2),则
    i)e1|e2是Σ上的正规式,它所表示的正规集为L(e1|e2)= L(e1)∪L(e2)。
    ii)e1e2是Σ上的正规式,它所表示的正规集为L(e1e2)= L(e1)L(e2)。
    iii)(e1)是Σ上的正规式,它所表示的正规集为L((e1))= L(e1)*。

  2. 正规式的运算
    1)种类:或”|”、连接”.”、闭包”*”。
    2)优先级:闭包>连接>或
    3)说明:仅由有限次使用这三种运算而得到的表达式才是Σ上的正规式。仅由这些正规式表示的单词集才是Σ上的正规式。

  3. 正规式的等价:若两个正规式U和V描述的正规集相同,则称正规式U和V等价。

  4. 正规式的性质:令U、V、W均为正规式:
    1)U|V=V|U
    2)U|(V|W)=(U|V)|W
    3)U(VW)=(UV)W
    4)U(V|W)=UV|UW
    5)(V|W)U=VU|WU
    6)εU=Uε=U

    eg:令Σ={a,b},则有:
    1)正规式a|b表示的正规集为{a,b}。
    2)正规式(a|b)(a|b)表示的正规集为{aa,ab,ba,bb}。
    3)正规式a*表示的正规集为{ε,a,aa,aaa,…}。
    4)正规式(a|b)表示的正规集为{ε,a,b,aa,ab,ba,bb,aaa,…}。
    5)正规式a|a
    b表示的正规集为包含字符串a和包含0个或多个a后跟随一个b的所有的符号串。

3.4.2 正规式与正规文法的关系

  1. 正规式转换为正规文法
    字母表Σ上的正规式U到正规文法G[Z]=(VN,VT,P,Z)的转换方法为:
    1)令VT=Σ,将Z→U加入到P中。
    2)对P中的每条产生式规则V→U,若U=ε或U=a(a∈Σ),则本次转换结束,否则按照如下规则反复执行,直到所有产生式规则最多含有一个终结符号为止:
    i)若U=e1|e2,则将V→U修改为V→A|B,A→e1,B→e2。
    ii)若U=e1e2,则将V→U修改为V→e1B,B→e2。
    iii)若U=(e1)*e2,则将V→U修改为V→e1V,V→e2。
  2. 正规文法转换为正规式
    1)将正规文法中的每个非终结符表示成它的一个正规式方程,获得一个联立方程组。
    2)若x=αx|β(或x=αx+β),则解为x=αβ。
    3)若x=xα|β(或x=xα+β),则解为x=βα

3.4.3 正规文法与有限自动机之间的转换

  1. 右线性文法转换为有限自动机
    设G[Z]=(VN,VT,P,Z)是一个右线性文法,其产生式规则具有形式A→aB|a|ε,由G构成相应的有限自动机M=(S,Σ,δ,s0,F)的步骤为:
    1)令s0={Z},将每个非终结符看作M中的一个状态,并增加一个终态Y且Y∉VN,令F={Y},即可得S=VN∪F。令Σ=VT。
    2)对G中每一形如A→ε的产生式规则,令δ(A,ε)=Y。
    3)对G中每一形如A→a的产生式规则,令δ(A,a)=Y。
    4)对G中每一形如A→aB的产生式规则,令δ(A,a)=B。
    构造的M多数情况下为NFA。
  2. 左线性文法转换为有限自动机
    设G[Z]=(VN,VT,P,Z)是一个左线性文法,其产生式规则具有形式A→Ba|a|ε,由G构成相应的有限自动机M=(S,Σ,δ,s0,F)的步骤为:
    1)令F={Z},将每个非终结符看作M中的一个状态,并增加一个初态X且X∉VN,令s0={X},即可得S=VN∪{X}。令Σ=VT。
    2)对G中每一形如A→ε的产生式规则,令δ(X,ε)=A。
    3)对G中每一形如A→a的产生式规则,令δ(X,a)=A。
    4)对G中每一形如A→Ba的产生式规则,令δ(B,a)=A。
    构造的M多数情况下为NFA。
  3. 有限自动机转换为正规文法
    对给定的有限自动机M=(S,Σ,δ,s0,F),可构造相应的正规文法G[Z]=(VN,VT,P,Z),使得L(G)=L(M),构造方法的主要步骤如下:
    1)令VT=Σ,VN=S,Z=s0.
    2)若Z是一个终态,则将产生式规则Z→ε加到P中。
    3)对δ(A,a)=B,若B∉F,则将产生式规则A→aB加到P中。否则,将产生式规则A→aB|A→a或A→aB,B→ε加到P中。特别的,若δ(A,a)=A,则将A→aA|ε加到P中。

3.4.4正规式与有限自动机之间的转换

  1. 由正规式构造有限自动机
    设r是字母表Σ上的一个正规式,构造可识别语言L®的NFA M=(S,Σ,δ,s0,F)的方法如下:
    1)引入初始结点s0和终态结点Z,把r表示称广义转化图:
    在这里插入图片描述

    2)若r=ε,或r=Ø,或r=a∈Σ,则构造相应的三个有限自动机:
    在这里插入图片描述

否则,按照转换规则3)执行。
3)针对r中的运算,按下图转换规则对r进行分裂并加进新结点(名字不同于已有的结点),直到每条边上的标记为单个符号或ε为止。
在这里插入图片描述

4)令F={Z},S为所有新增的结点。、初始结点s0、终态结点Z组成的集合。
2. 有限自动机构造正规式
设有一个NFA M=(S,Σ,δ,s0,F),构造可识别语言L®的正规式r的方法如下:
在这里插入图片描述

第四章 自顶向下的语法分析

4.1 语法分析器的功能

1.功能:以词法分析器生成的单词符号序列作为输入,在分析过程中验证这个单词符号序列是否是该程序设计语言的文法的一个句子
2.语法分析方法的种类:自顶向下和自底向上。
3.自顶向下的语法分析
1)定义:从顶部(树根)建立语法分析树,构造一个最左推导,面对当前输入的单词符号和当前被替换的非终结符,选择这个非终结符的某个产生式规则进行替换(替换哪个非终结符以及用该非终结符的哪个产生式进行替换)。
2)分类:递归下降的预测分析法(递归下降预测法)、非递归的预测分析法(非递归预测法)(LL(1)分析法)
3)说明:若文法是二义的,则递归下降法和非递归预测法通常均可回溯

4.1.1 最左推导

在最左推导中,总是选择每个句型的最左非终结符进行替换
在这里插入图片描述

4.1.2 最右推导

在最右推导中,总是选择每个句型的最右非终结符进行替换
在这里插入图片描述
自底向上采用最左规约(向上),最右推导(向下)
自顶向下采用最左推导,最右规约
最左推导和最右推导具有唯一性

4.2 不确定的自顶向下的分析方法

  1. 基本思想:对给定的单词符号串w,从文法的开始符号出发,试图构造一个最左推导,或自顶向下的为w建立一棵语法分析树。若成功的为w构造一个相应的推到序列或一棵语法分析树,则w为相应文法的合法句子,否则w不是文法句子。
  2. 本质:穷举试探,反复使用不同规则,寻求匹配输入串的过程
  3. 具体过程:在每一步推导中,面对替换的非终结符A和从左到右读输入串读到的单词符号a,若A的产生式规则(除了A→ε)A→α1|α2|…αn中,只有αi(1≤i≤n)能推导出的第一个终结符号是a,则可选择A→αi构造最左推导。若A的产生式规则(除了A→ε)中,推导的首个符号集合不含a,则选择A→ε进行推导。其中,a称为向前看符号。
  4. 特点:效率低,回溯代价高,实际过程通常不用

4.3 预测分析(确定的自顶向下的分析方法)

  • 预测分析不需要回溯,是递归下降分析技术的一个特例

4.4 LL(1)分析方法

4.4.0 文法转换

问题:

同一非终结符的多个候选是存在共同前缀,导致回溯现象在这里插入图片描述

左递归文法会使递归下降分析器陷入无限循环

4.4.1 回溯的判别条件与LL(1)文法

  1. First集:设G[Z]=(VN,VT,P,Z),α∈(VN∪VT),符号串α的首符号集合的定义为:
    First(α)={a|α ⇒
    a…且a∈VT}
    若α ⇒* ε,则规定ε∈First(α)。
  2. Follow集:设G[Z]=(VN,VT,P,Z),A∈VN,非终结符号A的后继符号集合的定义为:
    Follow(A)={a|Z ⇒* …Aa…且a∈VT}
    若Z ⇒* …A,则规定#∈First(A)。#为结束符。
  3. 回溯的判断:对一个上下文无关文法G[Z]=(VN,VT,P,Z),对某个产生式规则A→α1|α2|…αn,若存在a∈VT,使得a∈First(αi)∩First(αj)(1≤i,j≤n且i≠j)或a∈First(αi)∩Follow(A)(1≤i≤n,A ⇒* ε)或αi ⇒* ε且αj ⇒* ε(1≤i,j≤n且i≠j),则对应于文法G的自顶向下分析需要回溯。
  4. LL(1)文法定义
    1)文法不含左递归。
    2)对某个非终结符A,若其对应的产生式规则为A→α1|α2|…αn,则First(αi)∩First(αj)=Ø(1≤i,j≤n且i≠j)。
    3)对文法中的每个非终结符A,若A ⇒* ε,则First(αi)∩Follow(A)=Ø(1≤i≤n)。

4.4.2 左递归文法的改造(重点:消除左递归,算法)

  1. 左递归缺点:容易产生死循环

  2. 消除直接左递归
    若某个文法中非终结符A的产生式规则是直接左递归规则:A→Aα|β,其中α,β∈(VN∪VT)*。若β不以A打头,则将A的产生式规则改写为:A→βA’,A’→αA’|ε。A’是新增加的非中介符号。
    在这里插入图片描述

    推广:若A的全部产生式规则为:A→Aα1| Aα2|…|Aαm|β1|β2|…|βn,其中βi(1≤i≤n)不以A开头,且αi(1≤i≤m)不等于ε,则A的产生式规则改写为:A→β1A’|β2A’|…|βnA’, A’→α1A’|α2A’|…αmA’|ε。

在这里插入图片描述

在这里插入图片描述

eg:设有文法G[Z]:
E→E+T|E-T|T
T→TF|T/F|F
F→(E)|i
消除非终结符E,T的直接左递归后,文法G[Z’]改写为:
E→TE’
E’→+TE’|-TE’|ε
T→FT’
T’→
FT’|/FT’|ε
F→(E)|i

  1. 消除间接左递归
    1)对文法G的非终结符号按任一种顺序排列成A1,A2,…,An。
    2)依次对各非终结符号对应的产生式进行左递归的消除:
    for(j=1;j<=n;j++)
    for(k=1;k<=j-1;k++){
    i)把每个形如Aj→Akα的规则改写为Aj→δ1α|δ2α|…|δmα。其中Ak→δ1|δ2|…|δm是关于当前Ak的产生式规则;
    ii)消除关于产生式规则Aj的直接左递归;
    }
    3)进一步化简消除左递归之后的新文法,删去多余的产生式规则。
    eg:设有文法G[S]:
    S→Sa|Tbc|Td
    T→Se|gh
    将非终结符号排成顺序为S,T
    消除产生式S左递归:
    S→(Tbc|Td)S1
    S1→aS1|ε
    对T→Se|gh,将S代入展开得:
    T→T(bc|d)S1e|gh
    消除产生式T左递归:
    T→ghT1
    T1→(bc|d)S1eT1|ε

在这里插入图片描述

  1. 回溯的消除
    1)提取左因子
    若有A→αβ1|αβ2|…|αβ1|γ,其中γ不是以α开头的候选式,则A的产生式规则可替换为A→αA‘|γ,A’→β1|β2|…|βn。A’是一个新的非终结符号。
    在这里插入图片描述
    在这里插入图片描述

    2)消除左递归

4.5 构造递归下降分析程序

  1. 定义:由一组递归函数或过程组成,每个函数或过程对应文法的一个非终结符的程序,称为递归下降分析器。
  2. 基本思路:
    1)当遇到终结符a时,编写语句:if(当前读来的输入符号==’a’) 读入下一个输入符号;
    2)当遇到非终结符A时,则编写语句调用A()。
    3)当遇到A→ε产生式规则时,则编写语句:if(当前读来的输入符号∉Follow(A)) error();
    4)当某个非终结符有多个候选产生式规则时,分两种情况处理:
    i)if(当前读来的输入符号∈First(αi)) 按照规则A→αi进行推导;
    ii)if(当前读来的输入符号∈Follow(A)且αi ⇒* ε) 按照规则A→αi进行推导;

4.6 非递归的预测分析法

4.6.1 预测分析程序的工作原理

  1. 预测分析器的组成:一张预测分析表M(LL(1)分析表)、一个栈、一个预测分析控制程序、一个输入缓冲区、一个输出流。

在这里插入图片描述

1)输入缓冲区:存放待分析的输入符号串,其后以符号#作为结束符
2)存放替换当前非终结符的某个产生式规则的右部符号串,栈底的符号为#。
3)预测分析表:一张二维表,行为非终结符号,列为终结符号,其元素形式为M[S,a],表中元素M[S,a]存放一条产生式规则或相应的出错处理程序的入口地址(分析出错时)。其中,M[S,a]表示当前栈顶S面对当前向前看符号a应采取的动作。

  1. 预测分析器的工作原理:#和文法开始符号进栈,从输入缓冲区读进输入符号a,弹出栈顶元素给X:
    1)若X=a=’#’,则分析器工作结束,分析成功。
    2)若X=a≠‘#’,则分析器把X从栈顶弹出,让输入指针指向下一个输入符号。
    3)若X是一个非终结符号,则查阅预测分析表M。若在M[X,a]中存放着关于X的一个产生式规则,则先把X弹出,再把产生式规则右部符号串按逆序一一压入栈中。若M[X,a]={X→ε},则预测分析器把在栈顶的X弹出。若M[X,a]=error,则调用出错处理程序。

4.6.2 构造预测分析表

1.构造方法
1)计算文法G的每个非终结符的First集和Follow集
对每一个文法符号X∈(VT∪VN)如下计算First(X)里可以有ε
i)若X∈VT,则First(X)={X}。(x是终结符,first集里只有他本身)
ii)若X∈VN,且有产生式规则X→a…,a∈VT,则a∈First(X)。
iii)若X∈VN,且有产生式规则X→ε,则ε∈First(X)。
iv)若有产生式规则X→X1X2…Xn,对于任意的j(1≤j≤n),当X1X2…Xj-1都是非终结符,且X1X2…Xj-1 ⇒ ε(即X1X2…Xj-1→ ε)时,则将First(Xj)中的非ε元素加到First(X)中。特别地,若X1X2…Xn ⇒
ε,则ε∈First(X)**。
v)反复执行i)到iv),直到First集不再变化为止。

在这里插入图片描述
在这里插入图片描述

对文法中的每一个A属于VN,如下计算Follow(A)里无εA→αB则把Follow(A)加到Follow(B)中
i)若A是文法的开始符号,则将‘#’加入到Follow(A)中。
ii)若A→αBβ是一条产生式规则,则把First(β)中的非ε元素加到Follow(B)中。
iii)若A→αB或A→αBβ是一条产生式规则,且β ⇒* ε,则把Follow(A)加到Follow(B)中
iv)反复执行i)到iii),直到每个非终结符的Follow集不再发生变化为止。
2)对文法中的每个产生式规则A→α,若a∈First(α),则令M[A,a]=A→α。
3)若ε∈First(α),对任何b∈Follow(A),则令M[A,b]=A→α。
4)把预测分析表中无定义的空白元素标上出错标志error
eg:设有文法G[E]:
E→TE1
E1→ATE1|ε
T→FT1
T1→MFT1|ε
F→(E)|i
A→+|-
M→*|/
试构造该文法得预测分析表M。
文法G的每个非终结符的First集和Follow集

产生式规则First集Follow集
E→TE1First(E)={(,i}Follow(E)={#,)}
E1→ATE1IεFirst(E1)={+,-,ε}Follow(E1)={#,)}
T→FT1First(T)={(,i}Follow(T)={+,-,),#}
T1→MFT1 IεFirst(T1)={*,/,ε}Follow(T1)={+,-,),#}
F→(E)IiFirst(F)={(,i}Follow(F)={+,-,*,/,),#}
-First((E))={(},First(i)={i}-
A→+I-First(A)={+,-}Follow(A)={(,i}
-First(+)={+},First(-)={-}-
M→*I/First(M)={*,/}Follow(M)={(,i}
-First()={},First(/)={/}-

预测分析表

在这里插入图片描述

  1. 可选集
    在这里插入图片描述
  2. 串首终结符集
    在这里插入图片描述

第五章 自底向上的语法分析

在这里插入图片描述

5.1 引言

  1. 工作方式:移进-归约
    在这里插入图片描述
    在这里插入图片描述

2.2.3 短语、直接短语、句柄(第二章)

  • 直接短语一定是一个产生式的右部,但是产生式的右部不一定是当前句型的直接短语
  • 高人,民生,活水则都不是当前句型的直接短语,但是是其他句型的产生式右部
    在这里插入图片描述

在这里插入图片描述

设G[Z]是一个文法,假定αβδ是文法G的一个句型。
1)短语:若存在Z ⇒+ αAδ且A ⇒+ β,则称β是句型αβδ相对于非终结符A的短语。(即子树的边缘
2)直接短语:若存在Z ⇒+ αAδ且A⇒β,则称β是句型αβδ相对于产生式规则A→β的直接短语。(高度为2的子树的边缘
3)句柄:一个句型的最左直接短语称为该句型的句柄。

在这里插入图片描述

  1. 基本思想:将输入符号串中的符号从左向右逐个的移进栈,每当栈顶形成某一个可归约子串时,就把该可归约子串归约成某一个非终结符号。即先把该可归约子串从栈顶逐出,再把归约的非终结符号压进栈。

在这里插入图片描述
在这里插入图片描述

5.2 自底向上的语法分析面临的问题

  1. 如何寻找可归约子串?
  2. 可归约子串被归约到哪一个非终结符号?

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

LR分析法概述

在这里插入图片描述

LR分析法基本原理

在这里插入图片描述

LR分析器(自动机)的总体结构

在这里插入图片描述

LR分析表的结构

在这里插入图片描述

LR分析器的工作过程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

LR分析算法

在这里插入图片描述
在这里插入图片描述

LR(0)分析

LR(0)项目

在这里插入图片描述
K个符号对应K+1个项目

增广文法

(文法开始符号仅出现在一个产生式左部,一个接受状态)
在这里插入图片描述

文法中的项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
. 后是非终结符则存在等价项目
在这里插入图片描述


LR(0)分析表构造算法(略)

在这里插入图片描述

LR(0)分析过程中的冲突(移进规约冲突)

在这里插入图片描述
在这里插入图片描述
不知道使用移入动作还是规约动作

移进规约冲突和规约规约冲突

在这里插入图片描述


SLR分析

在这里插入图片描述
新增的LOLLOW集,说明就算规约了,E的FOLLW集也没有,故不能规约*
借助FOLLOW集判定什么时候不能进行规约

在这里插入图片描述

例子

在这里插入图片描述
根据状态2冲突的B和T,对比他们的FOLLOW集,写出对应的ACTION

SLR分析中的冲突

移入规约冲突
所以需要引入功能更加强大的分析法
在这里插入图片描述


LR(1)分析

LR(1)分析法的提出

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

等价LR(1)项目

在这里插入图片描述

例子

在这里插入图片描述
对比多了四个状态

在这里插入图片描述

项目集同心的概念

在这里插入图片描述
8 10
4 11
5 12
7 13都是同心的项目集

例子

在这里插入图片描述


LALR分析法

基本思想

合并同心项目集

在这里插入图片描述

例子

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

合并同心项目集产生规约规约冲突

(因为展望符只在规约的时候冲突,移入不起作用,所以不会产生移入规约冲突)
在这里插入图片描述

推迟错误的发现

在这里插入图片描述

LALR(1)的特点

在这里插入图片描述


二义性文法的LR分析

在这里插入图片描述
在这里插入图片描述

例子1

在这里插入图片描述
在这里插入图片描述

例子2

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二义性文法的使用

在这里插入图片描述

LR分析中的错误处理

在这里插入图片描述

恐慌层次错误恢复

在这里插入图片描述

短语层次错误恢复

在这里插入图片描述

例子(不会推迟错误的发现)

在这里插入图片描述
核心是假设获得了相应的输入或者删除相应的输入,并且转移到相应状态,并且输出相应信息
在这里插入图片描述

参考

编译原理总结,看这一篇就够了!

LR分析技术

LR分析技术概述

  1. LR(k)分析技术
    1)L代表从左向右分析,R代表最右推导,k代表向前查看k个字符。
    2)LR分析法实际上是最右推导的逆过程——最右归约。
    3)LR(k)分析技术利用已经移进栈中的和归约后进入栈中的一切文法符号,并向前查看最多k个符号,从而确定句柄是否已经在栈顶形成,一旦句柄出现在栈顶,立即进行归约。
  2. LR(k)技术的分类:LR(0)分析法、SLR(1)分析法、LR(1)分析法、LALR(1)分析法。
  3. LR分析器组成:一个输入串、一个分析栈、一张LR分析表、LR分析器总控程序。
    在这里插入图片描述

LR(0)分析法

  1. 活前缀:将每一条规则编上序号①、②、③…,附加在规则的右边,并在推导的过程中将序号带入句型中。句型中形如βω℗的前部称为活前缀。
  2. LR(0)项目:文法G中每一条产生式规则的右部添加一个圆点,称为LR(0)项目。

eg:A→cAd可以产生四个LR(0)项目:A→·cAd,A→c·Ad,A→cA·d,A→cAd·。
1)若是空规则A→ε,则只对应一个LR(0)项目A→·。
2)含义 :
i)A→·cAd表示期望下一个符号是终结符c。
ii)A→c·Ad表示目前输入串中已经有部分符号已正确分析成功,期望剩下的输入串能与圆点右部的部分分析成功。
iii)A→cAd·表示输入串已全部正确解析成功,可以归约到非终结符A。

  1. 初始项目:S→·α,S是文法的开始符号,称该项目为初始项目。
  2. 移进项目:A→α·aβ,其中a∈VT,称该项目为移进项目。
  3. 待约项目:A→α·Bβ,其中B∈VN,称该项目为待约项目。
  4. 归约项目和接收项目:A→α·,其中A∈VN,若A不是文法G的开始符号,则称为归约项目,否则称为接收项目。
  5. 后继项目:设有两个项目A→α·aβ和A→αa·β,两者同属于一条规则,只是圆点位置相差一个终结符,则称A→αa·β是A→α·aβ的后继项目。
  6. 文法G的拓广
    1)原因:为了保证文法G只有一个接收项目,一旦达到接收项目就完成整个语法分析。当一个文法G的开始符号不是只出现在一条规则的左边,则这个文法G需要拓广。
    2)定义:设文法G的开始符号是S,现引入一个新的开始符号S‘,并加入一条新规则:S’→S。产生新文法G’[S’],称G’是文法G的拓广。
  7. LR(0)项目集:由LR(0)项目构成的集合。
  8. LR(0)项目集闭包
    已知项目集I,求I的闭包CLOSURE(I)的算法:
    1)项目集I中所有的项目加入到CLOSURE(I)集合中。
    2)若待约项目A→α·Bβ属于CLOSURE(I),则对于每一个关于B的产生式规则B→γ,将项目B→·γ加入到CLOSURE(I)中。
    3)反复执行2),直到CLOSURE(I)中不再有新的项目加入为止。
  9. LR(0)的GO函数:项目集I经过符号X的状态转换函数GO(I,X)=CLOSURE(I的后继项目集)。
  10. LR(0)项目集规范族:把识别文法G的所有活前缀的LR(0)项目集闭包组成的DFA称为项目集的规范族。
    eg:设有文法G[S]:
    S→cAd①
    A→a②
    A→Aa③
    求该文法G的LR(0)项目集规范族。

在这里插入图片描述

  1. LR(0)分析表组成:ACTION子表和GOTO子表。
------ACTIONACTIONACTIONGOTOGOTO
状态a1#SA
0s212
1acc
nr3r3r3

其中,ai是终结符号,S和A是非终结符。
1)LR(0)分析表的第一列是状态列,登记DFA中的状态编号。
2)ACTION子表中的列全是终结符(包含#),填写动作,动作分为四种:
i)移进动作:用s表示。如状态0所在行与ACTION子表中的a1列交叉处填写的是s2,表示a1进栈,当前状态从状态0变成状态2。
ii)归约动作:用r表示。如状态n所在行与ACTION子表中的a1列交叉处填写的是r3,表示用第三条规则进行归约。
iii)接受动作:用acc表示。如状态1所在行与ACTION子表中的#列交叉处填写的是acc,表示成功接收,已正确识别出句子。
iv)报错:ACTION子表中的空白处,表示出错。
3)GOTO子表的列全是非终结符,表示状态转移。如状态0所在行与GOTO子表中第A列交叉处填写的是2,表示当前状态0下若识别出非终结符A,状态将变迁到状态2。

  1. LR(0)分析表的构造步骤:
    1)若移进项目A→α·aβ属于Ik且GO(Ik,a)=Ij,其中a是终结符,则令ACTION[k][a]=sj。表示将a移进栈,且状态变迁到j。
    2)若归约项目A→β·,并设A→β的规则编号为p,则将ACTION子表中状态k所在的行与每一个终结符(包括#)所在列的交叉处填写上rp。表示无论下一个字符是什么,只要当前状态是k,就立即使用第p条规则A→β进行归约。
    3)若接收项目S‘→S·属于Ik,则令ACTION[k][#]=acc。就是将ACTION子表中状态k所在的行与符号#所在列的交叉处填写acc,表示成功接收。
    4)若GO(Ik,A)=Ip,其中A是非终结符,则令GOTO[k][A]=p,表示状态k下若识别出非终结符A,状态将变为p。
    5)分析表中不能用以上规则填写的交叉处,全部填写报错标记。
  2. LR(0)文法:若一个文法G的LR(0)项目集规范族中所有的LR(0)项目集均不含有冲突项目,则该文法是LR(0)文法。
  3. LR(0)项目集中的冲突
    1)移进-归约冲突
    面临一个终结符,同时出现了移进和归约两种动作。
    2)归约-归约冲突
    一个项目集中出现两个归约动作
  4. LR分析器总控程序的工作步骤
    1)将(状态0,#)入栈.
    2)将下一个输入符号读入变量a中。
    3)由栈顶当前状态和变量a,查找ACTION子表:
    i)对sj型动作,二元组(状态j,a)入栈,且下一个输入符号读入变量a中;
    ii)对rj型动作,用第j条规则进行归约;
    若是rj型动作,用第j条规则进行归约时,设j条规则是A→β,且规则右部β的长度为n,则首先从栈中弹出n个符号,设此时栈顶的状态为s‘,然后由当前栈顶状态s‘及第j条规则A→β的左部符号A查GOTO子表,即GOTO[状态s’][A],得到新状态w,最后将二元组(状态w,A)入栈。
    iii)acc则成功,结束;
    iv)报错,调用出错处理子程序。
    4)跳到3)。

SLR(1)分析技术

  1. 含义:简化了的LR(1)分析技术
  2. SLR(1)的移进-归约方式:
    1)若下一个符号x是b,则使用A→α·bβ项目将b移进。
    2)若下一个符号x∈FOLLOW(B),则使用B→γ·项目进行归约。
    3)若下一个符号x∈FOLLOW©,则使用C→ξ·项目进行归约。
  3. 与LR(0)的区别:ACTION子表中r型动作填写规则不同。
    对于项目集Ik={B→γ·℗}:
    1)LR(0)分析表:状态k所在的行全部填写上rp。
    2)SLR(1)分析表:只有当终结符号x∈FOLLOW(B)时,才在状态所在的行与符号x所在的列的交叉处填写上rp,其余部分和LR(0)相同。
  4. SLR(1)型文法:若文法G的SLR(1)分析表中没有多重定义项,则该文法是SLR(1)文法

LR(1)分析技术

  1. SLR(1)的缺点:对每一个项目,仅依靠FOLLOW集,没有精确指明面临哪些符号时才能归约。
  2. LR(1)项目
    1)定义:形如[A→α·β,x]称为LR(1)项目。A→α·β是LR(0)项目,x是终结符。终结符x称为该LR(1)项目的搜索符。
    2)含义:表示当A→α·β到达归约项目A→αβ·时,只有面临的下一个符号是x时才能进行归约。
    3)若一个项目集中有LR(1)项目:[A→α·β,a],[A→α·β,b],[A→α·β,c],则可合并写成[A→α·β,a/b/c]。
    4)LR(1)的开始项目:[S’→·S,#]
  3. LR(1)项目对活前缀有效:若存在推导S ⇒* δAη ⇒ δαβη,其中ω=δα,x是η的第一个符号,或者η为ε时,x为#,则称LR(1)项目[A→α·β,x]对活前缀ω有效。
  4. LR(1)项目闭包集
    设有LR(1)项目集I,计算CLOSURE(I)的步骤:
    1)将I中的任何项目全加入到CLOSURE(I)中。
    2)若项目[A→α·Bβ,x]∈CLOSURE(I),则对任何规则B→ξ,将项目[B→·ξ,First(βx)]加入到CLOSURE(I)中。
    3)反复做2),直到CLOSURE(I)中不再加入新的项目为止。
  5. LR(1)的GO函数:状态集I与符号X的状态变迁函数GO(I,X)=CLOSURE(J)。其中J是I经过X的后继项目集,即J={[A→αX·β,a]|[A→α·Xβ,a]∈I}。
  6. LR(1)分析表的构造步骤:
    1)若移进项目[A→α·aβ,x]∈Ik且GO(Ik,a)=Ij,其中a是终结符,则令ACTION[k][a]=sj。表示将a移进栈,当前状态变迁到状态j。
    2)若归约项目[A→β·,a]∈Ik,并设A→β的规则编号为p,则将ACTION[k][a]rp。
    3)若接收项目[S‘→S·,#]∈Ik,则令ACTION[k][#]=accj。表示成功接收。
    4)若GO(Ik,A)=Ip,其中A是非终结符,则令GOTO[k][A]=p。表示状态k下若识别出非终结符A,则将状态变为p。
    5)分析表中不能用以上规则进行填写的交叉处,全部填写报错标记。
  7. LR(1)文法:若LR(1)分析表中没有多重定义项,则该文法是LR(1)的文法

LALR(1)分析技术

  1. 概述
    1)LALR(1)分析表的结构和大小与SLR(1)相同,比LR(1)的分析表小。
    2)LALR(1)的分析能力比SLR(1)强,比LR(1)稍弱。
  2. 基本思想
    LR(1)项目集规范族中的所有同心项状态集合并。合并时,对应项目的搜索符也合并。原先各自接收有向边,都改为由合并后的项目集接收。原先各自发出的有向边都改为由合并后的项目集发出。
    1)合并后的项目集可能出现归-约归冲突。
  3. LALR(1)分析表的构造步骤:
    1)构造文法G的LR(1)项目集规范族。设项目集族为{I0,I1,…,In}。
    2)合并所有同心项集。设新的项目集族为{ I0’,I1’,…,Ij’ }。
    3)若移进项目[A→α·aβ,x]∈Ik’且GO(Ik’,a)=Ij’,其中a是终结符,则令ACTION[k][a]=sj。表示将a移进栈,且状态变迁到状态j。
    4)若归约项目[A→β·,a]∈Ik’,并设A→β的规则编号是p,则令ACTION[k][a]=rp。
    5)若接收项目[S‘→S·,#]∈Ik’,则令ACTION[k][#]=acc,表示成功接收。
    6)构造合并后的GOTO表。
    设Ik’是由It1,It2,…,Itp合并得到的,由于It1,It2,…,Itp是同心项目集,所以GO(It1,X),GO(It2,X) ,…,GO(Itn,X)也是同心项目集且它们合并后的项目集为Im’。
    若GO(Ik’,X)=Im’,其中X是非终结符,则令GOTO[k][X]=m,表示状态k下若识别处非终结符X,状态将变为m。
    7)分析表中不能用以上规则填写的交叉处,全部填写上报错标记。
  4. LALR(1)文法:若LALR(1)分析表中没有多重定义项,则该文法是LALR(1)文法

第六章 语法制导翻译

什么是语法制导翻译

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

语法制导翻译的基本思想

归约(或推导)到某个产生式时,除了按照产生式进行相应的代换之外(语法分析),还要按照产生式所对应的语义规则执行相应的语义动作,如计算表达式、产生中间代码(语义分析)

在这里插入图片描述

SDD和SDT

在这里插入图片描述

SDD(语法制导定义)

在这里插入图片描述
在这里插入图片描述

SDT(语法制导翻译方案)

在这里插入图片描述

SDD与SDT的关系

在这里插入图片描述

SDD

在这里插入图片描述

综合属性

在这里插入图片描述

例子(重点:注释分析树)

在这里插入图片描述

继承属性

在这里插入图片描述

例子

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

补充例题

参考博客: 【编译原理】语法制导的语义计算——注释分析树
在这里插入图片描述

在这里插入图片描述


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述

在这里插入图片描述

属性文法(没有副作用的SDD)

在这里插入图片描述
红框中的就是副作用的例子

在这里插入图片描述

SDD的求值顺序

在这里插入图片描述

依赖图

在这里插入图片描述
在这里插入图片描述

其中,综合属性写在右边,继承属性写在左边

例子

在这里插入图片描述
在这里插入图片描述

属性值的计算顺序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


SL-SDD

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

S-属性定义与L-属性定义

S-属性定义

在这里插入图片描述
因为综合属性只依赖于其自身或者子节点,所以可以使用自底向上的顺序

L-属性定义

在这里插入图片描述

L-SDD正式定义

在这里插入图片描述
对于第一点,为什么Xi的继承属性为什么不能依赖于A的综合属性,因为如果是综合属性就会产生环路

父节点A的综合属性依赖于子节点的属性(i和s),如果子节点Xi的继承属性i依赖于父节点A的综合属性s,就会形成环路。故只能依赖于父节点的继承属性i

在这里插入图片描述
在这里插入图片描述

综合属性和继承属性的判别以及L-SDD的判别

在这里插入图片描述
对于L-SDD的判别只需要看继承属性(因为L属性定义对于综合属性没有限制,只限制继承属性)

只要继承属性不依赖于父节点的综合属性就行

在这里插入图片描述

语法制导翻译的应用(抽象语法树)

在这里插入图片描述
在这里插入图片描述

后缀表达式

在这里插入图片描述

语法制导翻译方案SDT

在这里插入图片描述
在这里插入图片描述

设计原则

在这里插入图片描述

将S-SDD转换成SDT

在这里插入图片描述

S-属性定义的SDT的实现

在这里插入图片描述
在这里插入图片描述

因为每个语义动作是放在产生是的最后,所以规约的时候才执行相应的语义动作

对应的栈操作

在这里插入图片描述

自底向上语法分析栈中实现桌面计算器

在这里插入图片描述
在这里插入图片描述
因为ETF三个产生式左部的值就等于产生式右部的值,不需要进行栈操作,如下:
在这里插入图片描述

在这里插入图片描述
I0遇到输入符号3(d)进入I5,将状态5和符号d入栈,d的属性值是词法分析器给的3,3入栈;
I5是归约状态, 将状态5和符号d出栈,将规约到的符号F入栈,回到I0状态,I0遇到F进入I3,将状态3入栈。

以此类推:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


小结

在这里插入图片描述

将L-SDD转换为SDT

在这里插入图片描述
在这里插入图片描述

例子

在这里插入图片描述
判断LL文法,需要判断相同左部的产生式的SELECT集是否都不相交

实现的分类:递归,非递归,LR分析

在这里插入图片描述

L-SDT在非递归的预测分析过程中进行翻译

《编译》——复习资料,可适用于课程学习资料、期末复习资料、自主学习资料等等,复习资料共218页,内容丰富,干货十足! 主要内容包括: 一、概述 1 1.1 课程介绍 1 1.2 编译过程 3 1.3 高级语言程序简介 11 二、程序语言概论 14 2.1 程序语言的定义 14 2.2 文法的形式化定义和分类 18 2.3 文法和语言 22 2.4 语法分析树 29 三、词法分析_1 33 3.1 词法分析概述 33 3.2 词法分析程序的设计 38 3.3 正规式与自动机 41 3.3.1 正规式与正规集 41 3.3.2 确定有限自动机(DFA) 44 3.3.3 非确定有限自动机(NFA) 49 3.4 单元测试 51 四、词汇分析_2 52 4.1正则式和有限自动机的等价 52 五、词法分析_3 59 5.1 DFA的化简 59 六、词法分析_4 62 6.1 词法分析器的自动生成 62 6.2 词法分析程序实现实例 64 七、语法分析—自上而下分析_1 71 7.1 词法分析简介 71 7.2 自顶向下分析简介 73 7.3 消除左递归和回溯 76 八、语法分析—自上而下分析_2 80 8.1 LL(1)分析法 80 8.2 FIRST集和FOLLOW集的构造 82 8.3 单元测试 85 九、语法分析—自上而下分析_3 86 9.1 LL(1)分析表的构造 86 9.2 递归子程序的原理 89 9.3 单元测试 95 十、语法分析—自下而上分析_1 96 10.1 自下而上分析方法的基本思想 96 10.2 分析树与规范规约 99 10.3 符号栈的使用 103 10.4 单元测试 105 十一、语法分析—自下而上分析_2 106 11.1 算符优先文法 106 11.2 优先表构造 109 11.3 算符优先分析算法 112 10.4 单元测试 115 十二、语法分析—自下而上分析_3 116 12.1 LR分析器 116 12.2 LR分析过程 119 12.3 单元测试 132 十三、语法分析—自下而上分析_4 133 13.1 构造识别前缀的DFA 133 13.2 LR(0)项目集规范族构造 140 13.3 由DFA构造LR(0)分析表 146 13.4 单元测试 150 十六、属性文法和语法翻译制导 151 16.1 L-属性文法和自顶向下翻译 151 16.2 自下而上计算继承属性 159 十七、语义分析和中间代码产生_1 166 17.1 语义分析的任务 166 17.2 中间代码的生成 168 17.3 算术表达式和赋值语句 175 17.4 单元测试 178 十八、语义分析和中间代码产生_2 179 18.1 布尔表达式的作用和文法描述 179 18.2 做控制用布尔表达式的翻译(回填) 181 18.3 控制流语句的翻译 186 18.4 控制流语句的翻译(回填) 189 十九、代码优化_1 194 19.1 什么是代码优化 194 19.2 基本块及流图 199 19.3 单元测试 202 二十、代码优化_2 203 20.1 基本块的DAG表示及其作用 203 二十一、重要知识点 213 1. 考试内容及分数分布 213 2. 名词解释 214 3. 简答题 215 4. 结语 216
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VengaZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值