|
我一直在為Jscex尋找好用的JavaScript解析器,之前我用的是Narcissus,也寫過相關(guān)文章。不過可惜的是,Narcissus使用了SpiderMonkey的擴(kuò)展,因此它并不是用ECMAScript 3實現(xiàn)的,無法在IE 8等瀏覽器中使用。目前Jscex使用的是NarrativeJS中舊版的Narcissus,但是我并不喜歡它輸出的AST結(jié)構(gòu),使用中也發(fā)現(xiàn)高級功能里的一些bug,有些食之無味棄之可惜的感覺,而改寫新版Narcissus又必須大動干戈。最近我接觸到了UglifyJS,發(fā)現(xiàn)它的解析器相當(dāng)不錯,性能也比Narcissus高出許多,在此介紹給大家。
介紹
UglifyJS是個JavaScript壓縮器,效果和Google Closure Compiler相比有過之而無不及。對于現(xiàn)代化的JavaScript壓縮器來說,簡單的去除空白和壓縮局部變量是遠(yuǎn)遠(yuǎn)不夠的,同時需要理解代碼的語義,將其替換成提及更小的形式(Uglify的說明頁上有許多描述)。這顯然需要一個JavaScript解析器。UglifyJS基于NodeJS開發(fā),不過可以在各種支持CommonJS模塊系統(tǒng)的JavaScript引擎/平臺上運(yùn)行。如果沒有CommonJS,也只需將exports相關(guān)的代碼去掉即可。
JavaScript解析器的作用自然是將JavaScript代碼分解成AST,然后根據(jù)AST便可以做到許多有趣的事情。相同的AST可以在內(nèi)存中有不同的表現(xiàn)形式,例如之前提到我不太喜歡Jscex目前使用的舊版Narcissus,一個重要的原因便是它的AST結(jié)構(gòu)不夠友好(最新的Narcissus倒不錯)。此外,雖然它提供了一些高級功能,例如標(biāo)注了每個元素在源代碼中的位置,這樣使用者就可以直接根據(jù)getSource方法獲得它對應(yīng)的源代碼——只可惜經(jīng)試驗這個功能有bug,這迫使我還得遍歷完整的AST。
UglifyJS的JavaScript分詞器和解析器存放在源代碼的parse-js.js文件中,移植于parse-js項目,后者是一個用Common Lisp實現(xiàn)的類庫。現(xiàn)在您應(yīng)該可以猜到它輸出的AST是什么表現(xiàn)形式了吧。沒錯,就是個“表”,用JavaScript來表示,就是個數(shù)組套數(shù)組。我寫了點簡單的代碼對其進(jìn)行格式化輸出,您可以在這里簡單嘗試一下UglifyJS的解析器。這個輸出雖然簡單,但對于Jscex來說也已經(jīng)完全夠用了。
使用
打開parse-js.js文件,您會看到這樣一些代碼:
/* -----[ Tokenizer (constants) ]----- */var KEYWORDS = array_to_hash([
...
]);
var RESERVED_WORDS = array_to_hash([
...
]);
...
function parse($TEXT, exigent_mode, embed_tokens) {
...
}
/* -----[ Exports ]----- */
exports.tokenizer = tokenizer;
exports.parse = parse;
exports.slice = slice;
exports.curry = curry;
exports.member = member;
exports.array_to_hash = array_to_hash;
exports.PRECEDENCE = PRECEDENCE;
exports.KEYWORDS_ATOM = KEYWORDS_ATOM;
exports.RESERVED_WORDS = RESERVED_WORDS;
exports.KEYWORDS = KEYWORDS;
exports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN;
exports.OPERATORS = OPERATORS;
exports.is_alphanumeric_char = is_alphanumeric_char;
exports.set_logger = function(logger) {
warn = logger;
};
it知識庫:UglifyJS有個不錯的JavaScript解析器,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。