如何从AST节点获取行号(Jison)

Cob*_*bby 4 programming-languages bison jison

我正在使用Jison构建一个简单的计算器语言,其中包含变量.我希望这些变量与JavaScript类似,即您必须var首次使用关键字对其进行初始化.在我的语言中,如果变量重新初始化,我想显示错误.

var myVar = 4
var myVar = 3
// Error, cannot reinitialise variable myVar on line 2
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何获取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) }
    ;
Run Code Online (Sandbox Code Playgroud)

我还需要编译器中其他节点的行号用于其他类型的错误检查.

从这个问题中得到的更高级别的内容可能是:使用Jison(或类似版本)检测和处理编译时错误的最佳方法是什么?

Cob*_*bby 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;
}
Run Code Online (Sandbox Code Playgroud)