词法分析的任务是对字符串表示的源程序从左到右地进行扫描和分解,根据语言的词法规则识别出一个一个具有独立意义的单词符号。
语言的单词符号是指语言中具有独立意义的最小语法单位 。
关键字 也称基本字,例如,C语言中的if,else,while, do等, 这些字在语言中具有固定的意义,一般不作为标识符使用。
标识符 表示各种名字,如变量名、常量名、数组名和函数名等。
常数 各种类型的常数,如整型常数125、实型常数0.718、布尔型常数TRUE等 。
运算符 如+、-、*、/、<等。
分界符 如 ,、;、(、)、:等 。
词法分析程序输出单词的形式
词法分析程序所输出的单词符号通常表示成如下的二元式:
(单词种别,单词自身的值)
单词种别
单词种别表示单词的种类,它是语法分析需要的信息。
为处理方便通常让每种单词对应一个整数码。
基本字: 可将其全体视为一种,也可以一字一种。
标识符: 一般统归为一种。
常数: 可统归为一种,也可按类型(整型、实型、布尔型等)分种。
运算符和界符: 可采用一符一种的分法,也可以统归为一种。
单词自身的值
正规式中包含三种运算符:
连接“·”,或“|”和闭包“*”。
其中闭包运算的优先级最高,连接运算次之,或运算最低。连结符“·”一般可省略不写。这三种运算符均是左结合的。
注意:
如果正规式 R1 和 R2 描述的正规集相同, 则我们称正规式R1与R2等价。记为 R1=R2。
1. 正规文法到正规式的转换
(1) 将正规文法中的每个非终结符表示成关于它的一个正规式方程,获得一个联立方程组。
(2) 依照求解规则:
若 A → xA |y 则解为 A = x*y
若 A→xB B→y 则A=xy
若A→x A→y 则A=x|y
以及正规式的分配律、交换律和结合律求关于文法开始符号的正规式方程组的解。
2. 正规式到正规文法的转换
(1) 令 VT=Σ 。
(2) 对任何正规式R选择一个非终结符Z生成规则Z→R并令S=Z。
(3) 若a和b都是正规式,对形如 A→ab 的规则转换成 A→aB 和 B→b 两规则,其中B是新增的非终结符。
(4) 对已转换的文法中, 形如A →a*b 的规则,进一步转换成 A →aA | b 。
(5) 不断利用规则(3)和(4)进行变换,直到每条规则最多含有一个终结符为止。
有穷自动机是具有离散输入与输出系统的一种抽象数学模型。有穷自动机有“确定的”和“非确定的”两类,确定的有穷自动机和非确定的有穷自动机都能准确地识别正规集。
确定有穷自动机(DFA)
一个确定有穷自动机M是一个五元组
M=( Q, Σ, f, S, Z )
Q是一个有穷状态集合,每一个元素称为一个状态。
Σ是一个有穷输入字母表,每个元素称为一个输入字符。
S∈Q ,是唯一的一个初态。
Z⊆Q ,是一个终态集。
非确定有穷自动机(NFA)
一个非确定有穷自动机M是一个五元组
M=( Q, Σ, f, S, Z)
其中:Q, ∑, Z 意义同DFA ,f 和 S不同于DFA 。
事实上DFA是NFA 的特例, 即对于每个NFA M 存在 DFA M' ,使 L(M) = L(M')。因此,我们利用有穷自动机构造词法分析程序的方法是从语言单词的描述中构造出非确定的有穷自动机,再将非确定的有穷自动机转化为确定的有穷自动机,并将其化简为状态最少化的DFA , 然后对DFA的每一个状态构造一小段程序将其转化为识别语言单词的词法分析程序。
输入:字母表Σ上的正规式R
输出:识别(接受)语言L(R)的NFA N
方法:
基本思想:
对于一个NFA,由于状态转换函数 f 是一个多值函数 ,因此,对于它们有
f ( q, a)={q1 , q2 , q3…,qn}
即是NFA状态集合的一个子集,为了将NFA转换为DFA,把状态集合{q1 , q2 , q3…, qn}看作一个状态A。
也就是说,DFA的每一个状态代表NFA状态集合的某个子集,这个DFA使用它的状态去记录在NFA读入输入符号之后可能到达的所有状态的集合,我们称此构造方法为子集法。
输入:一个NFA N
输出:一个接受(识别)相同语言的DFA M
方法:利用构造 ε –闭包的方法将NFA确定化为DFA。
由定义可知, ε – closure(I) 表示所有那些从I中的元素出发经过 ε 道路所能到达的NFA的状态所组成的集合, I中任何状态也在其中,因为它们是通过 ε 通路到达自身的。该集合对DFA来说是一个状态。
1. DFA的化简
所谓一个DFA M 的化简是指寻找一个状态数比 M 少的 DFA M' ,使得 L(M)=L(M') 。
化简了的DFA满足两个条件:
(1) 没有多余状态。
(2) 它的状态集中没有两个状态是互相等价的。
2. 多余状态
所谓有穷自动机的多余状态是指从该自动机的开始状态出发,任何输入串也不能到达的状态。
3.等价状态
4.两个状态等价的条件:
一致性条件: 状态s和t必须同时为终态或非终态。
蔓延性条件: 对于所有输入符号a,状态 s 和 t 必须转到等价的状态里。
5.化简方法
输入:一个DFA M 。
输出:接受与M相同语言的DFA M ',且其状态数最少。
无多余状态下把M的状态集 Q 分划成一些不相交的子集,使得每个子集中任何两个状态是等价的,而任何两个属于不同子集的状态都是可区别的。
然后在每个子集中任取一个状态作“代表”, 而删去子集中其余状态, 并把射向其余状态的箭弧都改作射向作“代表”的状态中。
下面给出化简算法的具体执行步骤:
1. 在 M 的转换图上添加两个结点: X 结和Y结。从X结用ε连线连结到M的所有初态结点,从 M 的所有终态结点用ε连线连结到 Y 结,从而构成一新的非确定有穷自动机 M’,它只有一个初态结 X和一个终态结Y。显然,L(M)=L(M’)。即,这两个NFA是等价的。
2. 逐步消去M’中的其它结点,直至只剩下X,Y结点。在消除结点过程中,逐步用正规式来标记相应的箭弧。
消除结点的过程是很直观的,只需反复使用下图的替换规则即可。
设给定有穷自动机M = (Q , Σ , f , q0 , Z )
则相应的正规文法 G = (VN ,VT , P , S)
1. 令 VN = Q VT = Σ S = q0
2. 若f (A,a)=B 且B∉Z时,则将产生式 A→aB 加到P中。
3. 若f (A,a)=B 且B∈Z时,则将产生式 A→aB、B→ε 加到P中。
4. 若文法的开始符号S是一个终态,则将产生式 S→ε 加到P中。