2008-04-10
JS解析测试代码片段
前一日与jindw聊天,谈到了正在研究的JS代码转换。譬如JSA所作的,其实就是一种代码转换。
PIES为了实现namespace(package)的管理,对JavaScript源代码也进行了处理。为了保证效率,所以想方设法只做了最最简单的预处理,也就是对代码段加头加尾,这样只是简单的字符串串接,对于效率是没有影响的。
但是最近在考虑是否有可能支持一些JS2(ES4)的特性,譬如支持let。这就必然需要将let转换为ES3所支持的某种结构(简单的说,在let语句开始的时候,把let的scope之外的同名变量先压栈,然后到了let的scope之外再恢复出来)。
总之这里就涉及到一种代码的transform或preprocessing。所以我在寻找某种轻型的代码解析方式。为此我先要写一些测试用例。
如果要进行JS代码的parse、transform、预处理、代码生成甚或compile等等,就需要考虑到JS的语法。以下是个很不完整的代码片段,parser、lint、preprocessor、transformer等等都需要能正确处理它,才具有实用价值。
这个代码包含了多行注释、单行注释、字符串、多行字符串(非ES3标准,但各种引擎都支持)、转义字符等等。
这个代码没有包含的,包括正则和e4x。正则literal(如/^r(eg)ex["'\/].*?$/ig)是个很麻烦的事情,比如考虑除法!所以暂时没有放入测试用例中。e4x也是一个麻烦事情,因为涉及了内插XML,暂时不予考虑。
BTW,代码syntax highlight其实也会用到类似的处置,显然JavaEye的syntax highlight还是存在小小的地方不能辨识的,呵呵。
下面是一个正则表达式,可以匹配最常见的造成解析困难的嵌套结构,包括注释和字符串,但是没有包括前面所说的正则和e4x的xml结构。
([\S\s]*?)(?:[*][/]|$)|[/][/](.*)|"((?:\\"|[^"])*)"|'((?:\\'|[^'])*)'/g;
注:如果你看到上面的代码里存在奇怪的东西,那是JavaEye的bbcode解析错误。
通过这个正则,我们可以过滤一般的JS代码(当然正则和e4x除外)。比如可以把注释都删除,把字符串里的特殊字符替换掉等等。我测试了上面那段人造的代码。然后我拿dojo 0.4.3的314KB的源代码做了测试,完成整个过滤在我的T60笔记本上大概需要0.5秒。
不过因为还没有处理正则,所以这个方法还不能用于实用。
PIES为了实现namespace(package)的管理,对JavaScript源代码也进行了处理。为了保证效率,所以想方设法只做了最最简单的预处理,也就是对代码段加头加尾,这样只是简单的字符串串接,对于效率是没有影响的。
但是最近在考虑是否有可能支持一些JS2(ES4)的特性,譬如支持let。这就必然需要将let转换为ES3所支持的某种结构(简单的说,在let语句开始的时候,把let的scope之外的同名变量先压栈,然后到了let的scope之外再恢复出来)。
总之这里就涉及到一种代码的transform或preprocessing。所以我在寻找某种轻型的代码解析方式。为此我先要写一些测试用例。
如果要进行JS代码的parse、transform、预处理、代码生成甚或compile等等,就需要考虑到JS的语法。以下是个很不完整的代码片段,parser、lint、preprocessor、transformer等等都需要能正确处理它,才具有实用价值。
function f(test) {
return (test/*
/* //
' "
{ ;
\*/ && // /* // " ' { ; \
test &&
" /* // \
\" ' \
{ ;" &&
' /* // \
" \' \
{ ;' &&
test);
}
这个代码包含了多行注释、单行注释、字符串、多行字符串(非ES3标准,但各种引擎都支持)、转义字符等等。
这个代码没有包含的,包括正则和e4x。正则literal(如/^r(eg)ex["'\/].*?$/ig)是个很麻烦的事情,比如考虑除法!所以暂时没有放入测试用例中。e4x也是一个麻烦事情,因为涉及了内插XML,暂时不予考虑。
BTW,代码syntax highlight其实也会用到类似的处置,显然JavaEye的syntax highlight还是存在小小的地方不能辨识的,呵呵。
下面是一个正则表达式,可以匹配最常见的造成解析困难的嵌套结构,包括注释和字符串,但是没有包括前面所说的正则和e4x的xml结构。
/[/]
注:如果你看到上面的代码里存在奇怪的东西,那是JavaEye的bbcode解析错误。
通过这个正则,我们可以过滤一般的JS代码(当然正则和e4x除外)。比如可以把注释都删除,把字符串里的特殊字符替换掉等等。我测试了上面那段人造的代码。然后我拿dojo 0.4.3的314KB的源代码做了测试,完成整个过滤在我的T60笔记本上大概需要0.5秒。
不过因为还没有处理正则,所以这个方法还不能用于实用。
- 17:19
- 浏览 (976)
- 评论 (7)
- 分类: JS
- 发布在 javascript研究小组 圈子
- 相关推荐
评论
Army
2008-04-13
唔……发现不少问题呢,以前都没想到过……受教了~慢慢想想去~
hax
2008-04-12
To Army:
jssc2对于引号内的/*会识别为注释,所以我正文中的代码jssc2似乎尚无法正确高亮。jindw应该不会告诉你要分别处理,因为交叉问题是无法分别处理的,必须一揽子解决,或者采用Token解析方式。但是对于高亮这种用途来说,用Tokenizer代价过高,没有必要,恰好适合用我这里所描述的解决方案。代价是,对于少数极端情况会有高亮错误。
jssc2对于引号内的/*会识别为注释,所以我正文中的代码jssc2似乎尚无法正确高亮。jindw应该不会告诉你要分别处理,因为交叉问题是无法分别处理的,必须一揽子解决,或者采用Token解析方式。但是对于高亮这种用途来说,用Tokenizer代价过高,没有必要,恰好适合用我这里所描述的解决方案。代价是,对于少数极端情况会有高亮错误。
Army
2008-04-11
这个jindw曾和我说起过,交叉语法时会有问题,正则、字符串和注释中任意两个相互交叉的话有可能出现高亮错误。
jindw告诉我的是先将它们分开再进行着色,所以我写jssc2的时候就是受到他的启发的~
jindw告诉我的是先将它们分开再进行着色,所以我写jssc2的时候就是受到他的启发的~
hax
2008-04-11
narcissus是一个完整的parser。所以它要用Tokenizer。这样开销还是相当大的。我其实想找一个用正则来做一种折衷处置的方式。
不过经过仔细研究,我发现正则literal是一个理论上难以解决的困境。因为是正则literal还是除法,要根据当时所处的语境(syntactic
grammar contexts)来决定,而不是只依据syntax的。考虑这样一个代码:
注意这里c实际为a/b/g(除法)。如果我检测到/b/g时,要回溯到之前的语境(包括跳过之前的注释)才能决定到底这是一个除法还是正则。这相当困难,因为JS中的正则不支持向前回溯。
不过在实践当中,几乎没有人会写出这样的语句:
- 跨行的除法
- 孤立的正则
所以可以考虑一种稍微严格的做法。目前正在思考中。
不过经过仔细研究,我发现正则literal是一个理论上难以解决的困境。因为是正则literal还是除法,要根据当时所处的语境(syntactic
grammar contexts)来决定,而不是只依据syntax的。考虑这样一个代码:
a = 1 b = 2 g = 1 c = a /* */ /b/g
注意这里c实际为a/b/g(除法)。如果我检测到/b/g时,要回溯到之前的语境(包括跳过之前的注释)才能决定到底这是一个除法还是正则。这相当困难,因为JS中的正则不支持向前回溯。
不过在实践当中,几乎没有人会写出这样的语句:
- 跨行的除法
- 孤立的正则
所以可以考虑一种稍微严格的做法。目前正在思考中。
trydofor
2008-04-11
http://lxr.mozilla.org/mozilla/source/js/narcissus/
Brendan Eich's narcissus, a JavaScript parser written in JavaScript for the Mozilla project.
Brendan Eich's narcissus, a JavaScript parser written in JavaScript for the Mozilla project.
hax
2008-04-10
注,列表符号(以及正文中的<li>)应该是“[ * ]”(不包含空格)
hax
2008-04-10
BTW,在贴这个代码的时候发现一个小bug,即
([\S\s]*?)(?:[*][/]|$)|[/][/](.*)|"((?:\\\\|\\"|[^"])*)"|'((?:\\\\|\\'|[^'])*)'/
存在某种模式的代码,会匹配错误。不知有人能看出来么,呵呵。
/[/]
存在某种模式的代码,会匹配错误。不知有人能看出来么,呵呵。
发表评论
- 浏览: 139368 次
- 性别:

- 来自: 上海

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
一个嵌入式HTML引擎
这个引擎的源码在什么地方可以下阿
-- by lizhaosuper -
注册Facebook的一点点用户 ...
注册验证码确实有点变态。好在只是一次性的。我经常看到一些网站每次留言都要验证码, ...
-- by hax -
注册Facebook的一点点用户 ...
那个注册验证码太强了点
-- by jinhao7773 -
注册Facebook的一点点用户 ...
第一次使用facebook也发现了这点。他的工作很细致。
-- by wutao8818 -
向左转?向右转?
这个论坛有人发过了
-- by lonelyblue






评论排行榜