编译原理笔记2:词法分析基础与模式的形式化描述

文章详细阐述了词法分析的过程,包括模式和记号的概念,以及如何用正规式来描述词法规则。正规式是定义语言集合的关键工具,而词法分析器则根据这些规则将源代码转换为记号流。此外,文章还提及了不同类型的文法,如上下文无关文法和正规文法,它们在描述编程语言结构中的作用。
摘要由CSDN通过智能技术生成

编译原理笔记2:词法分析基础与模式的形式化描述

词法分析,是词法分析器将源程序转化为线性记号流的过程。该过程中会对各种符号进行分类,比如将变量名换为标识符。

词法分析的含义:

  1. 规定词形成的规则,定义什么词是合法的;
  2. 根据规则识别输入的序列(词法分析),识别合法单词、指出非法的输入序列。

词法分析

模式、记号、单词

  • 模式(Pattern): 产生和识别元素的规则。也就是定义的词法规则;
  • 记号(Token): 按照某个模式(即,规则)识别出的(一组)元素。进行词法分析时,词法分析器将程序代码中的各个部分转为一个个记号的过程,就是根据规则得到一个记号流的过程;
  • 单词(lexeme): 被识别出的元素自身的值(一个),也称为词值。可以理解为源程序中一个个的字符串。

上面三个词放一起理解:源程序里面是一个个单词,我们使用“模式”这个规则,对单词进行识别、分类,把它们放到相应的记号里面去。记号是一堆单词,Pascal 语言的记号举例如下:

记号的类别单词举例模式的非形式化描述
const(01)constconst
if(03)ifif
relation(81)<, <=, =, <>, >, >=<, <=, =, …
id(82)pi, count, D2字母打头的字母数字串
num(83)3.1416, 0, 6.02E23任何数值常数
literal(84)“core dumped”双引号间的任意字符串
comment{ x is an integer }花括号间的任意字符串
  • id: 标识符记号。这里“字母”需要进行严格的形式化描述;
  • literal:字面量;
  • comment:注释
单词的基本分类
  • 关键字 kw(keyword, reserved word)
  • 标识符 id (identifier)
  • 字面量 literal
  • 特殊符号 ks (key symbol, special symbol)

例:

请添加图片描述

记号

记号 = 记号的类别 + 记号的属性

例如,mycount > 25,由三个记号组成。类别就是上表中对应的类别编号

请添加图片描述

词法分析器的作用与工作方式

编译器中只有该部分直接接触源代码,其他的部分都是通过使用之前的工作成果来间接接触源代码。词法分析器要进行的工作包括:

  1. 去掉注释、空格一类的无用部分;
  2. 处理和平台有关的输入,比如文件结束符的不同表示;
  3. 根据模式识别记号,交给语法分析器;(主要功能)
  4. 调用符号表管理器/出错处理器,进行相关处理。

工作方式:

  1. 词法分析器单独进行扫描,生成记号流。再将整个记号流交给语法分析器;
  2. 词法分析器作为语法分析器的子程序进行工作,语法分析器调用词法分析器去读源程序,得到词法分析器返回的记号就拿来构造语法树。然后用掉了这个记号就再去调用词法分析器读新的记号,如此重复;
  3. 词法、语法分析器并行工作。两者有一个共享的记号流,前者不停读程序、把记号放入记号流,后者不停取记号流来构造语法树。

模式的形式化描述

字符串与语言

从词法分析角度来看,语言是记号(Token)的集合

语言 L 是有限字母表 Σ 上有限长度字符串的集合字母表是字符的集合
空集Ø是一个语言,仅含一个空符号串的集合{ε}也是一个语言。Ø和{ε}是不同的语言。

字母表中的字符能够组成字符串。

例:字母表 Σ={ a, b, c },则其上的语言 L = { ε, a, b, c, aa, ab, ac, ba, bb, bc, … } (ε为空串,长度为0)

字符串的基本概念
术语示例
|S||abc| = 3
ε|ε| = 0
S1S2abc def = abcdef
Sn(abc)3 = abcabcabc
S 的前缀 Xabc 的前缀有:ε, a, ab, abc
S 的后缀 Xabc 的后缀有:ε, c, bc, abc
S 的子串 Xabc 的子串有:ε, a, b, c, …
S 的真前缀abc 的真前缀有:a, ab(去掉空和全)
S 的真后缀(去掉空和全)
S 的真子串(去掉空和全)
S 的子序列 Xabdf 是 abcdef 的一个子序列(和原序列顺序相同,可去掉一些字母)
术语意义
Φ空集合
{ ε }空串是唯一元素
X = L ∪ M并: X = { s| s∈L or S ∈M }
X = L ∩ M交:X = { s | s∈L and S ∈M }
X = LM连接: X = { st|s∈L and t ∈ M }
X = L*(星)闭包:X= L0∪L1∪L2∪…
X = L+正闭包:X= L1∪L2∪L3∪…

