02-词法分析
正则语言
定义:若存在一个 DFA/NFA 能够匹配所有这个语言的字符串,拒绝所有不属于这个语言的字符串,那么这个语言就是正则语言。
若 L1,L2 是正则语言,则以下也是正则语言
L1∪L2
L1∩L2
L1L2
L1∗
L1
L1R
原因:
多个终止状态的 NFA 可以合并为一个终止状态(增加 ϵ 转移)
L1∪L2:并联两个 NFA
L1∩L2:使用 De Morgan 定律,转换为 L1∪L2
L1L2:串联两个 NFA
L1∗:将 NFA 首尾相连,增加 ϵ 转移
L1:将 NFA 的终止状态改为非终止状态
L1R:将 NFA 的边反向
正则表达式
原始正则表达式
空集:L(∅)=∅
空串:L(ϵ)={ϵ}
字符:L(a)={a}
正则表达式进行以下运算后还是正则表达式
L(r1∣r2)=L(r1)∪L(r2)
L(r1r2)=L(r1)L(r2)
L(r1∗)=L(r1)∗
L((r1))=L(r1)
若两个正则表达式表示同一种语言,则它们是等价的。
正则表达式的运算定律
常见运算符
|:或*:0次,1次或多次+:1次或多次?:0次或1次
交换/结合律
r1∣r2=r2∣r1
(r1∣r2)∣r3=r1∣(r2∣r3)
(r1r2)r3=r1(r2r3)
零元/幺元
r∣∅=r
r∅=∅
r∣ϵ=r
rϵ=r
分配律
r1(r2∣r3)=r1r2∣r1r3
(r1∣r2)r3=r1r3∣r2r3
幂等律:r∣r=r
闭包:
(r∗)∗=r∗
∅∗=ϵ∗={ϵ} ( ∅拼接0次是空串,拼接多次是空集)
r+=r(r∗)=(r∗)r
r?=ϵ∣r
正则语言 & 正则表达式
任何正则表达式都能表示正则语言:将正则表达式转换为 NFA
原始正则表达式是 NFA 的一个个“部件”
正则表达式的运算是 NFA 的“组装”
任何正则语言都能用正则表达式表示:通过正则表达式表示 DFA
将 DFA 的状态转移变为正则表达式的等式
消元,化简,得到正则表达式
词法分析的基础
为词位(lexeme)建立正则表达式,构造 DFA
将源代码作为输入
将 DFA 作为状态机,识别出源代码中的词位
Lexical Analysis 词法分析
正则表达式 -> NFA -> DFA -> 最小化 DFA
当达到 DFA 的终止状态时,输出 Token
当有多个 DFA 同时匹配时
根据优先级选择 或
选择最长的 Token
关系运算符的例子
在知道是<或>之后,需要判断是否是<=或>=,若不是,则需要回退一个字符(DFA 图上标注*)
Pumping Lemma 泵引理
如果存在一个常数n,使得对于所有长度大于n的字符串w,w可以被分为三个部分x,y,z,满足以下条件,那么L是正则语言
∣xy∣≤n
∣y∣≤1
对于任意i≥0,xyiz∈L
证明思路:设状态数是n,长度大于n的字符串至少有n+1个状态,至少有一个状态被访问两次,产生循环。
用于证明一个语言不是正则语言
∀n,∃w∈L,∣w∣>n
选择x,y,z,使得
xyz=w
∣xy∣≤n
∣y∣≤1
但是∃i,xyiz∈/L
anbn是正则语言吗?
设n=3,w=a3b3,x=a3,y=b,z=b2
xy2z=a3b4∈/L
anbn不是正则语言
最后更新于