2012-04-09 177 views
4

我正在使用Jison構建簡單的計算器語言,其中包含變量。我希望這些變量能夠像JavaScript一樣工作,那就是您必須首次使用關鍵字var進行初始化。用我的語言,如果一個變量重新初始化,我想顯示一個錯誤。如何從AST節點獲取行號(Jison)

var myVar = 4 
var myVar = 3 
// Error, cannot reinitialise variable myVar on line 2 

我的問題是,如何獲取AST節點的行號?在我的語法文件中,我可以將解析器的行號傳遞給我的AssignVariable對象,但我想知道是否有更好的方法來執行此操作?

stmt 
    : 'PRINT' expr 
     { $$ = new yy.Print($2) } 
    | 'VAR' 'IDENTIFIER' 'ASSIGN' expr 
     { $$ = new yy.AssignVariable($2, $4, $3); $$.lineNo = yylineno } 
    | 'IDENTIFIER' 'ASSIGN' expr 
     { $$ = new yy.SetVariable($1, $3, $2) } 
    ; 

我還需要我的編譯器中其他節點的行號用於其他類型的錯誤檢查。

這個問題的更高層次的介紹可能是:使用Jison(或類似的)檢測和處理編譯時錯誤的最佳方法是什麼?

+0

野牛你通常還需要啓用'yyloc',然後通過'@ 1','@ 2'提到他們,等 – leppie 2012-04-09 07:12:16

+0

@leppie能否請您解釋這多一點,這如何影響AST? – Cobby 2012-04-09 08:41:27

回答

5

我能夠通過在編譯器中對生成的解析器進行猴修補,將行號注入到AST節點中。這是扎克提出的。 facepalms

// load in your generated parser 
var parser = require('./parser'); 

// store the current performAction function 
parser._performAction = parser.performAction; 

// override performAction 
parser.performAction = function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { 
    // invoke the original performAction 
    var ret = parser._performAction.call(this, yytext, yyleng, yylineno, yy, yystate, $$, _$); 
    // Do your own stuff 
    if (this.$._type) { 
     this.$.lineNo = yylineno; 
    } 
    return ret; 
}