若 L = {a, b}, M = {c, d}, 则 LM = {ac, bc, ad, bd}, L∪M = Φ

对任意符号串集合A,有{ε}A = A{ε} = A

L* = { ε, a, b, aa, bb, ab, ba, aaa, … }

L+ = { a, b, aa, bb, ab, ba, aaa, … }

A 0 A^0 A0 = {ε}
A 1 A^1 A1 = A
A n A^n An = A A n − 1 A^{n-1} An1(n>0)
eg:若A={0,1},则 A 0 A^0 A0 ={ε}, A 1 A^1 A1={0,1}, A 2 A^2 A2={00,01,10,11}。

在这里插入图片描述

正规式与正规集(文法和语言)

正规式是用来描述词法规则的,也就是描述:记号该长成什么样子、数字该长成什么样子之类。

正规式(Regular Expression,也叫正则表达式)是在字母表之上的集合——正规式表示集合。

正规式表示的集合叫做正规集,而正规集是语言,因此正规式表示语言。

比如有个正规式是字母 a,那么正规式 a 表示集合 {a},集合 {a} 就是语言 L(a)。

正规式表示正规集,正规集是与正规式对应的语言。

这两个概念是词法分析的基础。

正规式和正规集的递归定义

Σ 是有限字母表,则其上的正规式及其表示的集合(即正规集)递归定义如下:

  1. ε 是正规式,其表示集合(正规集) L(ε) = {ε}
  2. 若 a 是 Σ 上的字符,则 a 是正规式,它表示集合 L(a)={a}
  3. 若正规式 r 和 s 分别表示集合 L( r ) 和 L(s),则
    1. r|s 是正规式,表示集合 L( r) ∪ L(s)(“|”在正规式中表示“或”,也可以写作 r + s )
    2. rs 是正规式,表示集合 L( r)L(s)(直接将两个语言拼接起来,也可以写作 r·s)
    3. r* (正规式是一个星闭包)也是正规式,表示集合(L( r))*(L( r)这个语言进行星闭包)
    4. ( r) 是正规式,表示的集合仍然是 L( r)(也就是说正规式 r 外面括上括号得到的 ( r) 仍然是正规式,加括号可以用来改变运算次序)

语言是字母表上字符串的集合,而正规式是语言,因此正规式是字母表上字符串的集合

可以用正规式描述的语言,就是正规语言或正规集

定义的扩展说明
  1. 运算有优先级和结合性

    • 三种运算都有左结合的性质(左结合的意思是,当多个同优先级符号连写时是从左往右算。如果从右往左算就叫右结合)
    • 优先级从高到低:闭包、连接、或

    正规式中不必要的括号(去掉了也不影响运算顺序)是可以省略的。

    例:正规式: a|b*c 表示的语言有以下两种情况:

    1. 表示一个串:a
    2. 表示另一个串:以 0 到多个 b 开头,以 c 结尾
  2. 正规式的等价

    长得不同的正规式可以表示同一个正规集(就像加法中的1+3、2+2都可以表示4一样),即,同一个正规集可以对应多个正规式

正规式等价

定义:若正规式 P、Q 表示了同一个正规集,则称 P、Q 是等价的,记为 P = Q

【例】: 设字母表 Σ={a, b, c}, 则 Σ 上有:

正规式正规集
a, b, c{a}, {b}, {c}
a|b, b|a{a}∪{b} = {a, b}
a(a|b)*{a, aa, ab, aba, abb, aab, …},以 a 为首的 ab 串
Σ*{ε, a, b, c, aa, ab, ac, ba, bb, bc, …}

【例】:令 L(x) = {a, b}, L(y) = {c, d}

     则 L(x|y) = {a, b, c, d}

          L(y, x) = {a, b, c, d}

判断等价性,可以根据定义,证明两个正规式是否能表达同一个集合;也可以使用正规式的代数性质进行运算比较:

公理公理
r|s = s|r( r s ) t = r( s t )
r|( s|t ) = ( r|s )|tε r = r , r ε = r
r ( s|t ) = r s | r tr* = ( r+ | ε )
( s|t ) r = s r | t rr** = r*

