编译原理第二弹——词法分析

学习完成编译原理基础之后,我们知道编译原理的第一步就是把源程序的单词进行分类处理,变成一个二元组token,包括单词的种类和值。

学习本章知识首先需要了解一些基本概念,不过编译原理这门课程学起来困难、枯燥的原因便是它概念非常的多,需要记忆的东西也很多,需要多多复习,理解记忆。

预备知识:(在这里我基本会采用一定的对比解释,方便理解)

  • 字母表与串:这两个概念有一定的包含关系。

  1. 字母表:字母表∑是一个有穷符号集合,例如,{1,2,3,a,c}就是一个字母表,其中符号包括字母、数字、标点符号、…
  2. 字母表上的运算:乘积——12 ={ab|a 1, b 2},例: {0, 1} {a, b} ={0a, 0b, 1a, 1b},其中默认:∑0 ={ ε }, ∑n =n-1 , n 1。例: {0, 1}3 ={0, 1} {0, 1} {0, 1}={000, 001, 010, 011, 100, 101, 110, 111},字母表的n次幂:长度为n的符号串构成的集合

                                正闭包——+ = 23...,例:{a, b, c, d }+ = {a, b, c, d,aa, ab, ac, ad, ba, bb, bc, bd, ...,},字母表的正闭包:长度正数的符号串构成的集合

                             克林闭包——* = 0+ = 023...,例:{a, b, c, d }* = {ε, a, b, c, d,aa, ab, ac, ad, ba, bb, bc ...},字母表的克林闭包:任意符号串(长度可以为零)构成的集合

  3. 串:是一个字母表,x*x称为是上的一个串。例如,{1,2,3,a,c}字母表,其中123就是串,s长度,通常记作|s|,是指s符号的个数,: |aab|=3,其中空串长度为0的串,用 ε表示,ε|= 0

  4. 串上的运算:连接——如果 x和y是串,那么x和y的连接是把y附加到x后面而形成的串,记作xy ,例如,如果 x=dog且 y=house,那么xy=doghouse,其中,εs = sε = s,设x,y,z是三个字符串,如果 x=yz, 则称y是x的前缀,z是x的后缀。

                                 幂—— 串s的幂运算 s0= ε,sn = sn-1s , n ≥1,例:如果 s =ba,那么s1= ba,s2=baba, s3=bababa,...

  • 文法的形式化定义,G=(VT ,VN ,P,S)
  • VT :终结符集合,终结符是文法所定义的语言的基本符号,例: VT = { apple, boy, eat, little }
  • VN:非终结符集合,非终结符是用来表示语法成分的符号, 有时也称为“ 语法变量”,例: VN = { 句子, 名词短语, 动词短语, 名词 ... },规定VT ∩VN=Φ,VT∪VN :文法符号集,
  • P :产生式集合,产生式描述了将终结符和非终结符组合成串的方法 产生式的一般形式:α→β 读作:α定义为β
  • 开始符号S∈VN。开始符号表示的是该文法中最大的语法成分,例:S = 句子, 约定: 不引起歧义的 前提下,可以 只写产生式
  • 符号约定(这部分需要记住,后期举例子,直接默认)
➢下述符号是终结符
(a) 字母表中排在前面的小写字母,如a、b、c
(b) 运算符,如+、*等
(c) 标点符号,如括号、逗号等 ➢(d) 数字0、1、. . . 、9
(e) 粗体字符串,如id、if等
 ➢下述符号是非终结符

(a) 字母表中排在前面的大写字母,如A、B、C 

(b) 字母S。通常表示开始符号

(c) 小写、斜体的名字,如expr、stmt等
(d) 代表程序构造的大写字母。如E(表达式)、T(项) 和F(因子)
 
