实现自己的脚本语言ngscript之一:词法分析
正则表达式的理论基础可以参考装配脑袋的
如果学过编译原理的课程就更好了。
词法分析用到了我写的一个工具lexeroid。
下面说一些我写lexeroid时候遇到的问题。
Unicode
在 装配脑袋 的 自己动手开发编译器(四)利用DFA转换表建立扫描器 中,提到了等价类处理Unicode的方法。
我做了一些改进。
首先我把DFA Edge的输入改了,不再是一个char这种,而是一个Input类,它接受空(epsilon)或者begin和end范围(左闭右开区间)内的char。
然后我就可以把char1写成这样
public static NFA char1() {
return Re.range(0, 131072);
}
然后就支持中文了……
而定义regex时冲突的部分,比如定义了一个'a'-'z'的Input和一个'g'的Input在同一个Vertex上,会有一个reduce函数把'a'-'z'分离成'a'-'f'和'h'-'z'。
最长匹配
这个很多书上应该介绍过,就是设置一个lastFinal一样的东西,然后在DFA停机的时候把最后一个正确匹配的取出来。
NFA的组织
最开始我做的是把每个token的NFA分开,存成一个数组,然后每个生成DFA之后,在词法分析的时候一个一个去测试。后来发现这个似乎和用Java内置的正则表达式没什么区别。而且有一个问题是,token定义的顺序要十分小心,因为先定义的token会被优先匹配到。
后来我试了另外一种方法,就是等所有token生成NFA完之后,添加一个入口,用epsilon边把所有的NFA连起来形成一个大NFA,然后再用它生成的DFA去匹配。
最后
lexeroid定义token时大概是这个样子
LexerBuilder builder = new LexerBuilder();
builder.defineToken("if", Re.string("if"));
builder.defineToken("return", Re.string("return"));
builder.defineToken("else", Re.string("else"));
builder.defineToken("ident", Re.concat(
Re.or(Re.letter(), Re.chr('_')),
Re.many(Re.or(Re.or(Re.letter(), Re.chr('_')), Re.digit()))
));
builder.defineToken("string",
Re.concat(Re.chr('"'), Re.many(Re.char1()), Re.chr('"'))
); //此处省略N行
return builder.build();
代码可以从这里找到
https://github.com/wssccc/lexeroid.git
作为一个词法分析器,后面的文章中还会用到它。
相关资料
实现自己的脚本语言ngscript之一:词法分析的更多相关文章
- 实现自己的脚本语言ngscript之零
正式开始介绍前先扯点没用的. 从小玩basic长大的小朋友大多有一个梦想,就是自己实现一个basic解释器. 不过这里我实现的不是basic,而是一个语法和功能类似javascript的东西. 暂且称 ...
- 实现自己的脚本语言ngscript之三:语法设计
这是第四篇了,之所以隔了这么久才写,一方面是因为最近开始实习了,另一方面是因为设计语法真是要考虑很多东西. 于是我去读了这本书,里面实现了两种语言,一种跟js差不多语法,用ast解释执行:另一种语法类 ...
- 实现自己的脚本语言ngscript之四:代码生成
最近的进度 ngscript测试代码 function c1(a, b, c, d) { this.a = 1; this.b = new array(); this.b[0] = 1; this.b ...
- 实现自己的脚本语言ngscript之二:语法分析
ngscript的语法分析使用的是我自己的语法分析工具parseroid.与常用cc工具(yacc.bison.javacc.antlr.etc…)不同的是,parseroid生成的不是语法分析器的源 ...
- 脚本语言:Xmas(三)
自从将Xmas的GC换成现在的非迁移式的全局收集器后,最近几个月一直耗在Xmas上面:最明显的改变就是:更彻底地支持了面向对象.更强大的编译器. 所以,本文就来说说,真正的Xmas. 一.目标 一门语 ...
- 用PHP写一个最简单的解释器Part4(写一个最简单的脚本语言)
好吧!我承认我想标题党了.大家对解释器的吸引,绝对没有自己动手写一个脚本语言更有吸引力.不过如果看到标题过来的,可能也是 我承认,之前收藏的减肥视频,我都是这样对待他们的. 不过我还是相信很多程序猿o ...
- InstallShield 脚本语言学习笔记
InstallShield脚本语言是类似C语言,利用InstallShield的向导或模板都可以生成基本的脚本程序框架,可以在此基础上按自己的意愿进行修改和添加. 一.基本语法规则 ...
- JS脚本语言是什么意思?
javascript,Javascript是一种浏览器端的脚本语言,用来在网页客户端处理与用户的交互,以及实现页面特效.比如提交表单前先验证数据合法性,减少服务器错误和压力.根据客户操作,给出一些提升 ...
- 使用Lua脚本语言开发出高扩展性的系统,AgileEAS.NET SOA中间件Lua脚本引擎介绍
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
随机推荐
- a-b(高精度)
我现在已经是才语言中的一员了,我在此献上今日的佳作——a-b(高精度),以下是我的程序及其注释,欢迎各位来观赏,耶! 程序: #include<stdio.h> #include<s ...
- Sizzle引擎执行的流程图
Sizzle有太多都不是太懂,但能看懂这张图. 图片来源: http://www.cnblogs.com/aaronjs/p/3332805.html
- 开启 htaccess 配置
是在wamp中,apache2.2 开启 伪静态时,httpd.conf 配置如下: 查找 <Directory />Options FollowSymLinksAllowOverride ...
- sharepoint的webpart开发
前言 以前没有接触sharepoint感觉这东西好陌生,只是知道.来公司这段时间,也没有参加开发.今天自己简单的实现了一下这个开发过程,webpart部分的. 过程 其实webpart可以理解为一个放 ...
- Android Handler、Lopper消息驱动机制
Android应用程序是通过消息来驱动的,系统为每一个应用程序维护一个消息队例(MesageQueue),应用程序的主线程不断地从这个消息队例中获取消息(Mesage),然后对这些消息进行处理(Han ...
- Delphi 停靠技术的应用
一.基础知识介绍 1.VCL组件的基础知识 在TWinControl类中有一个DockSite属性(boolean),它的作用是是否允许别的控件停靠在它的上面:在TControl类中有一个DragKi ...
- JavaScript 自定义单元测试
<!doctype html> <html> <head> <meta charset="utf-8"> <script> ...
- bcov进行覆盖率统计
kcov是在bcov基础上进行的,bcov已经很久没有维护了: 首先需要下载依赖库libdwraft,然后在configure时候进行指定: ./configure --with-libdwarf=/ ...
- URL encode 与 URL decode 的C语言实现
转载自:http://blog.csdn.net/langeldep/article/details/6264058 本文代码为从PHP代码中修改而来,只保留了2个函数. int php_url_de ...
- EQueue 2.3.2
EQueue 2.3.2版本发布(支持高可用) 前言 前段时间针对EQueue的完善终于告一段落了,实在值得庆祝,自己的付出和坚持总算有了成果.这次新版本主要为EQueue实现了集群功能,基本实现了B ...