【第三章】词法分析

第三章.词法分析

词法分析器作用

将源程序的字符串流,组成词素,生成一个词法单元序列(词法单元包含词法单元名和属性值构成)。

对于词法分析器发现的标识符词素时,会将词素添加到符号表中。

词法分析器→语法分析器

常见的词法单元和词素

词法单元 描述 词素
if 字符i,f if
else 字符e,l,s,e else
comparison 大于小于 > <
id 字母开头的变量 po,D2
number 数字 3.14 2

词法单元的规约

正则表达式:用来描述词素的重要表示方法。

串相关

  • 前缀,后缀,子串,子序列(字符可以不连续)

正则表达式可以由娇小的正则表达式按照规则递归构建。

r={a,b,c,d...x,y,z} s={0,1,2,3...9}

  • (r)|(s) 等价于 L(r)交L(s) 共36个
  • (r)(s) 等价于 L(r)xL(s) 共26*10个
  • (r)* 所有r字母构成的集合,包括空串
  • s+表示一个或多个数位构成的串的集合

正则的扩展

  • 一个或多个实例。用单目运算符+
  • 零个或一个实力。用单目运算符? ,r?等价 r|空

词法单元识别

状态转换图:构造词法分析器的一个中间步骤,构造状态转换图。

  • 双圈表示接受状态,可以是返回词法单元的相关属性值
  • *星号表示回退上一个状态。

可以用while,switch实现状态转换图

有穷自动机(finite automata)

将出入程序变成一个词法分析器,自动机的本质是与状态转换图类似的图。

  • 有穷自动机是识别器,只能对每个可能的输入串回答Y/N
  • 不确定有穷自动机(Nondeterministic Finite Automata,NFA)对边上的标号没有任何限制。
  • 确定的有穷自动机(Deterministic Finite Automata,DFA)对于每个状态及自动机输入的字母表符号,有且只有一条离开状态。

不确定的有穷自动机(NFA)

对边上的标号没有任何限制,一个符号标记离开同一状态的多条边,空串也可以作为标号。

  • 可用转换表表示,行为状态,列为输入符号,记录各个可能的所有状态
状态 a b c
0 {0,1} {0}
1 {2}
2 {3}
3

确定的有穷自动机(DFA)

属于NFA的一个特例,说NFA是一个抽象表示的识别串的算法,DFA就是一个具体的识别串的算法。

  • 没有输入 空 之上的转换动作
  • 对于每个状态s每个输入符号a,有且只有一条标号为a的边离开s

从正则表达式到自动机

利用子集构造法将NFA转成DFA
基本思想让构造得到的DFA每个状态对应于NFA的一个状态集合

输入:一个NFA N

输出:一个转换后的DFA D

方法:为D构造一个转化表Dtran,D的每个状态都是一个NFA状态集合,利用Dtran,使D可以"并行"的模拟N遇到一个给定输入串时可以执行的所有动作。须要解决的问题包括,正确处理N的 空串 的转换。

最小化一个DFA的状态数

例中A和C等价,都不接受状态,对于任意输入总能转到同一个状态。

结论:对于任何正则语言都有一个唯一的 状态数目最少的DFA,通过分组合并并等价的状态,可以构造状态数最少的DFA。

死状态:所有输入符号上都转向自己的非接受状态。在一个DFA中,每个状态出发每个输入符号上都会有一个转换,发现正确词素的时候DFA结束。

从正则表达式构造NFA

可以将任何正则表达式变为接受相同语言的NFA。这个算法是语法制导的,就是沿着正则表达式的语法分析树自底向上递归进行处理。

对于每个子表达式,构造一个只有一个接受状态的NFA。

不同方法的开销

自动机 初始开销 每个串的开销
NFA O(r) O(rxs)
DFA typical case O(r^3) O(s)
DFA worst case O(r^2*2^r) O(s)

如果处理字符串所花时间很多,更倾向DFA。然而像grep这样的命令,只会对一个符号串运行自动机,通常使用NFA方式。

原文地址:https://www.cnblogs.com/SeekHit/p/7928401.html