3710 字
19 分钟
编译原理: 词法分析

更新于2024-04-21 22:34:13

Ch3: 词法分析#

0. 词法分析的模式和主要功能#

0.1: 词法分析的工作方式:#

词法分析程序主要有两种工作方式:

  1. 词法分析和语法分析完全分开,变为两个等地位的模块,词法分析的输出作为语法分析的输入,词法分析和语法分析一共至少扫描文本两遍。
  2. 词法分析作为语法分析的调用子模块,每当语法分析需要读入一个单词时,调用词法分析子模块从字符流种读入一个单词。词法分析和语法分析放在一起扫描文本一遍。一般采用的都是这个方式。

0.2: 词法分析程序的输出:#

词法分析程序每次从字符流中取出一个字符时,以单词符号的形式发送至语法分析程序。

单词符号是一个二元组**(单词种别,单词本身的值),其中单词的种别往往用整数编码来表示,单词本身的值是用来区分单凭单词种别无法区分的单词。比如const int i=1,j = 25112525都是常量,但是需要有单词本身的值来区分。特别的,一般标识符本身的值往往是单词符号表中的指针**。

0.3: 词法分析的主要功能:#

词法也是语法的一部分,但是仍旧将词法分析和语法分析分开的原因是:

  1. 使编译程序的结构更加清楚明了
  2. 改进编译程序的效率
  3. 增加编译程序的可移植、可维护性。

除了1. 识别单词,词法分析还具有:

  1. 滤去注释与空格
  2. 记录新读入的字符和行号
  3. 宏展开
  4. 词法分析的预处理…

0.4 用来描述词法规则的工具#

描述词法规则的工具主要有:

  1. 状态转换图
  2. 扩展巴科斯范式(EBNF)
  3. 正规文法(\star)
  4. 正规表达式(\star)
  5. 有限状态自动机(\star)

1. 正规文法#

3型文法G(VN,VT,P,S)G(V_N,V_T,P,S)(左线性/右线性)能够描述一个正规集。

2. 正规表达式#

2.1 正规式和正规集的定义:#

正规表达式所表示的正规式和正规集一般用递归定义:

(1)ε都是Σ上的正规式,对应的正规集为{ε},(2)如果aΣ,则a也是Σ上的正规式,它所表示的正规集是{a}(3)如果e1e2都是正规式,表示的正规集分别是L(e1)L(e2)     则(e1)[L(e1)],e1e2[L(e1)L(e2)],e1e2[L(e1)×L(e2)],e1[L(e1)]也都是正规式,[]中为对应的正规集。(4)只有有限次数应用上述规则得到的正规集才是Σ上的正规集。\begin{align} &(1)\varepsilon和\varnothing都是\Sigma上的正规式,对应的正规集为\{\varepsilon\},\varnothing \\ &(2)如果a \in \Sigma,则a也是\Sigma上的正规式, 它所表示的正规集是\{a\} \\ &(3)如果e_1和e_2都是正规式,表示的正规集分别是L(e_1)和L(e_2),\\& \ \ \ \ \ 则(e_1)[L(e_1)],e_1|e_2[L(e_1) \cup L(e_2)],e_1\cdot e_2[L(e_1)\times L(e_2)],e_1^*[L^*(e_1)]也都是正规式,[]中为对应的正规集。\\ &(4)只有有限次数应用上述规则得到的正规集才是\Sigma上的正规集。 \end{align}

定理2.1.12.1.1 运算符号的优先级为: >>^* > \cdot > | 。并且,,^*,\cdot,|都是左结合的。

左结合: 相同优先级的运算符的运算顺序: abc=(ab)ca\cdot b\cdot c=(a\cdot b)\cdot c

2.1.12.1.1 d(.ddε)(e(+ε)ddε)d^*(.dd^*|\varepsilon)(e(+|-|\varepsilon)dd^*|\varepsilon)表示一个无符号数。

配合ppt中例题使用

2.2 正规式的代数规律(运算符的性质):#

abc=(ab)c=a(bc)的结合率ab=ba的交换律aa=a的抽取律abc=(ab)c=a(bc)的结合律εa=aε=aε上的幺元(ab)c=ac  bc, c(ab)=ca  cb上的分配律\begin{align} &a | b | c = (a | b) | c = a | (b | c) &|的结合率\\ &a | b = b | a &|的交换律 \\ &a | a = a &|的抽取律 \\ &a \cdot b \cdot c = (a \cdot b) \cdot c = a \cdot (b \cdot c) &\cdot的结合律 \\ & \varepsilon \cdot a=a \cdot \varepsilon = a &\varepsilon是\cdot上的幺元 \\ &(a|b)\cdot c = a\cdot c \ | \ b \cdot c, \ c \cdot(a|b) = c\cdot a \ | \ c \cdot b &\cdot在|上的分配律 \end{align}