简言之,就是:

  • |可交换、可结合;
  • · 对 | 可分配;
  • · 可结合;
  • 幂等

记号的说明

先复读一遍模式、记号的概念:

  • 模式(Pattern): 产生和识别元素的规则,就是定义的词法规则;
  • 记号(Token): 按照某个模式(或规则)识别出的元素(一组)。进行词法分析时,将程序转为一个个的记号,就是根据规则得到一个记号流;

正规式可以用于严格地规定记号的模式。用正规式说明记号的公式:

记号=正规式 读作“记号定义为正规式” / “记号是正规式”。不引起混淆的情况下,可以直接把说明记号的公式叫做正规式/规则

e.g. id = a ( a | b )* 读作:“id定义为a(a|b)*”(这里的 id 就是一个标识符了。定义为a开头的ab串)

【例】记号 relation、id、num 分别是 Pascal 的关系运算符、标识符和无符号数,它们的正规式表示如下:

relation = < | <= | <> | > | >= | =
    
id = (a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z)
(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|0|1|2|3|4|5|6|7|8|9)*
    
num = (0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*
      (ε|.(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)
      (ε|E(+|-|ε)(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)

其中,一些东西可以进行简化描述

简化描述
  1. 正闭包:r 表示 L( r) 的正规式,那么 r+ 就表示 (L( r))+的正规式。

    即:r+ = rr* = r*r, r* = r+|ε

    比如:(0|1…|9)(0|1…|9)* 可以化简为 (0|1…|9)+

  2. 可缺省:r? 表示 L®∪{ε} 的正规式。

    即:r? = r|ε

    比如: E(+|-|ε) 可改写为:E(+|-)?

上面这些运算中的 +、? 、* 的结合性、优先级相同。

  1. 字符组。字符组是正规式的一种形式:对于只由 | 构成的正规表达式 r,可以改写为[r’]:

    • r’ 可以枚举:正规式 r = a|b|c 等价于 [abc]
    • r’ 可以分段:[0123456789abcdefghijklmnopqrstuvwxyz]等价于[0-9a-z]
  2. 非字符组。这里的“非”指的是非运算。也就是去掉某部分:

    若 [r] 是字符组形式的正规式,则 [^r] 表示 Σ -L( r) 的正规式,例如:

    若 Σ={a, b, c, d, e, f, g},则 L(^abc)={d, e, f, g}

  3. 辅助定义。就是给已有的正规式起个名字,以后可以直接用这个名字指代。

    请添加图片描述

    (如果 digits 不加花括号,那 digits 就是“ digittttt… ”)

    optional_fraction:可选的小数位。小数点如果不加双引号,在这里表示任意一个字符。

    optional_exponent:可选指数

请添加图片描述

上面的是 id,下面的是 num

2.2.2 语言的形式化定义

  1. 直接推导与推导(直接推导是一步,推导是任意步
  2. 句子是树叶,为终结符集,可以推导出来的则都为句型)句子一定是句型,句型不一定是句子
  3. 语言(语言是句子的集合,并且每个句子都能从开始符号推导得来,是终结符集的闭包的子集

在这里插入图片描述

2.2.3 短语、直接短语、句柄

  • 直接短语一定是一个产生式的右部,但是产生式的右部不一定是当前句型的直接短语(例如活水可能是为有源头活水来的直接短语,而不是当前句型的直接短语)
  • 高人,民生,活水则都不是当前句型的直接短语
    在这里插入图片描述

2.2.4规范推导和规范归约(最右推导,最左规约)

  1. 最左推导:对一个推导序列中的每一步直接推导α⇒β,都是对α中的最左非终结符进行替换
  2. 最右推导(规范推导):对一个推导序列中的每一步直接推导α⇒β,都是对α中的最右非终结符进行替换
  3. 规范句型:由规范推导得到的句型。
  4. 最左归约(规范归约):规范推导的逆过程

2.3 语法分析树与文法的二义性

2.3.1 语法分析树

  1. 语法分析树:一个句型推导过程的树形表示称为语法分析树,简称语法树。
  2. 满足条件:设G=( V N {V}^N VN V T {V}^T VT,P,Z)是一个上下文无关文法(CFG)。
    1)根节点的标记为Z。
    2)根节点外的每个节点也有一个标记,它是 V N {V}^N VN V T {V}^T VT∪{ε}中的符号。
    3)每一个内部节点(非终结符,所以标记在 V N {V}^N VN)的标记A必在VN中。
    4)若某个内部节点标记为A,其子节点的标记从左到右分别为X1,X2,…,Xn,则A→X1X2…Xn必为P中的一条产生式规则。
    5)若节点有标记ε,则该节点为叶子,且是它父亲唯一的孩子(子节点存在标记ε,则是其父节点的唯一子节点,即其无兄弟节点)。
  3. 构造步骤:已知文法G[Z],对于w,若Z ⇒* w,则
    1)以开始符号Z为标记的根节点。
    2)对每一步推导,根据使用的产生式规则生成一颗子树,直到所有叶子节点从左到右的标记符号连接为w为止。
    若产生式规则为A→X1X2…Xn,则生成以A为根节点的子树,其孩子节点从左到右分别为X1,X2,…,Xn。
    eg:设文法G[E]:
    E→E+T|E-T|T
    T→TF|T/F|F
    F→(E)|i
    推导句型T+i
    (F-i)的语法树。

