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的实现

  • 相关阅读:
    【NOIP 2003】 加分二叉树
    【POJ 1655】 Balancing Act
    【HDU 3613】Best Reward
    【POJ 3461】 Oulipo
    【POJ 2752】 Seek the Name, Seek the Fame
    【POJ 1961】 Period
    【POJ 2406】 Power Strings
    BZOJ3028 食物(生成函数)
    BZOJ5372 PKUSC2018神仙的游戏(NTT)
    BZOJ4836 二元运算(分治FFT)
  • 原文地址:https://www.cnblogs.com/zhangzizi/p/14510912.html
Copyright © 2011-2022 走看看