实现自己的脚本语言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构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
随机推荐
- SQL2008安装提示"Microsoft visual studio 2008早期之前的版本"解决(这是我认为最简单有效的方法)
作者:冰封 日期:2013-10-18 原文地址:http://www.skywj.com/thread-9230-1-1.html 在安装SQL Server的时候提示 Microsoft visu ...
- ios专题 - 单例模式的实现
[原创]http://www.cnblogs.com/luoguoqiang1985 单例模式是什么? 一个类只有一个实例. ----------------------- 这样做有什么好处? 在我的 ...
- jquery自适应布局
代码整理 - uix.layout.js /** * Grace [jQuery.js] * * UIX页面布局 * 290353142@qq.com * exp: * $.uix.layout(); ...
- LuaNode 开源库
受CJSON库的启发,用C++实现解析Lua文件的库. 整个库大概800行代码,因为新鲜出炉,所以有些潜在问题尚未发现. 截图中包含使用例子. 以下接口清单: LuaNode(); LuaNode(c ...
- ACM YTU 2018 母牛的故事
母牛的故事 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- php中如何实现网上商城用户历史浏览记录的代码
/如是COOKIE 里面不为空,则往里面增加一个商品ID if (!empty($_COOKIE['SHOP']['history'])){ //取得COOKIE里面的值,并用逗号把它切割成一个数组 ...
- XML&DTD&XML Schema学习
XML(eXtensible Markup Language)可扩展的标记语言.xml在web service编程中尤为重要.在网络传输中可以作为传输数据的载体.xml作为元语言,它可以用来标记数据. ...
- Java之网络请求工具类(依赖:org.apache.http;注:HttpClient 4.4,HttpCore 4.4)
到此处可以去下载依赖包:http://hc.apache.org/downloads.cgi import java.util.List; import org.apache.http.HttpSta ...
- Fizz Buzz
class Solution { public: /** * param n: As description. * return: A list of strings. */ vector<st ...
- java.lang.UnsupportedClassVersionError(Unsupported major.minor version 49.0)报错
报错截图如下: