翻译程序的三种方式
编译程序的五个阶段
问题:源代码中括号不匹配的错误一般在编译的哪个阶段(采用五阶段划分模型)被检查出来,简述这一阶段的名称和主要任务
标准格式(
)
:非空有限集,每个元素都是终结符
:非空有限集,每个元素都是非终结符
:非终极符号,即 开始符号
:产生式集合(有限),每个产生式的形式是
,其中
,
如果 G 是一个文法,S 为开始符号,如果
,则称
为一个 句型。仅含 终结符的句型是一个句子。文法 G 所产生的句子的全体是一个语言,记为 L(G)
语法分析树是语言推导过程的图形化表示方法。这种表示方法反映了语言的实质以及语言的推导过程。
定义:对于 CFG G 的句型,分析树被定义为具有下述性质的一棵树:
是该节点从左到右的所有孩子的标记。则:
是一个产生式。若 A→ε,则标记为 A 的节点可以仅有一个标记为 ε 的孩子。
以 E => -E => -(E) => -(E+E) => -(id+E) => -(id+id) 为例
分析树与语言和文法的关系
短语:子树末端节点字符串相对于子树根,即 叶子
简单短语(直接短语):相当于简单子树
句柄:最左简单子树的末端节点组成字符串
二义性:一个文法中存在某个句子,有两个不同的最左(最右)推导,则称这个文法是二义的
类型 | 名称 | 限制条件 |
---|---|---|
0型 | 短语结构文法 | 没有约束(只要左边至少有一个非终结符) |
1型 | 上下文有关文法 | 所有产生式形如 α → β,其中 |
2型 | 上下文无关文法 | 所有产生式形如 A → β,其中 A 是单个非终结符 |
3型 | 正规文法 | 所有产生式为 A → a 或 A → aB(右线性),或 A → Ba(左线性) |
0型文法(短语文法,上下文无关文法),每个产生式的左边
且至少含有一个非终结符号
中的每个产生式规则的形式为:
,其中
且至少含有一个非终结符号,而
,则G[Z]为0型文法
1型文法(上下文敏感文法)
定义:若文法
中的每个产生式规则的形式为:
,其中
,
,
,则G[Z]为1型文法
例如
S → aAB
AB → BA
BA → a
其中 AB → BA 这类规则长度不变,但左部是多个符号,所以是 上下文有关文法 (1型)
2型文法(上下文无关文法)
定义:若文法
中的每个产生式规则的形式为:
,其中
,
,则G[Z]为2型文法
特点:语法结构上下文无关,一般用于识别程序设计语言的语法结构
例如
S → aSb | ε
这是一个 上下文无关文法 (2型),因为它每个产生式的左部都是一个单独的非终结符
3型语言(正规文法)
种类:右线性文法、左线性文法 正则文法 左(右)线性文法
右线性文法:若文法
中的每个产生式规则的形式为:
或
,其中
,则 G[Z] 为右线性文法。(非终结部分永远在右部)
左线性文法:若文法
中的每个产生式规则的形式为:
或
,其中
,则G[Z]为左线性文法。(非终结部分永远在左部)
特点:作为定义程序设计语言规则的文法
正规语言:3型文法定义的语言
例如
A → a
A → aB
B → b
这类产生式符合右线性正规文法,属于 3型文法
📌 总结步骤:
当我们判断一个文法属于哪一型时,我们要找它能归入的最严格类型 (也就是编号最大的那个类型)
🧠 乔姆斯基文法的层级关系(包含关系)
类型 | 名称 | 包含关系 |
---|---|---|
0型 | 短语结构文法 | 最广泛,包含所有其他类型 |
1型 | 上下文有关文法 | 包含 2型和 3型 |
2型 | 上下文无关文法 | 包含 3型 |
3型 | 正规文法 | 最严格,是最小的集合 |
例题: 已知文法 G(S) 的产生式集为: S->bA,A-> aA|a,请判断这个文法属于乔姆斯基几型文法
第一步:检查是否符合 2型文法(上下文无关文法,CFG)
2型文法的定义:
观察该文法:
S → bA
:左边是 S(一个非终结符)A → aA | a
:左边是 A(一个非终结符)✔️ 全部产生式的左边都是单个非终结符 ,所以这是一个上下文无关文法(CFG) ,即2型文法
第二步:是否属于更严格的 3型文法(正规文法,Regular Grammar)
3型文法要求:
看看当前文法:
S → bA
✔️ 符合右线性A → aA
✔️ 符合右线性A → a
✔️ 是终结符,也符合右线性✔️ 所有产生式都满足右线性正规文法的要求
➡️ 所以这个文法不仅是 2型文法,而且还是 3型文法(正规文法),因此最终结论:该文法属于乔姆斯基的第 3 型文法(正规文法)
First集(最左边可能出现的终结符):设G[Z]=(VN,VT,P,Z),α∈(VN∪VT),符号串α的首符号集合的定义为:
,则规定
Follow集:设G[Z]=(VN,VT,P,Z),A∈VN,非终结符号A的后继符号集合的定义为:
,则规定#∈First(A)。#为结束符
LL(1)文法定义(也是 LL(1) 文法的判断条件)
,则
含有A→Aa形式产生式的文法称为是直接左递归的 (immediate left recursive)
,那么这个文法就是直接左递归的
左递归缺点:容易产生死循环
消除直接左递归规则
。其中
不以A打头,
。
是新增加的非中介符号
消除间接左递归:
例
将S的定义代入A-产生式,得:
消除A-产生式的直接左递归,得:
题目:
解:
(1)从 S 开始,将含有非终结符不能推导出终结字符串消除,比如 C,因此删除
(2)最后结果为:
正归式转 NFA 规则如下:
比如当前正则表达式为
,求其等价的 DFA
NFA 确定化
要求确定化之前,需要判断是否有从该点出发的某个路径可以到达两个不同终点
题目如下:0 是终结 符号,求其 确定化,和 最小化的结果
graph LR;
0 --> |a|0(((0)))
0 ---> |a, b| 1((1));
1 --> |a| 0;
由于 0 的 a 路径有两条,因此其并不是确定化,确定化状态转换矩阵如下:
I | I a I_a Ia | I b I_b Ib |
---|---|---|
{0} | {0, 1} | {1} |
{0, 1} | {0, 1} | {1} |
{1} | {0} | Φ \Phi Φ |
Φ \Phi Φ | Φ \Phi Φ | Φ \Phi Φ |
{0}{0, 1}{1}{0, 1}{0, 1}{1}{1}{0}
先入 0 这个点到队列中,然后再把其通过 a, b 路径得到的值 依次入队列,然后按照 先进先出 的顺序取出,然后对 状态重新编号,如下:
I | I a I_a Ia | I b I_b Ib |
---|---|---|
0 | 1 | 2 |
1 | 1 | 2 |
2 | 0 | 3 |
3 | 3 | 3 |
012112203333
因此其 DFA 状态图为
graph LR;
0(((0))) ---> |a|1((1))
0 ---> |b|2((2))
1--->|a|1
1--->|b|2
2--->|b|3((3))
2--->|a|0
3--->|a, b|3
其最小化求解如下:
包含最初的终结节点 0 的都属于 终态组,其他的就属于非终态组,比如:上面 DFA 确定化中 终态组{0, 1},非终态组 {2,3}
由于 {0, 1} => {1}(a 路径下),{0,1} => {2}(b 路径下)
因此终态组无需再分
然后再来看非终态组
由于 {2, 3} => {0,3}(a 路径下),{2,3} => {3}(b 路径下),前者不是当前集合子集,所以需要划分为 {2} {3},故最小化的结果为 {0, 1},{2},{3}
然后再重新编号 ,最小化图为
graph LR;
0 ---> |a|0(((0)))
0--->|b|1((1))
1--->|a|0
1--->|b|2((2))
2--->|a, b|2
给定右线性文法 G:
画图得其 NFA 如下:
graph LR;
0((S)) ---> |0,1|0(((0)))
0 ---> |1|1((A))
0 ---> |0|2((B))
1 ---> |1|3((C))
1 ---> |1|4((F))
2 ---> |0|3
2 ---> |0|4
3 ---> |0,1|3
3 ---> |0, 1|4
根据图,可以写出对应的左线性文法:
文法 G 如下:
消除直接左递归结果如下:
如何求First集与Follow集(超详细) – 具体步骤在这
思路:
求 FIRST 集合:
FOLLOW 集合的构造规则
# ∈ FOLLOW(S)
,其中 #
表示输入结束符。其中:
则将 FIRST(β) 中除去 ε 的所有符号 加入到 FOLLOW(B) 中。
或
且 ε∈FIRST(β) 则将 FOLLOW(A) 中的所有符号加入到 FOLLOW(B) 中
非终结符 | FIRST | FOLLOW |
---|---|---|
E E E | (,i | ),# |
E ′ E' E′ | +,ε | ),# |
T T T | (,i | ),+,# |
T ′ T' T′ | *,ε | ),+,# |
F F F | (,i | *,),+,# |
(,i),#
+,ε),#
(,i),+,#
*,ε),+,#
(,i*,),+,#