事后總結(jié)予颤,通過今天的代碼學到的:
- 鞏固了對責任鏈模式的認識囤官。
- 實際寫了一個生成AST的類:對于處理不同類型的節(jié)點要有不同的方法。
上一次既然已經(jīng)可以通過詞法分析器獲得token了蛤虐,今天打算用這些token生成一個抽象語法樹党饮,也就是AST。AST的根節(jié)點格式是這樣的:
{
"type": "Program",
"body": [這里面是樹的分支]
}
這個格式不是我信口胡謅的驳庭,看了幾個編譯原理相關的書刑顺,他們的根節(jié)點都是這個格式,在線js語法編譯器編譯出來的也是這個格式:在線編譯器生成出來的例子饲常。
因為之前的詞法分析器只能分析出一個單獨的數(shù)字蹲堂,比如是42。需要一提的是不皆,像42這種數(shù)字贯城,或者"hello"這種字符串,節(jié)點的type都是Literal霹娄。Literal的英文意思是:準確的能犯。大概意思就是這種字面量寫出來是啥那就是啥。所以這次試圖生成的目標AST結(jié)構(gòu)應該是這樣:
{
"type": "Program",
"body":{
"type":"Literal",
"value":42
}
}
為了生成這么一個樹犬耻,需要一個ASTBuilder對象踩晶。這個對象有一個ast方法,用于生成樹枕磁。
function ASTBuilder(){
}
ASTBuilder.prototype.ast=function(){
}
如何組合Lexer和ASTBuilder這兩個類渡蜻,之前是想讓ASTBuilder接收一個tokns數(shù)組作為參數(shù),然后運行ast方法计济。但是這樣的話感覺太面向過程了茸苇。所以借鑒了責任鏈設計模式,讓ASTBuilder接收一個Lexer對象作為參數(shù)沦寂,形象點說就是:ASTBuilder對象身上有一個插槽学密,插著一個Lexer,當我按下ASTBuilder的ast按鈕時传藏,ASTBuilder會調(diào)用自己插槽上的Lexer來分析一個表達式腻暮,代碼是這樣的:
function ASTBuilder(lexer){
this.lexer=lexer;
}
ASTBuilder.prototype.ast=function(expression){
}
因為AST的節(jié)點有很多種,所以要用不同的方法來生成不同類型的節(jié)點毯侦,比如哭靖,根節(jié)點用program方法生成,常量型節(jié)點用constant方法生成侈离。
function ASTBuilder(lexer){
this.lexer=lexer;
}
ASTBuilder.Program="program";
ASTBuilder.Literal="Literal";
ASTBuilder.prototype.ast=function(expression){
this.tokens = this.lexer.lex(expression);
return this.program();
}
ASTBuilder.prototype.program=function(){
return {
type:ASTBuilder.Program,
body:this.constant()
}
}
ASTBuilder.prototype.constant = function () {
return {
type:ASTBuilder.Literal,
value:this.tokens[0].value
}
};
這樣就足夠產(chǎn)生一個最簡單的抽象語法樹了试幽。不過現(xiàn)在很明顯的問題是ASTBuilder.prototype.constant
這個方法返回的是一個寫死的值value:this.tokens[0].value
。不過這個先不考慮霍狰,現(xiàn)在的目標是寫一個完整的流程出來抡草。等以后慢慢迭代饰及。
現(xiàn)在看一下測試案例能否通過:
describe('AST構(gòu)建類',function(){
it('ASTBuilder函數(shù)存在',function(){
expect(ASTBuilder).toBeDefined();
})
it('可以生成一個符合預期的AST',function(){
var lexer = new Lexer();
var astBuilder= new ASTBuilder(lexer);
var ast = astBuilder.ast('42');
expect(ast.type).toBe('program');
expect(ast.body.value).toBe(42);
})
})
測試結(jié)果通過。美滋滋康震。
感悟:這兩天從0開始寫這個框架燎含,自己動腦動手,感覺對很多東西都有了新的認識腿短,看來寫程序真的是要勤動手屏箍,光看書是不夠的。寫程序就像健身橘忱,要保持經(jīng)常寫赴魁,經(jīng)常想,堅持久了钝诚,水平自然就上來了颖御。