引申性质:

r=(rε)(ab)=(ab)(r)=r\begin{align} r^* &= (r | \varepsilon)^* \\ (a | b)^* &= (a^*b^*)^* \\ (r^*)^*&=r^* \end{align}

2.3 正规式和正规文法的等价性#

如果正规式ee所表达的字符串的正规集L[e]L[e]和正规文法G[S]G[S]所表达的正规语言L[G]L[G]相等,则说该正规式和该正规文法等价。

2.3.1 正规式和正规文法的相互转换#

规则正规式正规文法
规则1:顺序ababAaB,BbA \to aB, B \to b
规则2:选择$ab$
规则3:循环abab^*/aba^*b$A \to aB,B \to bB

注意: 注意正规文法的左/右线性要保持好!不能混用!

当正规式转换为正规文法时,可以使用代入规则。并且可以使用更加熟悉的”+ *“来代替”| \cdot两个运算,化简更快更熟悉(+*的运算性质和”|\cdot完全一致)

3. 有穷自动机#

定义:有穷自动机(有限自动机)(Finite Automata)是一种识别装置,用来自动识别正规集[正规文法构成的语言的集合/正规式所表示的集合]。分为确定的有穷自动机和不确定的有穷自动机。

3.1 确定的有穷自动机DFA(Deterministic Finite Automata)#

定义3.1.13.1.1 一个确定的有穷自动机M是一个5元组

M=(K,Σ,f,S,Z)M = (K,\Sigma,f,S,Z)

其中:

KK是一个有穷的状态集合。

Σ\Sigma是一个有穷的输入符号表。每个元素称为一个输入符号。

ff是状态转换函数,f:K×ΣKf: K\times \Sigma \to K定义了从一个状态接受一个合法符号后转换到的一个确定的状态。注意,确定有穷自动机不因为空串ε\varepsilon转换状态。

SS唯一的一个起始状态,并且SKS\in K

ZZ是一个终止状态集合,且ZKZ \subseteq K,注意Z=Z = \varnothing的情况。​

以上是定义表示法,还有矩阵表示法(状态转换矩阵)[易被计算机表示]和图表示法(状态图)[直观]。见书Page48即可。注意表示方法

  1. 如何表示初态节点
  2. 如何表示终态节点

定义3.1.23.1.2 定义符号串tt可以被自动机所接受: 如果在状态图上存在一条从初态节点到某一终态节点的道路,且该条道路上的所有弧连接成的符号串等于tt,则称符号串可以被自动机接受。注意:只有当起始节点恰好也是终止节点时,ε\varepsilon才可被接受

定义3.1.33.1.3 定义在自动机MM上的运算:

f(U,t)=f(U,t1tx)=f(f(U,t1),tx)f(U,ε)=Uf(U,t) = f(U,t_1t_x) = f(f(U,t_1),t_x) \\ f(U,\varepsilon) = U

其中UK,tΣ,t1Σ,t=t1txU\in K, t\in\Sigma^*,t_1\in\Sigma,t = t_1t_x

tt可被接受也等价于f(S,t)=u,uZf(S,t) = u,u \in Z

定义集合L(M)L(M):

L(M)={tt可以被自动机M接受}L(M) = \{t|t可以被自动机M接受\}

为自动机MM的语言。

定理3.1.13.1.1 Σ\Sigma上的一个串集合VΣV \subseteq \Sigma^*是正规的当且仅当存在一个确定的有穷自动机MM的语言L(M)=VL(M) = V

3.2 不确定的有穷自动机NFA(Nondeterministic Finite Automata)#

定义3.2.13.2.1 不确定的有穷自动机MM也是一个5元组:

M=(K,Σ,f,S,Z)M = (K,\Sigma,f,S,Z)

其中:

KK是一个有穷的状态集合。

Σ\Sigma是一个有穷的输入符号表。每个元素称为一个输入符号。

ff是一个状态转移函数,f:K×Σ2Kf: K \times \Sigma^* \to 2^{K},其中2K2^KKK的幂集,Σ\Sigma^*Σ\Sigma上的字符串集。首先是可以因为ε\varepsilon转换状态,接着是因为一个输入可以有nn个后继状态。

SS是一个初始状态集合SKS \subseteq KSS \neq \varnothing

ZZ是一个终止状态集合ZKZ\subseteq K。可为空!

当然NFANFA也可以用状态图和状态转移矩阵表示。接受字符串的定义也和DFADFA完全一致。不过ε\varepsilon可以被不确定的有穷自动机MM接受的条件是:

  1. 存在一个初始节点也是终止节点。
  2. 从初始节点出发存在一条ε\varepsilon的路径到终止节点。

