Search code examples
javascriptgrammaroperator-precedencejison

jison rule precedence doesnt work?


I am now sitting multiple hours in front of a problem that seems rather simple to solve but i just cant get behind it :/

I am defining a small javascript-like language in jison. The problem is that the Parameter rule and the AssignStatement rule both (can) start with an CHAR_SEQUENCE and it always chooses the parameter rule. E.g. even though the code is a = 5; it reaches the throw "reached parameter"; so it seems to parse the a as a Parameter instead of a = 5; as an AssignStatement

the relevant part of my grammar:

Parameter
    : InlineVariable
        { $$ = $1; }
    | CHAR_SEQUENCE
        { throw "reached parameter"; checkUndefined($1, @1); $$ = vars[$1]; }
    ;

InlineVariable
    : NUMBER
        { $$ = new Runtime.Integer(parseInt($1)); }
    | '"' CHAR_SEQUENCE '"'
        { $$ = new Runtime.String($2); }
    | FUNCTION '(' ParameterList ')' Statement
        { $$ = new Container($5); }
    ;

AssignStatement
    : CHAR_SEQUENCE AssignmentOperator Parameter ';'
        {
            $$ = function()
            {
                if((typeof vars[$1] == 'undefined' && $3 instanceof Runtime.Integer) || (vars[$1] instanceof Container && $3 instanceof Runtime.Integer))
                    vars[$1] = new Runtime.Integer(0, $1);
                else if(typeof vars[$1] == 'undefined' || (vars[$1] instanceof Container && !($3 instanceof Container)))
                    vars[$1] = $3.constructor.call();

                $2(vars[$1], vars[$3]);
            }
        }
    | CHAR_SEQUENCE SingleAssignmentOperator ';'
        {
            $$ = function()
            {
                if(typeof vars[$1] == 'undefined')
                    vars[$1] = new Runtime.Integer(0, $1);

                $2(vars[$1]);
            };
        }
    ;

I posted the full grammar at https://gist.github.com/M4GNV5/36c2550946c1a1f6ec91

So is there a way to solve this problem? I of course already tried using %left, %right, %assoc and %precedence but it didnt work (or i did something wrong?


Solution

  • You are misunderstanding the flow control in a bottom-up parser.

    Actions are executed when the associated production is reduced (i.e. fully recognized), which won't happen until after all non-terminals in the production have been reduced.

    The AssignmentStatement production is:

    AssignStatement
        : CHAR_SEQUENCE AssignmentOperator Parameter ';'
    

    So before its associated action can be executed, the productions for AssignmentOperator and Parameter must be executed. In this case, Parameter is matching the 5.