Skip to content

Instantly share code, notes, and snippets.

@zkessin
Created April 9, 2017 08:58
Show Gist options
  • Save zkessin/607e148c5ca41adc02deb05376f37425 to your computer and use it in GitHub Desktop.
Save zkessin/607e148c5ca41adc02deb05376f37425 to your computer and use it in GitHub Desktop.
/* 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;}
;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment