Posts Tagged ‘jssc’

http://jssc.googlecode.com/svn/trunk/jssc5/bin/index.html
已经可以看到添加了不少语言了,找翻译可真够受罪的。通过flashvars中传递lang=param来设置语系,比如说:lang=chinese。
还有检测时添加了对textarea节点的检查,最初也是有的,后来为了标准只检测pre节点,现在发现textarea还是有优势的,比如html代码在pre节点中得转义<号,textarea则不需要。控制权还是交给用户为妙。
另外删除了关于按钮,右上角只保留复制功能,协议改成了MIT。github和google code并存:https://github.com/army8735/jssc
最近始终在考虑5.0的结构设计问题,lexer之间父子继承的关系真可谓一坨坨的:

想要添加新语种十分麻烦,因为要实现这个语言的lexer才行。虽说当初设计的两大目的是准确性和速度性能,但是忽略了易配置性,罪过罪过。UNIX上的Lex做得很不错,每种语言用描述自己的规则文件来定义,值得借鉴,这样即使不懂如何实现lexer的人只要通过配置自己所需的语言规则,也能添加语法种类。
下一代的jssc要提炼出一个lexer核心,这样其它地方也能用这个核心,不必重复实现。现在的做法耦合太严重,解析过程和生成html的逻辑死死绑在一起,当然唯一的好处是性能最快。解耦后将略微损失一些性能,但总体时间复杂度还是O(n)的,再加上加入缓冲区的概念,性能不是问题,最终结果得要远远大于失的。
至于版本号么,5.1?5.5?6.0?算了,还是别学chrome了……
最后,昨天看见syntaxhighlighter更新到3.x了,开源竞争激烈啊,不过准确性和速度性还是不能比的。习惯性地祭出js校验代码(前一部分是我编的,后一部分来源于hax),还是没有根本性的改变:
//javascript
var reg = /**//[\/][/][*]([\S\s]*?)(?:[*][/;\[\]]|$)|[\/][/g;//](.*)|”((?:\\\\|\\”|[^"///])*)”|’((?:\\\\|\\’|[^'\//;])*)’/gm; ”; /\d/.test(1);
reg = 12;
reg = 2 / 1 /**///
/**///
/reg/ 1;
var num1 = 0.541;
function f(test) {

十二月 17th, 2010

jssc 5.0.4

2 Comments, jssc, 前端开发, by army.

http://code.google.com/p/jssc/
昨天偶然同学使用发现ie下无法显示,maxthon下却行,很是郁闷。最后发现是object标签上的visibility:hidden导致,真没想到。于是乎连忙修正之,并用compiler压缩js部分的代码,这样整体又稍稍减少了0.2k。
成员中增加了lubin1119,来尝试编写sas的解析,我本人倒是希望加入python的解析,随后便是拖延很久的缓冲式解析方法,用以支持超多行数代码高亮。看来又要变动不少了。

整体流程
终于说到整体流程上了。之前的文章一直在解说as中如何来做词法分析,js方面丝毫未提,更没说jssc到底在页面上是怎么工作的。现在,就来详细地解释一下。
环境需求:

现代浏览器(废话)
装有Adobe Flash Player插件,版本号为9或9以上
javascript启用
页面中放入jssc.swf文件

大致流程:

swf文件载入完毕
内嵌在swf中的js首先被执行,寻找页面中所有符合规则的pre节点
顺序遍历这些pre节点,提取每个pre节点的文本内容(即原始代码)
将原始代码传递给swf
swf对传递来的原始代码进行词法分析,并生成一段结果html片段(即一串li节点)
将结果传递回js
js对结果进行包装(一串li节点放入ol节点中,以及标题头、边距和复制等等)
将对应的原始pre节点隐藏(display:none)
将新生成的内容插入原始pre节点的前面

可以看出,js和as耦合的地方在哪里,以及它们之间是如何相互合作的。下面将对以上9个步骤细细说来,希望更多的开发者能提出改进意见~
1.载入swf
这里没什么好说的,在页面底部加入flash标签即可。值得注意的是不同浏览器中标签有所区别,理想情况下可以使用swfobject来插入标准的html标签。不过为了兼容以及简单,一般我是这样做的:
<object classid=”clsid:d27cdb6e-ae6d-11cf-96b8-444553540000″ id=”jssc5″ style=”position:absolute;visibility:hidden;”>
<param name=”movie” value=”jssc5.swf”/>
<param name=”flashvars” value=”find=brush”/>
<embed src=”jssc5.swf” flashvars=”find=brush” name=”jssc5″ type=”application/x-shockwave-flash” style=”position:absolute;visibility:hidden;”/>
</object>
这里面有许多可配置的地方。
object的id和embed的name必须一致且唯一(应该是唯二才对),为了满足不同浏览器的需要。我设为jssc5,这也是默认值。如果和页面上某个节点有冲突需要修改,那么就需要传入参数修改配置。比如说变成jssc5_modify,就得在flashvars中这样做:
<object classid=”clsid:d27cdb6e-ae6d-11cf-96b8-444553540000″ id=”jssc5_modify” style=”position:absolute;visibility:hidden;”>
<param name=”movie” value=”jssc5.swf”/>
<param…

内嵌解析
很容易遇到这样的情况:在需要高亮的代码中还混淆着其它语言种类的代码(最常见的例子为Html内嵌css和js,以下也将以此为例)。这是一件让人头疼的事情,因为无论采用何种方法,内嵌的语言和原本语言的规则一定是不同的。这意味着必须将它们区分开来对待。从这一点出发,自然而然就能引出问题的关键所在——如何区分?
剥离内容
先来考虑最简单的情况:
<head>
<script>var i = 0;</script>
</head>
假如没有第2行的script标签以及其内部的代码,那么整个就是纯html代码高亮,这个没有什么难度(如果已经完全理解前三篇的此法分析的话)。然而不凑巧的是,关键点就在于script标签中会出现js代码,html的此法分析中并没有js的词法规则,两者不能等同。那么怎么办呢?
答案是将它们剥离出来。上例是最简单的例子,我们在对html进行此法分析的时候,一旦读到了<script>开始标签,接着便去寻找</script>结束标签(一般会使用String.indexOf()来查找),然后将标签里面的内容单独提取出来。这是第一步,如果做完的话,此时html的高亮结果应该是:除了js代码没有高亮(即默认颜色)以外,其它的html代码均被正确高亮了。
更复杂的情况
剥离到此还没有结束,因为剥离要考虑其它一些复杂的元素。看以下代码:
<head>
<script>var i = 0;
//</script>
</script>
</head>
代码的第3行中,出现了单行注释,其中有被注释掉的script结束标签。这点需要格外注意。假若使用String.indexOf()来查询script结束标签的话,那么就会在第3行结束。这样就错了,因为第3行实际上是个注释,真正的结束符在第4行。
以此延伸,除了上面的情况以外,引号中的字符串、多行注释、正则里面均会出现类似情况。因此,单纯的String.indexOf()是肯定不行的。我们必须对js代码部分进行预处理。
预处理
在as的解析部分,实际上主要分为两大块:词法分析和存储结果。词法分析即是前面几篇一直在讲解的内容;存储结果即是将分析出来的代码链接起来,说白了就是简单的字符串拼接。
在html中的js代码可能会出现混淆script结束标签的情况之下,唯一解决的办法就是对js也进行简单的词法分析预处理,但不存储结果。因为分析是“读”,而存储是“写”。写的耗时要比读多多了,而且预处理只是为了防止注释、字符串和正则的混淆,不需要真正地进行解析,实现复杂读也比较低。等完全将js代码从html中剥离后,再交给js解析器来做真正的工作,如此也保证了代码的不重复。
<head>
<script>
var i = 0;
//</script>
“</script>”
/*</script>*/
/[</script>]/
</script>
</head>
html中的预处理,至少要保证能将3到7行的js代码完全剥离出来交给js解析器处理,其它html代码则由本身来完成高亮。
状态区分
接下来的难点可能还是在如何在html解析的时候完成区分上面。在这里,我设置了一个state变量用以标识状态。仔细考虑下html,无非发现它主要有以下几种状态:

html节点:即<>内的tag,还有随之的一些属性内容。如:<img width=”100px”/>。
text节点:文本内容,段落p中最常见到。
css节点:style中的css代码。
script节点:script中的js代码。

在默认最开始的时候,是文本节点。一旦遇到了左尖括号,并且随后跟的是个正确的节点名(<x>绝对不是个正确的节点,所以不能当成节点来处理),那么就进入节点状态来解析;当节点解析完了之后,返回文本状态。css和script节点是个两个特殊的节点,因为在它们的开始标签结束之后,要进行预处理查找结束标签。实际上会做其中的一个,另外一个也就懂了。
值得注意的是,html标签中有单个类型的存在,比如<br/>,它不需要成对出现,甚至可以写成<br>。省略/的又是另外一种自闭合类型。它们在处理起来有点麻烦,特别是涉及到深度折叠的时候。解决的办法也是设置状态变量,标识当前节点属于那种类型,以此来区分判断。
这篇写得可能有点简单,因为的确是比较抽象的东西。我也偷偷懒,相信能做到前章所提的词法分析的情况下,纯理论来读本篇也不是什么难事了。可能直接读我的源代码反而会更容易些。在下一篇当中,我会介绍as和js的交互以及jssc的大概处理流程,它将作为结束篇章。

一月 22nd, 2010

jssc 5.0 beta5

9 Comments, jssc, 前端开发, by army8735.

下载页面:http://code.google.com/p/jssc/downloads/list
源码地址:http://jssc.googlecode.com/svn/trunk/
预览效果:http://army8735.org/wp-content/uploads/jssc/
全部是细节方面的调整。
性能有所略微的提升,体积稍微减少一点,可能整体没啥感觉。因为性能瓶颈主要在两方面:as的分析阶段和js的显示阶段。分析阶段中主要是词法分析阶段和字符串拼接阶段,调整的是词法分析阶段,而这个部分占整体所耗时间不是最多的,所以提升不明显。
接口稍微改了下,具体的看源代码。php由原本的纯php代码变为了内嵌显示方式,像html那样。
这个可能是最后一个beta版了,rc如果放出基本都是针对bug的修补,另外会全面更新wiki的使用方法。
说下5.x系列的计划吧:

首先是增加语言:诸如jsp、ruby、csharp等等。语系的增加不会增加子版本号,如5.1,而是后缀的小版本号——5.0.1。
新特性增加将以子版本号形式出现,譬如5.1版本首先考虑的是缓存输出优化(针对代码行上万的高亮显示)。
也是以前考虑实现而没有实现的特性:自动格式化,这个可能难一点,在以后的计划之内吧。

暂且这么多,有想到新的或者别人的想法再列入计划里。