定理3.2.23.2.2 对于任意一个不确定的有穷自动机MM',一定存在一个确定的有穷自动机MM,使得L(M)=L(M)L(M') = L(M). 也就是一定存在一个确定的有穷自动机MM使得MM'MM等价。

3.3 NFANFA转换为DFADFA: 子集法#

定义3.3.13.3.1 状态集合IIε\varepsilon闭包:

εclosure(I)={uv经过<任意>ε能够抵达u,其中vI}\varepsilon-closure(I) = \{u|v经过<任意>条\varepsilon能够抵达u,其中v\in I\}

定义3.3.23.3.2 状态集合IIaa弧转换:

move(I,a)={uv经过<一条>a弧可以抵达u,其中vI}move(I,a) = \{u|v经过<一条>a弧可以抵达u,其中v \in I \}

3.3.1 子集法转换#

用确定的有穷自动机MM的一个状态来对应不确定自动机NN的一组状态。

把不确定有穷自动机N=(K,Σ,f,K0,Kt)N = (K,\Sigma,f,K_0,K_t)转换为确定的有穷自动机M=(S,Σ,D,S0,St)M = (S,\Sigma,D,S_0,S_t)

1.输入字符集Σ不变。令队列C=2.M的初始状态S0=εclosure(K0),且将S0置入C3.执行子集构造算法 得到子集组S作为M的状态集合4.M的终止状态集合St={QQSQKt}即所有包含N中终止节点的状态集合Q都是M的终止节点\begin{align} &1. 输入字符集\Sigma不变。 令队列C = \varnothing\\ &2. 令M的初始状态S_0 = \varepsilon-closure(K_0),且将S_0置入C中\\ &3. 执行子集构造算法 \ 得到子集组S作为M的状态集合\\ &4. M的终止状态集合S_t = \{Q|Q\in S且Q\cap K_t \neq \varnothing\}即所有包含N中终止节点的状态集合Q都是M的终止节点 \end{align}

如果是手算,一般是构建一个表格。

横行是输入字符集,纵列是状态集合。

3.4 DFA的最小化#

定义3.4.13.4.1 当一个DFA既没有多余状态,也没有等价状态时,该DFADFA是化简了的,也是最小化了的。

最小化DFADFA的步骤有2步!!

  1. 消除多余状态
  2. 合并等价状态

3.4.1 消除多余状态#

定义3.4.23.4.2 有穷自动机的多余状态是

  1. 从开始状态出发无法到达的状态。
  2. 从该状态出发无法到达终止状态的状态。

对于这2种多余状态的处理办法是: 简单地去掉该节点和和该节点相关的边即可。

建议还是先bfsbfs找出多余的状态。

3.4.2 合并等价状态#

定义3.4.33.4.3 有穷自动机的状态uuvv是等价状态,当且仅当u,vu,v满足:

1.uv同时是终止状态(可接受状态)或者同时是非终止状态(不可接受状态)2.a(Σε),uv必须由a弧上转移到等价的状态上。\begin{align} &1. u和v同时是终止状态(可接受状态)或者同时是非终止状态(不可接受状态)。 \\ &2. \forall a \in (\Sigma \cup\varepsilon), u和v必须由a弧上转移到等价的状态上。 \end{align}

定义3.4.43.4.4 有穷自动机的状态uuvv如果不等价,则称状态uuvv是可区分的。

好用的结论:

  1. 一致性条件: 如果状态uu和状态vv所有后继都一样,则uuvv一定等价。
  2. 蔓延性条件: 如果状态uu和状态vv对于某一输入字符(非空串),一个有后继而另一个没有,则则uuvv一定可区分。

用来合并不含多余状态的DFA(也没有空弧)的等价状态的方法是分割法: 一个一个把不等价的状态从等价集合中分开。

执行步骤:

0.建议先画状态转移表格1.把状态集合分为两个大的集合:{uuZ}{uuZ}(终止集和非终止集)2.遍历所有状态数量2的集合IcSigma,move(I,c)3.如果I状态的某一个move(I,c)不同属一个等价集合   则反过来求I的一个划分π,把I划分为π,回到24.如果所有状态数量2的集合I的所有输入后继都同属一个集合,   则此为最后的最小状态集合。\begin{align} &0. 建议先画状态转移表格\\ &1. 把状态集合分为两个大的集合: \{u|u \in Z\}和\{u|u \notin Z\}(终止集和非终止集)\\ &2. 遍历所有状态数量\ge2的集合I,\forall c\in Sigma,求move(I,c)\\ &3. 如果I状态的某一个move(I,c)不同属一个等价集合\\ & \ \ \ 则反过来求I的一个划分\pi,把I划分为\pi,回到2\\ &4. 如果所有状态数量\ge2的集合I的所有输入后继都同属一个集合,\\& \ \ \ 则此为最后的最小状态集合。 \end{align}

