zoukankan      html  css  js  c++  java
  • 编译原理入门:词法分析

    本文介绍词法分析的基本概念与几个重要算法的思想。

    概念与背景

    扫描字符,拼接成词”,这是对词法分析器主要功能的精简概括。

    词法分析是编译的第一个阶段,从左到右逐个字符地对源程序进行扫描,产生一个个单词序列(标记,token),用于语法分析。事实上,词法分析器除了按规则识别单词、管理单词的属性(调用符号管理器)之外,还会过滤源程序中的无用部分(注释等)并处理错误。

    image-20210814164032348

    我们通常用正则表达式(正规式)来说明单词的构成模式,是表示正规集的数学工具。正规集也就是有正规式可以确定的串的集合。

    image-20210814164256265

    根据乔姆斯基的分类,文法可以分为 4 种,分别为 0 型文法(无限制文法)、1 型文法(上下文相关文法,Context Sensitive)、2 型文法(上下文无关文法,Context Free)和 4 型文法(正规文法)。

    其中,上下文无关文法的产生式形如 ((V_N) ightarrow (V_N igcup V_T)^+)示意用,非正式记法),而正规文法是在其基础上进一步限制,分为左线性右线性两种。左线性即 ((V_N) Rightarrow (V_T) | (V_T)(V_N)),右线性即 ((V_N) ightarrow (V_T)|(V_N)(V_T))

    image-20210814164721748

    有穷自动机 (finite state automata) 是一个识别器,它对每个输入的字符做识别和判断,以确定其能到达的最终状态或状态集和路径,有穷自动机分为两类,即不确定的有穷自动机 NFA 和确定的有穷自动机 DFA

    DFA 和 NFA 的区别在于:DFA 没有对空串的转换操作;DFA 从一个状态,对一个特定的符号输入只能得到一个状态,而 NFA 可能得到一个状态集合。

    image-20210814190557914

    接下来,我们讨论正则文法、正则表达式、NFA 之间的相互转换,以及如何从 NFA 构建 DFA 并化简。

    image-20210814200323953

    将 NFA 转换为 DFA

    有定理曰:如果语言 L 被一个 NFA 所接受,那么一定存在一些 DFA 也接受这一语言 L。因此,一定可以构造 NFA 对应的 DFA。

    image-20210814190821763

    NFA 之 N 在于它接受一个特定的输入后,其所有可能的状态构成了一个集合,而非一个确定的状态。因此,在构造 NFA 对应的 DFA 时,我们考虑这个 NFA 可能到达的状态集合的所有可能性,并将每个状态集合映射为一个状态。

    image-20210814191000421

    算法对 NFA 的子集进行搜索。初态为 (s_0)(varepsilon) 闭包,将其加入候选队列。循环对候选队列中每个集合 (p),枚举字符集中的字符 (a),将状态集合中所有状态接受该字符后构成的新状态集合的 (varepsilon) 闭包 (u) 求出,如果 (u) 不是以及出现过的集合,则将其加入候选队列,并为 (u) 创建新的 DFA 节点。将 (p)(u)​ 的 (a) 边在 DFA 图中连上。

    image-20210814191444505

    DFA 化简

    我们将 M 的状态集首先分按是否为终态分为两个子集。

    每次考虑当前划分的每个子集,如果这个子集 (x)​ 的所有元素经过某一字母到达的所有状态不在划分的同一子集内(不属于同一个等价类),则将 (x)​ 按照这一情况继续划分以满足条件。

    不断迭代直到收敛。根据划分,建立化简后的 DFA 即可。

    image-20210814200000288

    正规式与 NFA 的转换

    首先我们考虑如何从正规式建立 NFA。这个过程是直观的,只需要将正规式不断拆解即可。

    image-20210814200800095

    建立 NFA 的过程,本质上是将若干已经构建的小 NFA 组装成大 NFA。

    image-20210814201029991

    NFA 转换为正规式的过程则类似上述过程的逆过程。

    首先我们需要为 NFA 添加超级源汇点(连接到所有初态、终态节点)。

    我们不断从 NFA 图中寻找三种模式,然后它们简化。直到只剩下两个节点一条边时,读出边上的串即可。

    image-20210814205717158

    正规文法和 NFA 的转换

    最后我们简要讨论一下正规文法与 NFA 的转换和对应关系。

    首先考虑如何从正规文法构建 NFA。我们主要关注状态转换函数(状态转换图)的产生。

    • 对于 (A o aB),有 (delta(A,a)=B)
    • 对于 (A o a),有 (delta(A,a)=T)
    • 对于 (ain V_T)(delta(A,a)=emptyset)

    反过来,对于任意 (a in Sigma, Bin S),若有 (delta(A,a)=B),则

    • (B otin F),则 (A o aB)
    • (B in F),则 (A o a|aB)
    • (s_0 in F)​,则 (s_0 o varepsilon)
  • 相关阅读:
    LeetCode My Solution: Minimum Depth of Binary Tree
    Managing Data in Containers
    ZooKeeper系列(四)
    ZooKeeper系列(三)
    ZooKeeper系列(二)
    Zookeeper系列(一)
    (转)淘淘商城系列——dubbo监控中心
    (转)淘淘商城系列——MyBatis分页插件(PageHelper)的使用以及商品列表展示
    (转)淘淘商城系列——展示后台管理页面
    (转)淘淘商城系列——服务调用测试
  • 原文地址:https://www.cnblogs.com/mollnn/p/15141845.html
Copyright © 2011-2022 走看看