预览:http://jssc.googlecode.com/svn/trunk/jssc5/bin/index.html
下载:http://code.google.com/p/jssc/downloads/list
源码:http://jssc.googlecode.com/svn/trunk/jssc5/src/
好久不动,都生疏了。离上次5.1alpha版有好几个月了,今天释出beta版,添加了Python语法。
之前说过5.1版本最大的变动是使得添加新的语法变得更加容易,老的5.0版每个新语言都得写个词法分析器太累了,于是乎花大精力修改这一部分,添加了“匹配模式”类,用以方便添加新语法解析。
匹配模式的概念
简单地说,匹配模式就是描述某个语言基本词法单元(Token)的规则。以javascript举例,需要高亮的Token大致有注释、字符串、正则表达式、数字、关键字。其中关键字属于Word中的保留字。注释的匹配模式就是以/*开头*/结尾的代码、字符串是指引号之间的内容等等。
现有的几种匹配模式
所有匹配模式都实现IMatch接口,我目前定义了以下几种:CharacterSet、CompleteEqual、LinearSearch、LinearParse、IDMatch、RegularMatch。
CharacterSet 是个字符集匹配,它定义了Token以什么字符集为开头并以什么字符集为组成内容。比如js中的Word是以下划线、美元符号、字母为开头,下划线、美元符号、字母和数字为组成内容。出于初期设计的原因,字符集不能完全自定义,只能使用已经定义的若干常量。这个缺陷会在以后考虑。
CompleteEqual 是最简单的全等匹配,只有完全相等时才会匹配成功。在js中我用全等来查找花括号和圆括号,因为它们要参与计算深度(折叠功能)。
LinearSearch 线性查找,寻找以什么字符串为开头和结尾的内容。js中注释是以此实现的。注释是以/*开头*/结尾、或者//开头行末结尾。
LinearParse 线性分析和线性查找很像,只是它多了判断转义的逻辑,性能稍稍差一些。js中字符串是以此实现的。字符串以引号开始引号结束,但是结尾的引号可能存在转义的情况,字符串中也可能出现转义符,需要特殊对待。
IDMatch ID匹配和线性查找也有点相似,它定义了以什么字符串为开头,然后匹配一个正则表达式结果。js中并没有直接用到,但其实注释部分也可以用它来实现:以//为开头,匹配的正则表达式是//[^\n]*。至于为什么不用ID匹配来实现呢,那是因为正则的消耗比较大,为性能考虑才使用的线性查找。事实上只要是能用线性查找替换的地方,都应该这样做。
RegularMatch 看名字就知道这是终极解决方案了,和IDMatch的差异也只在于定义开头也是个正则。最消耗的方案。我根本没有用到它,放在那里有备无患而已。
ecmascript的示例
以下是用来解析js、as等语言的定义类文件:
package lexer.rule {
/**
* …
* @author army8735
*/
import lexer.*;
import lexer.depth.*;
import lexer.match.*;
public class EcmascriptRule…

本博客所有文章均采用