zoukankan      html  css  js  c++  java
  • 第二章:词法分析1

    第二章:词法分析1

    2.1 词法分析的任务

    编译器的阶段

    image-20210310095351771

    前端处理的是和源语言相关,后端处理的是和体系结构和目标机相关的程序。

    image-20210310095618276

    词法分析器的任务

    image-20210310095740291

    读入字符流后,词法分析器对整个字符流进行切分,按照它们是关键字、标识符、标点符号、字符串、整型数做一个明确的划分。

    例子

    image-20210310100332117

    每一个IF、LPAREN等都是记号(单词),结束会有一个EOF。

    记号的数据结构

    image-20210310100604491

    不同的语言,枚举类型是有限的但不一定相同。

    lexeme是所识别的单词的具体的值。

    if(x>5)
    
    token{ k = IF, lexeme = 0};
    token{ k = LPAREN, lexeme = 0};
    token{ k = ID, lexeme = 'x'};
    

    小结

    • 词法分析器的任务:字符流到记号流
      • 字符流:
        • 和被编译的语言密切相关(ASCII,Unicode,...)
      • 记号流:
        • 编译器内部定义的数据结构,编码所识别出的词法单元(记号)

    2.2 词法分析器的手工构造

    描述任何一个软件系统最重要的可能都是输入输出接口。

    词法分析器的实现方法

    • 手工编码实现法
      • 相对复杂、且容易出错
      • 但是目前流行
        • GCC、LLVM、...
      • 对程序的各个部分都会有精确的控制,算法和数据结构都是由程序员控制的。
      • 效率高
    • 词法分析器的生成器
      • 快速原型、代码量少
      • 较难控制细节

    转移图

    image-20210310101926175

    如何分析符号

    <=	LE
    <>	NE
    < 	LT
    = 	EQ
    >=	GE
    > 	GT
    

    *代表一次回退

    转移图算法

    image-20210310102618379

    标识符的转移图

    image-20210310102914509

    标识符和关键字

    • 很多语言中的标识符和关键字有交集
      • 从词法分析的角度看,关键字是标识符的一部分
    • 以C语言为例:
      • 标识符:以字母或下划分开头,后跟零个或多个字母、下划线、或数字
      • 关键字:if ,while,else,...

    识别关键字(以if为例)

    image-20210310103549529

    关键字表算法

    • 对给定语言中所有的关键字,构造关键字构成的哈希表H
    • 对所有的标识符和关键字,先统一按标识符的转移图进行识别
    • 识别完成后,进一步查表H看是否是关键字
    • 通过合理的构造哈希表(完美哈希),可以在(O(1))时间完成

    2.3 正则表达式

    自动生成

    image-20210310104124275

    声明式的规范:正则表达式

    转换:正则表达式—>自动机

    lex、flex、jlex

    正则表达式

    • 对给定的字符集(Sigma = { c1,c2,...,cn})
    • 归纳定义:
      • 空串 (varepsilon) 是正则表达式
      • 对于任意(cin Sigma),c是正则表达式
      • 如果M和N是正则表达式,则以下也是正则表达式
        • 选择 $ M|N = {M,N} $
        • 连接 $ MN ={mn| min M,n in N }$
        • 闭包 (M*={varepsilon,M,MM,MMM,...})

    举例

    1. 对于给定字符集(Sigma = { a,b}),可以写出哪些正则表达式?
    2. C语言中的关键字:例如if,while等,如何用正则表达式表示?
    3. C语言中的标识符:以字母或下划线开头,后跟零个或多个字母、数字或下划线。如何用正则表达式表示?
    4. C语言中的无符号整数:(十进制整型数)规则:或者是0;或者是以1到9开头,后跟零个或多个0到9。如何用正则表达式表示?

    语法糖

    • 可以引入更多的语法糖,来简化构造
      • [c1-cn] == c1|c2|…|cn
      • e+ == 一个或多个 e
      • e? == 零个或一个 e
      • “a*” == a* 自身, 不是a的Kleen闭包
      • e{i, j} == i到j个e的连接
      • . == 除‘ ’外的任意字符

    2.4 有限状态自动机

    image-20210310113322930

    正则表达式(INPUT)、lex(flex)(转换算法内部)、有限状态自动机(OUTPUT)

    有限状态自动机(FA)

    image-20210310113943522

    自动机例子1(DFA)

    字母表:(Sigma = {a,b})

    状态集:(S={0,1,2})

    初始状态:(q_0=0)

    终结状态集:(F={2})

    转移函数:(delta={(q_0, a) ightarrow q_1,(q_0, b) ightarrow q_0,(q_1, a) ightarrow q_2,(q_1, b) ightarrow q_1,(q_2, a) ightarrow q_2,(q_2, b) ightarrow q_2})

    实际上转移函数也就是一个映射关系,也可以用如下的图来表示。

    image-20210310115142504

    接受:首先处于初始状态,当串S在状态机上读完后转移到了最后状态,即称这个串可以被接受。

    自动机例子2(NFA)

    image-20210310115705408

    值域发生了变化,转移函数不确定,这类自动机为非确定的自动机(NFA)。上面的例子1就是确定的自动机(DFA)。

    对于NFA来说,难以判断是否接受串S。需要遍历,排除不接受的路径,再回溯找到接受的路径。

    一般来说,会将NFA转换为DFA来进行简化。

    小结

    • 确定状态有限自动机DFA

      • 对任意的字符,最多有一个状态可以转移

        (delta: mathrm{S} imesSigma ightarrow mathrm{S})

        (这里是笛卡尔积)

    • 非确定的有限状态自动机NFA

      • 对任意的字符,有多于一个状态可以转移

        (delta: mathrm{S} imes(Sigma cup varepsilon) ightarrow wp(mathrm{S}))

        (wp(S))表示是幂集

    DFA的实现

  • 相关阅读:
    实时监听输入框值变化的完美方案:oninput & onpropertychange
    展示两行,超出用。。。表示
    修改下拉框滚动条样式
    js单线程工作
    锚点
    火狐图片乱码
    解决重复提交的几种方法
    forward和redirect的区别
    form表单刷新自动提交
    addEventListener和attachEvent的区别
  • 原文地址:https://www.cnblogs.com/zhangzizi/p/14510912.html
Copyright © 2011-2022 走看看