在这里插入图片描述

2.3.2 文法的二义性

  1. 定义:若一个文法存在某个句子对应两棵不同的语法树,则称这个文法是二义的。
  2. 特点:为编译程序的执行带来不确定性

2.3.3 二义性的消除

  1. 不改变文法:通过附加限制性条件(增加消歧规则,例如:每个if跟最近的尚未匹配的else匹配)消除二义性。
    寻找充分不必要条件,当文法满足这些条件时可确保文法是无二义性的。(即满足就是二义性,不满足也不一定是无二义性
    2.改变文法:改写原有文法(增加 V N {V}^N VN或者空产生式),把排除二义性的规则合并到原文法消除二义性。

2.4 文法的化简

  1. 若一个非终结符不能推导出终结字符串,则该非终结符是无用的,删除所有包括该非终结符的产生式规则。
  2. 若一个符号不能出现在文法的任何句型中,则该符号是无用的,删除所有包括该符号的产生式规则。

2.5 语言的分类

二型识别程序设计语言,三型定义程序设计语言

  • 0型文法(短语文法,上下文无关文法),每个产生式的左边α∈( V N {V}^N VN V T {V}^T VT)*且至少含有一个非终结符号
    1)定义:若文法G[Z]=( V N {V}^N VN V T {V}^T VT,P,Z)中的每个产生式规则的形式为:α→β,其中α∈( V N {V}^N VN V T {V}^T VT) 且至少含有一个非终结符号,而β∈( V N {V}^N VN V T {V}^T VT),则G[Z]为0型文法。
    2)特点:0型文法的能力相当于图灵机,识别能力最强
  • 1型文法(上下文敏感文法)
    1)定义:若文法G[Z]=( V N {V}^N VN V T {V}^T VT,P,Z)中的每个产生式规则的形式为:αAβ→αvβ,其中α,β∈( V N {V}^N VN V T {V}^T VT),A∈ V N {V}^N VN,v∈( V N {V}^N VN V T {V}^T VT)+,则G[Z]为1型文法。
  • 2型文法(上下文无关文法)(左边只是Vn,0型文法左边则( V N {V}^N VN V T {V}^T VT)*
    1)定义:若文法G[Z]=( V N {V}^N VN V T {V}^T VT,P,Z)中的每个产生式规则的形式为:A→v,其中A∈ V N {V}^N VN,v∈( V N {V}^N VN V T {V}^T VT)*,则G[Z]为2型文法。
    2)特点:语法结构上下文无关,一般用于识别程序设计语言的语法结构
  • 3型语言(正规文法)
    1)种类:右线性文法、左线性文法
    正则文法 左(右)线性文法
    2)右线性文法:若文法G[Z]=( V N {V}^N VN V T {V}^T VT,P,Z)中的每个产生式规则的形式为:A→αB或A→α,其中A,B∈ V N {V}^N VN,α∈( V N {V}^N VN V T {V}^T VT),则G[Z]为右线性文法。(非终结部分永远在右部)(最右推导)
    3)左线性文法:若文法G[Z]=( V N {V}^N VN V T {V}^T VT,P,Z)中的每个产生式规则的形式为:A→Bα或A→α,其中A,B∈ V N {V}^N VN,α∈( V N {V}^N VN V T {V}^T VT)
    ,则G[Z]为左线性文法。(非终结部分永远在左部)(最左推导)
    4)特点:作为定义程序设计语言规则的文法
    5)正规语言:3型文法定义的语言。

2.6课后问题

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VengaZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值