➢字母表中排在后面的大写字母(如X、Y、Z) 表示文法符号(即终结符或非终结符)
➢字母表中排在后面的小写字母(主要是u、v、. . . 、z) 表示终结符号串(包括空串)
➢ 小写希腊字母,如α、β、γ,表示文法符号串(包括空串 ➢除非特别说明,第一个产生式的左部就是开始符号

  终结符 非终结符 文法符号

  • 句型和句子,对于一个文法(规则),通过该规则推导到最终产生的符号中只要终结符,则最后的符号为句子,过程中产生的符号为句型。
 
  •  语言,由文法G的开始符号S推导出的所有句子构成的集合称为文法G生成的语言,记为L(G )。 即
  • Chomsky 文法分类体系

➢0型文法 ,α →β,又称无限制文法,顾名思义,这种文法对于左右两边没有任何的限制

➢ 1型文法,又称上下文有关文法,满足∀α → β∈P,|α|≤|β|,产生式的一般形式: α1Aα2 → α1βα2 ( β≠ε ) 

➢ 2型文法α →β,又称上下文无关文法 ,满足∀α → β∈P,α∈VN ,产生式的一般形式:A→β,即保证A一定为非终结符

➢ 3型文法,又称正则文法,正则文法能描述程序设计语言的多数单词,要求相对严格,与后面的正则表达式、有限自动机等价

  • 四种文法之间的关系

  •  CFG 的分析树,上下文无关文法的语法分析树,分析树是推导的图形化表示
                            ➢ 根节点的标号为文法开始符号
                            ➢ 内部结点表示对一个产生式A→β的应用,该结点的标号是此产生式左 部A 。
                            ➢ 叶结点的标号既可以是非终结符,也可以是终结符。从左到右排列叶 节点得到的符号串称为是这棵树的产出



  •  (句型的)短语
➢给定一个句型,其分析树中的每一棵子树的边缘称为该句型的一个短语
➢ 如果子树只有父子两代结点,那么这棵子树的边缘称为该句 型的一个直接短语
  • 正则表达式,这是一个非常常见的概念,我们在学习编程语言的时候多少都会涉及这个知识。
正则表达式是一种用来描述正则语言的,例:r = a(a|b)*( ε | (.| _)(a|b)(a|b)* ),正则表达式可以由较小的正则表达式按照特定规则递归地构建。每个正则表达式 r定义一个语言,记为L(r )。

正则表达式的定义 ε是一个RE,L(ε) = {ε}

    如果 a∈∑,则a是一个RE,L(a) = {a}

 正则文法与正则表达式等价

    对任何正则文法 G,存在定义同一语言的 正则表达式 r

    对任何正则表达式 r,存在生成同一语言的 正则文法 G

现在进入正题,在编译器中一般采用词法分析器进行词法分析,也就是我们说的有穷自动机。

  有穷自动机
    有穷自动机 ( FA ),主要根据当前状态,以及输入字符进行状态的切换。

     FA使用转换图进行表示, 结点:FA的状态、初始状态(开始状态):只有一个,由start箭头指向 、终止状态(接收状态):可以有多个,用双圈表示、带标记的有向边:如果对于输入a,存在一个从状态p到状 态q的转换,就在p、q之间画一条有向边,并标记上a



            
该FA定义(或接收)的语言,记为L(M ) 
一般自动机都遵循,最长子串匹配原则,当输入串的多个前缀与一个或多个模式匹配时, 总是选择最长的前缀进行匹配在到达某个终态之后,只要输入带上还有符号, DFA就继续前进,以便寻找尽可能长的匹配
FA的分类

确定的FA (DFA)

确定的有穷自动机 (DFA)
M = ( S,Σ ,δ,s0,F )
S:有穷状态集
Σ:输入字母表,即输入符号集合。假设ε不是 Σ中的元素
δ:将S×Σ映射到S的转换函数。 s∈S, a∈Σ, δ(s,a)表示 从状态s出发,沿着标记为a的边所能到达的状态。
s0:开始状态 (或初始状态),s0∈ S F:接收状态(或终止状态)集合,F⊆ S

 通俗的理解就是,DFA每个状态中处理能接收的字符,进行跳转的选择是唯一的。

非确定的FA (NFA)

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

M = ( S,Σ ,δ,s0,F )
S:有穷状态集
Σ:输入符号集合,即输入字母表。假设ε 不是Σ中的元素
δ:将S×Σ映射到2S的转换函数。s∈S, a∈Σ, δ(s,a)表示 从状态s出发,沿着标记为a的边所能到达的状态集合
s0:开始状态 (或初始状态),s0∈ S F:接收状态(或终止状态)集合,F⊆ S
通俗的理解就是,NFA每个状态中处理能接收的字符,进行跳转的选择是不唯一的。

 DFA和NFA的等价性 

对任何非确定的有穷自动机N ,存在定义同一语言的确定的有穷自动机

对任何确定的有穷自动机D ,存在定义同一语言的 非确定的有穷自动机N
 
DFA和NFA可以识别相同的语言
由于等价,我们有办法实现正则表达式与NFA,NFA与DFA的转换。理解这两个过程最好的办法就是举例子。

正则表达式到NFA

这里需要使用五条规则




根据上述规则进行转换,把正则表达式转换成NFA

例:r=(a|b)*abb 对应的NFA


 NFA到DFA的转换

根据上述的NFA,构造转换表


根据表把{A,B},{B,C},{C,D}作为新的状态



  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
词法分析 一、实验目的: 通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。 编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示) 、实验说明 1、 词法分析器的功能和输出格式 词法分析器的功能是输入源程序,输出单词符号。词法分析器的单词符号常常表示成以下的元式(单词种别码,单词符号的属性值)。本实验中,采用的是一类符号一种别码的方式。 2、 单词的BNF表示 -> ->|| |ε -> -> |ε -> + -> - -> > -> >= 三、实验要求 (一)准备: 1.阅读课本有关章节,明确语言的语法,写出基本保留字、标识符、常数、运算符、分隔符和程序例。 2.初步编制好程序。 3.准备好多组测试数据。 ()上课上机: 将源代码拷贝到机上调试,发现错误,再修改完善。 第二次上机调试通过。 (三)程序要求: 程序输入/输出示例: 如源程序为C语言。输入如下一段: main() { int a,b; a = 10; b = a + 20; } 要求输出如下: (2,”main”) (5,”(“) (5,”)“) (5,”{“) (1,”int”) (2,”a”) (5,”,”) (2,”b”) (5,”;”) (2,”a”) (4,”=”) (3,”10”) (5,”;”) (2,”b”) (4,”=”) (2,”a”) (4,”+”) (3,”20”) (5,”;”) (5,”}“) 要求: 识别保留字:if、int、for、while、do、return、break、continue; 单词种别码为1。 其他的都识别为标识符;单词种别码为2。 常数为无符号整形数;单词种别码为3。 运算符包括:+、-、*、/、=、>、=、<=、!= ; 单词种别码为4。 分隔符包括:,、;、{、}、(、); 单词种别码为5。 以上为参考,具体可自行增删。 (四)程序思路 这里以开始定义的C语言子集的源程序作为词法分析程序的输入数据。在词法分析中,自文件头开始扫描源程序字符,一旦发现符合“单词”定义的源程序字符串时,将它翻译成固定长度的单词内部表示,并查填适当的信息表。经过词法分析后,源程序字符串(源程序的外部表示)被翻译成具有等长信息的单词串(源程序的内部表示),并产生两个表格:常数表和标识符表,它们分别包含了源程序中的所有常数和所有标识符。 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将源程序全部输入到字符缓冲区中。 2.取单词前:去掉多余空白。 3.取单词后:去掉多余空白(可选,看着办)。 4.取单词:利用实验一的成果读出单词的每一个字符,组成单词,分析类型。(关键是如何判断取单词结束?取到的单词是什么类型的单词?)
这个里面的都是测试数据,总共得分5分。从控制台输入,不能从文件中读取。实现了基本功能,加分项目都没有去实现,没有函数数组这些的实现。这是用C++语言写的,新建parser类别要选C++,其他对于VS的配置和C语言一样。for语句用的是枚举所有情况,你可以自行修改。 对预备工作中自然语言描述的简化C编译器的语言特性的语法,设计上下文无关文法进行描述 借助Yacc工具实现语法分析器 考虑语法树的构造: 1.语法树数据结构的设计:节点类型的设定,不同类型节点应保存哪些信息,多叉树的实现方式 2.实现辅助函数,完成节点创建、树创建等功能 3.利用辅助函数,修改上下文无关文法,设计翻译模式 4.修改Yacc程序,实现能构造语法树的分析器 考虑符号表处理的扩充 1.完成语法分析后,符号表项应增加哪些标识符的属性,保存语法分析的结果 2.如何扩充符号表数据结构,Yacc程序如何与Lex程序交互,正确填写符号表项 以一个简单的C源程序验证你的语法分析器,可以文本方式输出语法树结构,以节点编号输出父子关系,来验证分析器的正确性,如下例: main() { int a, b; if (a == 0) a = b + 1; } 可能的输出为: 0 : Type Specifier, integer, Children: 1 : ID Declaration, symbol: a Children: 2 : ID Declaration, symbol: b Children: 3 : Var Declaration, Children: 0 1 2 4 : ID Declaration, symbol: a Children: 5 : Const Declaration, value:0, Children: 6 : Expr, op: ==, Children: 4 5 7 : ID Declaration, symbol: a Children: 8 : ID Declaration, symbol: b Children: 9 : Const Declaration, value:1, Children: 10: Expr, op: +, Children: 8 9 11: Expr, op: =, Children: 7 10 12: if statement, Children: 6 11 13: compound statement, Children: 3 12

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值