73 lines
1.8 KiB
Plaintext
73 lines
1.8 KiB
Plaintext
|
/* description: Parses end executes mathematical expressions. */
|
||
|
|
||
|
/* lexical grammar */
|
||
|
%lex
|
||
|
%%
|
||
|
|
||
|
\s+ /* skip whitespace */
|
||
|
[0-9]+("."[0-9]+)?\b return 'NUMBER'
|
||
|
"n" return 'n'
|
||
|
"||" return '||'
|
||
|
"&&" return '&&'
|
||
|
"?" return '?'
|
||
|
":" return ':'
|
||
|
"<=" return '<='
|
||
|
">=" return '>='
|
||
|
"<" return '<'
|
||
|
">" return '>'
|
||
|
"!=" return '!='
|
||
|
"==" return '=='
|
||
|
"%" return '%'
|
||
|
"(" return '('
|
||
|
")" return ')'
|
||
|
<<EOF>> return 'EOF'
|
||
|
. return 'INVALID'
|
||
|
|
||
|
/lex
|
||
|
|
||
|
/* operator associations and precedence */
|
||
|
|
||
|
%right <code> '?' ':'
|
||
|
%left '||'
|
||
|
%left '&&'
|
||
|
%left '<=' '>=' '<' '>' '!=' '=='
|
||
|
%left '%'
|
||
|
|
||
|
%start expressions
|
||
|
|
||
|
%% /* language grammar */
|
||
|
|
||
|
expressions
|
||
|
: e EOF
|
||
|
{ return { type : 'GROUP', expr: $1 }; }
|
||
|
;
|
||
|
|
||
|
e
|
||
|
: e '?' e ':' e
|
||
|
{$$ = { type: 'TERNARY', expr: $1, truthy : $3, falsey: $5 }; }
|
||
|
| e '||' e
|
||
|
{$$ = { type: "OR", left: $1, right: $3 };}
|
||
|
| e '&&' e
|
||
|
{$$ = { type: "AND", left: $1, right: $3 };}
|
||
|
| e '<' e
|
||
|
{$$ = { type: 'LT', left: $1, right: $3 }; }
|
||
|
| e '<=' e
|
||
|
{$$ = { type: 'LTE', left: $1, right: $3 };}
|
||
|
| e '>' e
|
||
|
{$$ = { type: 'GT', left: $1, right: $3 };}
|
||
|
| e '>=' e
|
||
|
{$$ = { type: 'GTE', left: $1, right: $3 };}
|
||
|
| e '!=' e
|
||
|
{$$ = { type: 'NEQ', left: $1, right: $3 };}
|
||
|
| e '==' e
|
||
|
{$$ = { type: 'EQ', left: $1, right: $3 };}
|
||
|
| e '%' e
|
||
|
{$$ = { type: 'MOD', left: $1, right: $3 };}
|
||
|
| '(' e ')'
|
||
|
{$$ = { type: 'GROUP', expr: $2 }; }
|
||
|
| 'n'
|
||
|
{$$ = { type: 'VAR' }; }
|
||
|
| NUMBER
|
||
|
{$$ = { type: 'NUM', val: Number(yytext) }; }
|
||
|
;
|