实现自己的脚本语言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构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
随机推荐
- oracle插入数据报错ORA-26026
今天进行数据清理时发现报错ORA-26026,主要是把从交易库提取数据并插入到归档库中. 检查一下发现是归档库的索引问题. 当时为了提高插入速度,所以删除了归档库的索引,可能对主键索引产生了影响. 解 ...
- java中关于static的小知识
static能够修饰属性和方法.凡是static修饰的方法和属性都是和类的关系较大,都在加载的时候要特殊处理(包括属性和类的优先加载).下面比较下static修饰属性和方法时的区别: 一.修饰属性的时 ...
- php验证码封装
/** * 生成验证码 * @param int $type 1: 纯数字,2:纯字母,3:数字与字母混合 * @param int $length * @return string */funct ...
- windows上SVN服务器以及客户端TortoiseSVN的安装配置
(1)svn的安装 1. 下载软件:Setup-Subversion-1.7.5.msi,安装就很容易了,一路NEXT 2. 把SVN的bin文件夹路径添加到环境变量中 把svn安装目录下的bin路径 ...
- centos 6.5 openfire安装
1.下载:http://igniterealtime.org/downloads/download-landing.jsp?file=openfire/openfire-3.9.3-1.i386.rp ...
- 如何便携使用github
Git是一个分布式的版本控制系统,最初由Linus Torvalds编写,用作Linux内核代码的管理.在推出后,Git在其它项目中也取得了很大成功,尤其是在Ruby社区中.目前,包括Rubinius ...
- Yeoman安装
Yeoman帮助我们创建项目,提供更好的工具来使我们的项目更多样化. Yeoman提供generator系统,一个generator是一个插件,在我们在一个完整的项目上使用‘yo’命令时,会运行该ge ...
- PHP的类自动加载机制
在PHP开发过程中,如果希望从外部引入一个class,通常会使用include和require方法,去把定义这个class的文件包含进来. 这个在小规模开发的时候,没什么大问题.但在大型的开发项目中, ...
- 【python】由一个小例子看出python的灵活性,IF ELSE一例
temp = input("请输入1到100之间的数字:") num = int(temp) if 1 <= num <= 100: ...
- 关于script,first,second,third=argv运行出错的问题
from sys import argv input(argv) #python自带的IDLE直接执行不能提供命令行参数 script,first,second,third=argv print(&q ...