Question

I'm trying to modify this "Calculator" Jison example to be an expression parser rather than an expression interpreter. I want to output a JSON object that describes the expression instead of immediately evaluating it.

  • I attempted to modify the demo to return javascript arrays with the operators and operands as elements.
  • When I Parse 1 + 2, I expect to get a JSON array that stringifies to ['+', 1, 2]. Instead I get 1.
  • This seems to be directly related to the NUMBER action - whatever I tell that to return is all I get back.
  • However, if I attempt to parse `1 2 + 3' it does give a syntax error.

(I'm not concerned about whether I'm representing the expression in a useful AST model, I'm just trying to learn Jison)

/* description: Parses mathematical expressions. */

/* lexical grammar */
%lex
%%

\s+                   /* skip whitespace */
[0-9]+("."[0-9]+)?\b  return 'NUMBER'
"*"                   return '*'
"/"                   return '/'
"-"                   return '-'
"+"                   return '+'
"^"                   return '^'
"("                   return '('
")"                   return ')'
"PI"                  return 'PI'
"E"                   return 'E'
<<EOF>>               return 'EOF'
.                     return 'INVALID'

/lex

/* operator associations and precedence */

%left '+' '-'
%left '*' '/'
%left '^'
%left UMINUS

%start expressions

%% /* language grammar */

expressions
    : e EOF
        { return $e; }
    ;

e
    : e '+' e
        { return ['+', $e1, $e2]; }
    | e '-' e
        { return ['-', $e1, $e2]; }
    | e '*' e
        { return ['*', $e1, $e2]; }
    | e '/' e
        { return ['/', $e1, $e2]; }
    | e '^' e
        { return ['^', $e1, $e2]; }
    | '-' e %prec UMINUS
        { return ['-', $e]; }
    | '(' e ')'
        { return ['G', $e ]; }
    | NUMBER
        { return Number($NUMBER); }
    | E
        { return Math.E; }
    | PI
        { return Math.PI; }
    ;
Was it helpful?

Solution

In this line, instead of returning the sum of the operands in $$,

: e '+' e
    {$$ = $1+$3;}

would it work to return the desired object?

: e '+' e
    {$$ = ["+", $1, $3];}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top