实现自己的脚本语言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构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
随机推荐
- error MSB6006: “CL.exe”已退出
解决方案之一: 删除 \Windows\System32 目录下 mspdb110.dll. 试试吧.
- pl/sql编程
body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...
- 系统设计 - 使用面向 iOS 的本机插件扩展
本文转自:http://www.cnblogs.com/zhwl/archive/2013/07/26/3217155.html 本文细致探讨了 Xcode(以 iOS 设备为目标)中的 PhoneG ...
- java.net.ServerSocket和java.net.Socket
个人博客地址:http://www.cnblogs.com/wdfwolf3/ java.net.ServerSocket 1.构造函数 a.ServerSocket() 创建一个无连接的server ...
- React 学习资源分享 菜鸟刚学5天 博客写的不多 不懂写博客的套路
http://www.ruanyifeng.com/blog/2015/03/react.html 首先个人强烈推荐 阮一峰的React基础 细细过一遍,看得出大师的用心良苦 然后就开始看书般的过ht ...
- python 读入
2 3 4 f=open('message1.txt','r') #这个message1.txt文件应该和这个.py的文件放在同一文件夹下 或者是把路径写全 例: f=open('c:/message ...
- SQL Server与Oracle中的隔离级别
在SQL92标准中,事务隔离级别分为四种,分别为:Read Uncommitted.Read Committed.Read Repeatable.Serializable 其中Read Uncommi ...
- Multilingual App Toolkit v2.2 release
Multilingual App Toolkit v2.2 release Today we released Multilingual App Toolkit v2.2. This release ...
- javascript学习代码-判断闰年
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- java 类的加载,链接,初始化
本篇的话题,讨论Java类的加载.链接和初始化.Java字节代码的表现形式是字节数组(byte[]),而Java类在JVM中的表现形式是java.lang.Class类的对象.一个Java类从字节代码 ...