3.5 正规式和有穷自动机的等价性#

定理3.5.13.5.1 对于任何一个不确定的有穷自动机(NFA)MM,一定存在一个相同Σ\Sigma上的正规式rr,使得L(r)=L(M)L(r) = L(M)

定理3.5.23.5.2 对于任何一个正规式rr,一定存在一个相同Σ\Sigma上的不确定的有穷自动机(NFA)MM,使得L(M)=L(r)L(M) = L(r)

3.5.1 不确定有穷自动机MM转换为等价的正规式rr#

3.5.1.1 添加新的节点xxyy#

在原不确定有穷自动机MM中添加两个新的节点xxyy其中xx向每一个起始节点添加一条ε\varepsilon每个终止节点向yy添加一条ε\varepsilon

3.5.1.2 将自动机的弧转换为正规式,直至只剩下节点xxyy#
  1. 顺序

  1. 选择

  1. 循环

最后节点xxyy上弧的正规式就是最后的答案。

3.5.2 正规式rr转换为等价的不确定有穷自动机MM#

这个过程有点像结构化编程。把正规式rr自顶向下分解。这个过程也叫做**“语法制导”**。

Attention: 弧上不能出现aba|b,而a,ba,b是可以接受的。。

3.5.2.0 基本转换#
  1. \varnothing表达式

  1. r=εr = \varepsilon

  1. r=a,aΣr = a, a \in \Sigma

3.5.2.1 顺序 r=r1r2r = r_1r_2#

将一个正规式的终止节点和另一个正规式的起始节点连接起来

3.5.2.2 选择 r=r1r2r = r_1 | r_2#

让起始节点xx分别空弧连接到两个正规式的起始节点,再从每一个正规式的终止节点连空弧到终止节点yy

3.5.2.3 循环 r=r1r = r_1^*#

r1r_1的终止节点连接一条空弧到r1r_1的初始节点。

从初始节点xx到终止节点yy非常重要!!(r1r_1^*),否则是r1+r_1^+

有时可以思考能否像下面的情况一样尽量简化一些:

少一些空弧总是好的!

3.6 正规文法和不确定有穷自动机的等价性#

定理3.6.13.6.1 从正规文法GG可以直接构造一个等价的不确定的有穷自动机MM,从不确定有穷自动机MM也可以直接构造出一个等价的正规文法GG

3.6.1 从正规文法GG中导出不确定有穷自动机MM#

一般只考虑形如AaB, a(Σ{ε})A \to aB, \ a\in(\Sigma \cup\{\varepsilon\})的正规式。

正规文法G(VN,VT,P,S)G(V_N,V_T,P,S)到不确定有穷自动机M(K,Σ,f,KS,KZ)M(K,\Sigma,f,K_S,K_Z)转换。

  1. K=VNK = V_N: 将非终结符集作为状态集合。
  2. Σ=VT\Sigma = V_T: 字符表即终结符集合
  3. KS={S}K_S = \{S\}: 起始状态集合仅包含开始符号SS
  4. 添加一个新的状态Z作为唯一的终止状态。
  5. 对每一条形如AaBA \to aB的产生式添加一条从状态AA到状态BBaa弧(f(A,a)=Bf(A,a) = B)。
  6. 对每一条形如AaA \to a的产生式添加一条从状态AA到终止状态ZZaa弧。

大功告成!

3.6.2 从不确定有穷自动机MM中导出正规文法GG#

M不能有空弧,且只能有一个起始状态,否则将不为正规文法。

确定的有穷自动机M(K,Σ,f,S,Z)M(K,\Sigma,f,S,Z)转换为正规文法G(VN,VT,P,S)G(V_N,V_T,P,S)

  1. VN=KV_N = K: 非终结符集合就是状态集合
  2. VT=ΣV_T = \Sigma: 终结符集合就是字符表
  3. S=SS = S :开始符就是起始状态
  4. 对于AA通过aa弧转换为状态BB的状态转换函数f(A,a)=Bf(A,a) = B,添加一条AaBA \to aB的产生式
  5. 对于终止状态ZZ,添加一条ZεZ \to \varepsilon的产生式

大功告成!

编译原理: 词法分析
http://blog.fragments.work/posts/principleofcompiling/ch3/
作者
Lixin WANG
发布于
2024-03-17
许可协议
CC BY-NC-SA 4.0