• 编译原理-词法分析04-NFA & 代码实现


    编译原理-词法分析04-NFA & 代码实现

    0.术语

    NFA

    非确定性有穷自动机nondeterministic finite automation。

    ε-转换ε-transition

    是无需考虑输入串(且无需消耗任何字符)就有可能发声的转换,它可看作是一个空串的“匹配”。

    转换表transition table

    是一个 T(状态,字符) --> 状态 的函数。

    通常用二维数组表示。

    表驱动table driven

    利用表格来引导算法的过程。是转换表的一般化抽象。

    1.定义

    NFA(确定性有穷自动机)M由字母表∑,状态集合S,转换函数T:Sx(∑∪{ε})→P(S)、初始状态_s0_∈S以及接受状态的集合A⊂S组成。由M接受的且写作L(M)被定义为字符c1c2...cn串的集合,其中每个ci∈∑∪{ε},存在状态s1=T(s0,c1),s1=T(s1,c2),...,sn=T(sn-1,cn),其中sn是A(即一个接受状态)的一个元素。

    T转换函数:T的范围是S的幂集。

    与DFA的区别:DFA中,T(Sn,ci) = Sn+1,而NFA中,T(Sn,ci) = {Sn+1,Sn+2,...},即同一个字符可以转换到多个不同的状态分支。

    2.NFA图

    3.表驱动

    C注释的表格结构:

    stateinput character / * other Acceptable
    1 2 no
    2 3 no
    3 3 4 3 no
    4 5 4 3 no
    5 yes

    通常的伪代码描述为:

    T:定义了转换表。

    Advance:先行输入,尝试取下一个字符。

    state = 1;
    ch = readchar(); //读取一个字符
    while (!Accept[state] && !error(state)) 
    {
        int newstate = T[state][ch]; //取得新的状态
        if(Advance[state][ch]) //
        {
           ch = readchar();
        }
        state = newstate;
    }
    
    if(Accept[state]) //接受状态,则做点什么
    {
       ...
    }
    

    总结:

    • 表驱动的方式主要是针对DFA,对于NFA的,由于有很多条路径的选择,如果使用表驱动,则会涉及到回溯,这个会引起效率问题,一般的做法是将NFA转为DFA。

    • 表驱动可能会造成稀疏矩阵,如果使用二维数组的话,有可能需要使用压缩算法等。当然,使用邻接表则忽略空间的浪费。

  • 相关阅读:
    C++探究transform算法
    C++探究foreach算法
    C++ MFC棋牌类小游戏day6
    C++ MFC棋牌类小游戏day5
    C++ MFC棋牌类小游戏day4
    C++ MFC棋牌类小游戏day3
    MFC 字体
    C++ MFC棋牌类小游戏day2
    第三章 使用属性升级MyBank
    第二章 C#语法快速热身
  • 原文地址:https://www.cnblogs.com/pengzhen/p/5837527.html
Copyright © 2020-2023  润新知