Simple calculator language with variable substitution using jison
%lex
%{
var parser = yy.parser;
%}
%%
\n return 'NEWLINE'
\s+ /* skip whitespace */
"$"[A-Z]+[A-Z0-9]*\b return 'VARIABLE'
[0-9]+("."[0-9]+)?\b return 'NUMBER'
"=" return '='
"-" return '-'
"+" return '+'
"/" return '/'
"÷" return '/'
"*" return '*'
"^" return '^'
"(" return '('
")" return ')'
"," return ','
"√" return 'SQRT'
"SQRT" return 'SQRT'
"COS" return 'COS'
"SIN" return 'SIN'
"TAN" return 'TAN'
"π" return 'PI'
"PI" return 'PI'
"LN2" return 'LN2'
"LN10" return 'LN10'
"LOG2E" return 'LOG2E'
"LOG10E" return 'LOG10E'
'LOG' return 'LOG'
"E" return 'E'
<<EOF>> return 'EOF'
/lex
%start pgm
%right '='
%left '+' '-'
%left '*' '/'
%right '^'
%left UMINUS
%%
pgm
: el EOF
{
var results = yy.parser.getResults();
yy.parser.clearResults();
return results;
}
;
el
: e NEWLINE el
{ yy.parser.addResult($1); }
| e
{ yy.parser.addResult($1); }
;
e
: NUMBER
{$$ = Number(yytext);}
|VARIABLE '=' e
{
yy.parser.setVar($1, $3);
$$ = $3;
}
| VARIABLE
{$$ = yy.parser.getVar($1); }
| e '+' e
{$$ = $1+$3; }
| e '-' e
{$$ = $1-$3;}
| e '*' e
{$$ = $1*$3;}
| e '/' e
{$$ = $1/$3;}
| e '^' 'e'
{$$ = Math.pow($1, $3);}
| SQRT '(' e ')'
{$$ = Math.sqrt($3);}
| COS '(' e ')'
{$$ = Math.cos($3);}
| SIN '(' e ')'
{$$ = Math.sin($3);}
| TAN '(' e ')'
{$$ = Math.tan($3);}
| '-' e %prec UMINUS
{$$ = -$2;}
| '(' e ')'
{$$ = ($2);}
| E
{$$ = Math.E;}
| PI
{$$ = Math.PI;}
| LOG '(' e ',' e ')'
{$$ = Math.log($3) / Math.log($5);}
| LOG '(' e ')'
{$$ = Math.log($3);}
| LN2
{$$ = Math.LN2;}
| LN10
{$$ = Math.LN10;}
| LOG2E
{$$ = Math.LOG2E;}
| LOG10E
{$$ = Math.LOG10E;}
;
%%
parser.addResult = function(value) {
if (!this._results) {
this._results = [];
}
this._results.push(value);
}
parser.getResults = function() {
return this._results;
}
parser.clearResults = function() {
this._results = [];
}
parser.getVar = function(key) {
if (!this._varTable) {
return undefined;
} else {
return this._varTable[key];
}
}
parser.setVar = function(key, val) {
if (!this._varTable) {
this._varTable = {};
}
this._varTable[key] = val;
}