编译原理-词法分析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注释的表格结构:

state\input 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。

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

编译原理-词法分析04-NFA & 代码实现的更多相关文章

  1. 编译原理-词法分析05-正则表达式到DFA-01

    编译原理-词法分析05-正则表达式到DFA 要经历 正则表达式 --> NFA --> DFA 的过程. 0. 术语 Thompson构造Thompson Construction 利用ε ...

  2. 编译原理词法分析 java简单实现

    package com.csray; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundEx ...

  3. 编译原理-词法分析03-DFA

    0.术语 DFA Deterministic finite automation,确定性有穷自动机.一般用于翻译正则表达式. 状态state DFA中的圆圈,表示模式在识别过程中的位置. 转换tran ...

  4. Atitit.编译原理与概论

    Atitit.编译原理与概论 编译原理 词法分析 Ast构建,语法分析 语意分析 6 数据结构  1. ▪ 记号 2. ▪ 语法树 3. ▪ 符号表 4. ▪ 常数表 5. ▪ 中间代码 1. ▪ 临 ...

  5. 跟vczh看实例学编译原理——二:实现Tinymoe的词法分析

    文章中引用的代码均来自https://github.com/vczh/tinymoe.   实现Tinymoe的第一步自然是一个词法分析器.词法分析其所作的事情很简单,就是把一份代码分割成若干个tok ...

  6. 前端与编译原理 用js去运行js代码 js2run

    # 前端与编译原理 用js去运行js代码 js2run 前端与编译原理似乎相隔甚远,各种热门的框架都学不过来,那能顾及到这么多底层呢,前端开发者们似乎对编译原理的影响仅仅是"抽象语法树&qu ...

  7. 编译原理-NFA构造DFA

    本题摘自北邮的编译原理与技术. 首先,根据此图构造状态转换表 表中第一列第一行表示从第一个符号B通过任意个空转换能到达的节点,Ia表示由此行的状态数组({B,5,1}可以看作0状态)经过一个a可以到达 ...

  8. java动态编译 (java在线执行代码后端实现原理)(二)

    在上一篇java动态编译 (java在线执行代码后端实现原理(一))文章中实现了 字符串编译成字节码,然后通过反射来运行代码的demo.这一篇文章提供一个如何防止死循环的代码占用cpu的问题. 思路: ...

  9. java动态编译 (java在线执行代码后端实现原理)

    需求:要实现一个web网页中输入java代码,然后能知道编译结果以及执行结果 类似于菜鸟java在线工具的效果:https://c.runoob.com/compile/10 刚开始从什么概念都没有到 ...

随机推荐

  1. arcgis engine 监听element的添加、更新和删除事件(使用IMovePointFeedback)

    VB代码: 复制进程序稍作修改变量名和事件逻辑即可使用. Members   AllPropertiesMethodsInheritedNon-inherited Description Displa ...

  2. [Nhibernate]sqlite数据库基本使用

    目录 写在前面 操作步骤 总结 写在前面 昨天有朋友问我在nhibernate中如何使用sqlite数据库,当时实在忙的不可开交,下周要去山西出差,实在没空,按我的说法使用sqlite跟使用sqlse ...

  3. UIScrollView的常见属性

    @property(nonatomic) CGPoint contentOffset; 这个属性用来表示UIScrollView滚动的位置 (其实就是内容左上角与scrollView左上角的间距值) ...

  4. Mongodb profile(慢查询日志)

    在MySQL中,慢查询日志是经常作为我们优化数据库的依据,那在MongoDB中是否有类似的功能呢?答案是肯定的,那就是MongoDB Database Profiler.所以MongoDB 不仅有,而 ...

  5. Ubuntu 14 中,SecureCRT、SecureFX个性化设置

    [SecureCRT 个性化设置] 打开设置路径:菜单栏 -> Opions -> Global Options -> General -> Default Session - ...

  6. Redis学习 - 配置属性:protected-mode

    根据redis的说明,protected-mode在同时存在如下两种情况时触发: 1) The server is not binding explicitly to a set of address ...

  7. eclipse for php现有项目不能导入问题

    1.少了.project文件 解决办法:创建一个新项目,然后将新项目文件夹下的.project文件复制到将要导入的文件夹中.

  8. 通过goto语句学习if...else、switch语句并简单优化

    goto语句在C语言中实现的就是无条件跳转,第二章一上来就介绍goto语句就是要通过goto语句来更加清楚直观的了解控制结构. 我理解的goto语句其实跟switch语句有相似之处,都是进行跳转.不同 ...

  9. C#高级编程笔记 Day 4, 2016年9月 12日(接口)

    1.定义和实现接口:接口名称通常上以字母 I 开头 例子:定义IBankAccount接口 namespace Test.YinXi{ public interface IBankAccount{ v ...

  10. oracle常用脚本

    自动启动oracle sqlplus -S sys/123456 as sysdba <<EOF startup quit EOF lsnrctl start lsnrctl reload