Question

I'm using Jison to build a simple calculator language, which includes variables. I want these variables to work similar to JavaScript, that is you have to initialise it with the var keyword the first time. In my language, I want to show an error if a variable gets re-initialise.

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

My question is, how do I get the line number for an AST node? In my grammer file, I can pass the line number from the parser to my AssignVariable object, but I'm wondering if there is a better way to do this?

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) }
    ;

I will also need the line number for other nodes in my compiler for other types of error checking.

A more high-level takeaway from this question could be: What's the best way to detect and handle compile time errors using Jison (or similar)?

Was it helpful?

Solution

I was able to inject the line number into my AST nodes by monkey-patching the generated parser in my compiler. This was suggested by Zach. 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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top