atitit.自己动手开发编译器and解释器(1) ------词法分析--attilax总结
atitit.自己动手开发编译器and解释器(1) ------词法分析--attilax总结
1. 应用场景:::DSL 大大提升开发效率 1
2. 2. 流程如下::: 词法分析(生成token流) >>>>语法分析(生成ast) >>解释执行... 2
3. 如何进行词法分析?Fsm状态机(自动机) 2
4. 使用状态模式构建FSM (简单,易用。。推荐首选) 2
5. ---代码( 状态模式构建FSM ) 3
6. 词法分析概念 3
6.1. 词法分析(英语:lexical analysis)跟token 4
6.2. 五种token类型 4
7. 其他词法分析方法 5
7.1. switchcase或者ifelse 5
7.2. 状态表 5
7.3. 使用NFA、DFA构建FSM( 专业方法,难度大) 6
7.3.1. DFA的局限 7
8. 参考 7
1. 应用场景:::DSL 大大提升开发效率
为了大大提升开发效率,使用了大量DSL ,就需要实现自己的编译器、解释器了。。
String s = "@QueryAdptr(sqlwhere=\" clo1='@p' \",prop2=\"v2\") @Nofilt";
// 创建环境
所以,要解析注解...
网上马,,子能嘎自实现兰....
要是java 源码中的注解能使用java api读取了...
html中的注解嘎自实现兰.
作者:: 老哇的爪子 Attilax 艾龙, EMAIL:1466519819@qq.com
转载请注明来源: http://blog.csdn.net/attilax
2. 2. 流程如下::: 词法分析(生成token流) >>>>语法分析(生成ast) >>解释执行...
3. 如何进行词法分析?Fsm状态机(自动机)
A: 一种很简单的思路就是,用一个状态保存在处理到各个字符时的状态,比如是标识符或者数字或者空格等等,直到状态改变到可以认定是不同token的时候结束。
可以肯定的是,必然要对需要处理的数据挨个字符判断,然后在恰当的位置截断,得到一个个的token.
这里的核心在于将不同符号对应的字符给区别开,在一个字符无法表达此符号时将它截断,token形成。
4. 使用状态模式构建FSM (简单,易用。。推荐首选)
这种模式使用代码实现fsm 简单,易用。。推荐首选
使用这种方法,attilax初次实现词法分析,也只用一天时间
5. ---代码( 状态模式构建FSM )
public static List getTokenList() {
String s = "@QueryAdptr(sqlwhere=\" clo1='@p' \",prop2=\"v2\") @Nofilt";
s="@qu(at1=\"v1\" , at2 = \" v2 abc \",at3=\"v3\" ) ";
// 创建环境
AnnoPaserContext context = new AnnoPaserContext();
// 将状态设置到环境中
// 创建状态
context.setState(new iniState());
int n=0;
while(!( context.state instanceof FinishState))
{
// System.out.println(n);
// 请求
context.request(s);
n++;
if(n>200)
break;
}
for (Token tk : context.tokenList) {
//if(tk.value.trim().length()>0)
System.out.println(tk.value+"");
}
return (List) context.tokenList;
}
6. 词法分析概念
6.1. 词法分析(英语:lexical analysis)跟token
这里的单词是一个字符串,是构成源代码的最小单位。从输入字符流中生成单词的过程叫作单词化(Tokenization),在这个过程中,词法分析器还会对单词进行分类。
词法分析器通常不会关心单词之间的关系(属于语法分析的范畴),举例来说:词法分析器能够将括号识别为单词,但并不保证括号是否匹配。
6.2. 五种token类型
下面就是上述单词的正则表达式定义。
类型 |
正则表达式 |
例子 |
关键字string |
string |
string |
标识符(变量名) |
[a-z][a-z0-9]* |
str |
等号 |
= |
= |
字符串字面常量 |
"[^"]*" |
"hello world" |
分号 |
; |
; |
接下来的问题是,怎么用正则表达式表示的规则来进行词法分析呢?正则表达式利于我们理解单词的规则,但并不能拿来直接解析字符串。为此我们要引入有穷自动机的概念来真正处理输入字符串。
7. 其他词法分析方法
7.1. switchcase或者ifelse
这无意是最直观的方式,使用一堆条件判断,会编程的人都可以做到,对简单小巧的状态机来说最合适,但是毫无疑问,这样的方式比较原始,对庞大的状态机难以维护。
但checkStateChange()和performStateChange()这两个函数本身依然会在面对很复杂的状态机时,内部逻辑变得异常臃肿,甚至可能是难以实现。
在很长一段时期内,使用switch语 句一直是实现有限状态机的唯一方法,甚至像编译器这样复杂的软件系统,大部分也都直接采用这种实现方式。但 之后随着状态机应用的逐渐深入,构造出来的状态 机越来越复杂,这种方法也开始面临各种严峻的考验,其中最令人头痛的是如果状态机中的状态非常多,或者状 态之间的转换关系异常复杂,那么简单地使用switch语句构造出来的状态机将是不可维护的。
7.2. 状态表
,介绍了正则表达式、正则语言和DFA等工具。今次我们要开始涉及编译器前端最重要的阶段——语法分析。简单而言,这一步就要完整地分析整个编程语言的语法结构。上回说到词法分析的结果是将输入的字符串分解成一个个的单词流,也就是诸如关键字、标识符这样有特定意义的单词
7.3. 使用NFA、DFA构建FSM( 专业方法,难度大)
DFA实际上就是高级版的状态表
使用DFA的方法完成的可配置词法分析器的性能是相当好
一般来说,比较高性能的DFA的实现是一张二维的表。行代表字符,列代表DFA 的状态,单元格代表该状态经输入某个字符之后进行转移的目标状态。此外还有一张表用来记录哪些状态对应哪些规则的结束状态
确定有限自动机(英语:deterministic finite automaton, DFA)是一个能实现状态转移的自动机。对于一个给定的属于该自动机的状态和一个属于该自动机字母表的字符,它都能根据事先给定的转移函数转移到下一个状态(这个状态可以是先前那个状态)
这种模型就叫做有穷自动机(finite automation,FA),有时也叫有穷状态机(finite state machine)。
,还有一种非确定性有穷自动机(NFA),
string1 = null; 这句代码中的string1是一个标识符,代表一个变量。如果词法扫描器刚刚扫描到string,就报告发现了“关键字string”,那这里逻辑就不对 了。而如果等到DFA状态抓换到停机状态时再判断,就能判断到最长可能的的单词。比如,当词法分析器分析到了string时,它仍然没有停机,于是就输入 了下一个字符"1",这时词法分析的状态就从接受“关键字string”的状态转换到接受“标识符”的状态;然后词法分析器发现下一个字符是空格,而空格 接在string1后面并不是任何合法的单词,所以它就会转到停机状态。最后我们判断停机前最后一个状态是接受“标识符”的状态,于是报告成功扫描标识符 string1。这样就实现了最长匹配的目的。
先来看miniSharp的词法分析。miniSharp语言的单词根据优先级和不同种类可以分成以下五类:
1. 关键字
2. 标识符
3. 整型数字常量
4. 各种标点符号
5. 空白符、换行符和注释
必须识别为保留字,标识符(变量),常量,操作符(运算符 )和界符五大类 2
我们现在需要寻找一种可以描述token类型的工具,在此之前我们首先研究一下常见的记号的结构。为了表示出具有某种共性的字符串的集合,我们需要书写出一些能代表字符串集合的规则。这个集合中的所有成员都将被认为是一种特定类型的记号。
,直接使用正则表达式进行匹配配的话,不仅工作量大,而且速度缓慢。因此我们还需要另外一种专门为机器设计的表达方式。本文在以后的章节中会给出 一种算法把正则表达式转换为机器可以阅读的形式,就是这一章节所描述的有穷状态自动机。
从正则表达式到ε-NFA
7.3.1. DFA的局限
DFA是一種实际的计算模型,因为有平凡的线性时间、恒定空间的在线算法模拟在输入流上的DFA。给定两个DFA有有效算法找到识别它们所识别语言的并集、交集和补集的DFA。还有有效算法确定一个DFA是否接受任何给定字符串,一个DFA是否接受所有字符串,两个DFA是否识别同样的语言,和对特定正则语言找到状态数目最小的DFA(最小DFA)。
在另一方面,DFA在可识别的语言上有严格的限制—很多简单的语言,包括需要多于恒定空间来解决的任何问题,不能被DFA识别。经典的DFA不能识别的简单语言的例子是括号语言,就是由正确配对的括号组成的语言,比如 (()())。由形如anbn的字符串组成的语言,就是有限数目个a,随后是相等数目个b。可以证明没有DFA有足够状态来识别这种语言(通俗地说,因为需要至少2n个状态,而n是不恒定的)。
8. 参考
NFA_DFA算法 - 于公摊的杂货铺 - 博客频道 - CSDN.NET.htm
自己动手开发编译器(二)正则语言和正则表达式 - 装配脑袋 - 博客园.htm
Atitit. 有限状态机 fsm 状态模式 - attilax的专栏 - 博客频道 - CSDN.NET.htm
atitit.词法分析的实现token attilax总结 - attilax的专栏 - 博客频道 - CSDN.NET.htm
Atitit.注解解析(1)---------词法分析 attilax总结 java .net - attilax的专栏 - 博客频道 - CSDN.NET.htm
atitit.自己动手开发编译器and解释器(1) ------词法分析--attilax总结相关推荐
- 自己动手开发编译器(我们的朋友 -- 装配脑袋走了)
编者: 昨天在微信群里得知 我们的朋友--装配脑袋(施凡老师),因白血病离我们而去,自从得病以来,施老师在积极的接受治疗,8.27 得到的消息还是比较让人开心的,大家都在期待着他能够重出江湖.装配脑袋 ...
- 自己动手开发编译器(十)miniSharp语法分析器
经过前面四篇的铺垫,我们终于拥有了编写语法分析器的强大工具,现在可以正式开发一门编程语言的语法分析器了.我们先来定义miniSharp的语法规则,然后根据LL文法的特点进行一些调整,最后借助解析器组合 ...
- 自己动手开发编译器特别篇——用词法分析器解决背诵圣经问题
这几天比较忙,让大家久等了.但是我语法分析篇还需要一些准备,所以今天带来一个特别娱乐项目.其实也正好想多举一些例子,介绍VBF.Compilers.Scanner库的使用方法.今天的问题来自于一道腾讯 ...
- 自己动手开发编译器(四)利用DFA转换表建立扫描器
上回我们介绍了两种有穷自动机模型--确定性有穷自动机DFA和非确定性有穷自动机,以及从正则表达式经过NFA最终转化为DFA的算法.有些同学表示还是难以理解NFA到底怎么转化为DFA.所以本篇开头时我想 ...
- 斯坦福大学CS143编译原理课程笔记:1.编译器与解释器简介
目录 前言 第一节课:编译器与解释器简介 线上与线下的概念 线上 线下 编译器与解释器的区别 编译器 解释器 FORTRAN 1结构 它包含五个阶段 1.词法 分析 2.语法解析 3.语义分析 4.优 ...
- 学了编译原理能否用 Java 写一个编译器或解释器?
16 个回答 默认排序 RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...
- 《编译与反编译技术实战》——2.1节编译器、解释器及其工作方式
本节书摘来自华章社区<编译与反编译技术实战>一书中的第2章,第2.1节编译器.解释器及其工作方式,作者刘晓楠 陶红伟 岳 峰 戴超,更多章节内容可以访问云栖社区"华章社区&quo ...
- python各个解释器的用途-11 个优秀的 Python 编译器和解释器
Python 是一门对初学者友好的编程语言,是一种多用途的.解释性的和面向对象的高级语言. 它拥有非常小的程序集,非常易于学习.阅读和维护.其解释器可在Windows.Linux 和 Mac OS 等 ...
- 《编译与反编译技术》——第一章 引论 1.1节编译器与解释器
本节书摘来自华章出版社<编译与反编译技术>一书中的第1章,第1.1节,作者庞建民,陶红伟,刘晓楠,岳峰.更多章节内容可以访问云栖社区"华章计算机"公众号查看. 人类之间 ...
- Atitit. 提升软件开发效率and 开发质量---java 实现dsl 4gl 的本质and 精髓 O725
Atitit. 提升软件开发效率and 开发质量---java 实现dsl 4gl 的本质and 精髓 O725 1. DSL主要分为三类:外部DSL.内部DSL,以及语言工作台. 1 2. DSL ...
最新文章
- 织梦引用html,html直接引用vue和element-ui的方法
- 用SSDT方法恢复冒险岛的部分函数
- powerbi视觉对象_玩转Power BI的图片可视化
- delphi query 存储为dbf_Delphi 代码审计项目实战 1
- opencv读取usb摄像头_2020 款 11寸 iPad Pro 深度摄像头 RGBD 视频流可视化
- 布隆过滤器速度_高并发系统一定要考虑的 Bloom Filter 布隆过滤器
- 初始化中断按键(2440)
- Nginx基础和原理介绍
- GitHub 热榜:不用 PS,一键去除照片中的对象,这个神器可试玩
- Vmware下安装配置HMC
- 阿尔伯塔大学 计算机科学,阿尔伯塔大学
- linux c 读取.bin文件
- batch size设置技巧
- 7.2 MVC 实现登录验证
- 上海汇珏EPON典型应用分析
- 搜索引擎网站收录提交入口
- 本体推理中jess和jena区别
- 【视频直播场景下P2P对等网技术②】任意两节点的联通性能评估
- 关于 数据对接入库失败后的 补录机制的一些想法
- Vue.js 2.0 渐进开发应用实践
热门文章
- server2012卸载oracle,Windows Server 2008 R2卸载干净ORACLE 11G
- Thymeleaf 模板 js和css引入的方式
- OpenCV 与 OpenGL 的关系是什么?
- jsp+servlet实现模糊查询和分页效果
- window7 右键菜单显示-》在此处打开命令窗口
- 传说中的“猴年马月”就要来了,感觉很多愿望都要实现啦!
- 非聚集索引的注意事项
- MEF 编程指南(二):定义可组合部件和契约
- libuv 与 libev 的对比
- python 3模块导入(import)问题一则