Calculator demo
This demo parses mathematical expressions and returns the answer, keeping the correct order of operations.
Enter an expression to evaluate, such as PI*4^2 + 5:
The grammar
This Jison grammar was used to create the parser/evaluator:
/* description: Parses and executes mathematical expressions. */
/* lexical grammar */
%lex
%%
\s+ /* skip whitespace */
[0-9]+("."[0-9]+)?\b return 'NUMBER';
"*" return '*';
"/" return '/';
"-" 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 '^'
%right '!'
%right '%'
%left UMINUS
%token INVALID
%start expressions
%% /* language grammar */
expressions
: e EOF
{ typeof console !== 'undefined' ? console.log($1) : print($1);
return $1; }
;
e
: e '+' e
{$$ = $1 + $3;}
| e '-' e
{$$ = $1 - $3;}
| e '*' e
{$$ = $1 * $3;}
| e '/' e
{$$ = $1 / $3;}
| e '^' e
{$$ = Math.pow($1, $3);}
| e '!'
{{
$$ = (function fact(n) { return n == 0 ? 1 : fact(n - 1) * n; })($1);
}}
| e '%'
{$$ = $1 / 100;}
| '-' e %prec UMINUS
{$$ = -$2;}
| '(' e ')'
{$$ = $2;}
| NUMBER
{$$ = Number(yytext);}
| E
{$$ = Math.E;}
| PI
{$$ = Math.PI;}
;