Skip to content

Instantly share code, notes, and snippets.

@nandor
Created January 19, 2014 19:20
Show Gist options
  • Save nandor/8509693 to your computer and use it in GitHub Desktop.
Save nandor/8509693 to your computer and use it in GitHub Desktop.
grammar
/* Lexer for the mini language */
%lex
%%
\s+ /* skip whitespace */
"func" return 'FUNC';
"return" return 'RETURN';
"if" return 'IF';
"else" return 'ELSE';
"while" return 'WHILE';
[a-zA-Z_][a-zA-Z_0-9]* return 'ID';
0|[1-9][0-9]* return 'NUMBER';
"*" return '*';
"/" return '/';
"-" return '-';
"+" return '+';
"^" return '^';
"(" return '(';
")" return ')';
"{" return '{';
"}" return '}';
"," return ',';
";" return ';';
"==" return '==';
"=" return '=';
<<EOF>> return 'EOF';
. return 'INVALID';
/lex
%left '+' '-'
%left '*' '/' '%'
%left '=='
%left UMINUS
%start program
%%
program
: root EOF
{ return $1; }
| EOF
{ return []; }
;
root
: func
{ $$ = [$1]; }
| root func
{ $1.push($2); $$ = $1; }
;
func
: FUNC ID funcArgsOpt bodyOpt
{ $$ = { 'name': $2, 'args': $3, 'body': $4 }; }
;
funcArgsOpt
: '(' funcArgs ')'
{ $$ = $2; }
| '(' ')'
{ $$ = []; }
;
funcArgs
: ID
{ $$ = [$1]; }
| funcArgs ',' ID
{ $1.push($3); $$ = $1; }
;
bodyOpt
: '{' body '}'
{ $$ = $2; }
| '{' '}'
{ $$ = []; }
;
body
: statement
{ $$ = [$1]; }
| body statement
{ $1.push($2); $$ = $1; }
;
statement
: return
| ifElse
| assignment
;
return
: 'RETURN' expr ';'
{ $$ = { 'op': 'return', 'expr': $2 }; }
;
ifElse
: IF '(' expr ')' bodyOpt ELSE bodyOpt
{ $$ = { 'op': 'if', 'cond': $3, 'true': $5, 'false': $7 }; }
;
assignment
: ID '=' expr ';'
{ $$ = { 'op': 'assign', 'var': $1, 'val': $3 }; }
;
expr
: '(' expr ')'
{ $$ = $2; }
| expr '+' expr
{ $$ = { 'op': '+', 'lhs': $1, 'rhs': $3 }; }
| expr '-' expr
{ $$ = { 'op': '-', 'lhs': $1, 'rhs': $3 }; }
| expr '==' expr
{ $$ = { 'op': 'equ', 'lhs': $1, 'rhs': $3 }; }
| NUMBER
{ $$ = Number(yytext); }
| ID callArgsOpt
{ $$ = { 'op': 'call', 'name': $1, 'args': $2 }; }
| ID
{ $$ = { 'op': 'var', 'name': $1 }; }
;
callArgsOpt
: '(' callArgs ')'
{ $$ = $2; }
| '(' ')'
{ $$ = []; }
;
callArgs
: expr
{ $$ = [$1]; }
| callArgs ',' expr
{ $1.push($3); $$ = $1; }
;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment