Created
May 1, 2019 20:09
-
-
Save saevarb/0b6c740de0c15d70c7ef1605ed321bd0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
#include <stdio.h> | |
#include <string.h> | |
#include "tree.h" | |
extern char *yytext; | |
extern Body* prgBody; | |
void yyerror(char *str) { | |
fprintf(stderr, "%s\n", str); | |
fprintf(stderr, "syntax error before %s\n",yytext); | |
} | |
int yylex(); | |
%} | |
%union { | |
int intConst; | |
int boolConst; | |
char* stringConst; | |
Exp* exp; | |
StmtList* stmtList; | |
Stmt* stmt; | |
Decl* decl; | |
DeclList* declList; | |
ExpList* expList; | |
Type* type; | |
Body* body; | |
Var *var; | |
} | |
%token <intConst> tINTCONST | |
%token <boolean> tBOOLCONST | |
%token <stringConst> tIDENTIFIER | |
%token tPLUS | |
%token tMINUS | |
%token tTIMES | |
%token tDIV | |
%token tEQUAL | |
%token tNEQUAL | |
%token tLT | |
%token tLTE | |
%token tGT | |
%token tGTE | |
%token tAND | |
%token tOR | |
%token tRETURN | |
%token tWRITE | |
%token tIF | |
%token tTHEN | |
%token tELSE | |
%token tWHILE | |
%token tDO | |
%token tALLOCATE | |
%token tOF | |
%token tLENGTH | |
%token tTRUE | |
%token tFALSE | |
%token tNULL | |
%token tFUNC | |
%token tEND | |
%token tVAR | |
%token tTYPE | |
%token tBOOL | |
%token tINT | |
%token tARRAYOF | |
%token tRECORDOF | |
%token tUNIT | |
%token tINVALID_TOKEN | |
%type <body> program body | |
%type <stmtList> statement_list | |
%type <stmt> statement | |
%type <decl> var_type | |
/*declaration has type decList because a single variable declaration can | |
*declare multiple variable */ | |
%type <declList> decl_list var_decl_list declaration par_decl_list | |
%type <exp> expression term | |
%type <expList> act_list | |
%type <type> type | |
%type <var> variable | |
%right tTHEN tELSE | |
%left tAND tOR | |
%left tEQUAL tNEQUAL tLT tLTE tGT tGTE | |
%left tPLUS tMINUS | |
%left tTIMES tDIV | |
%start program | |
%% | |
program : body { prgBody = $1; } | |
; | |
/* body : expression; */ | |
body : decl_list statement_list { $$ = makeProgramBody($1, $2); } | |
statement_list | |
: statement { $$ = makeStmtListCons(makeStmtListNil(), $1); } | |
| statement statement_list { $$ = makeStmtListCons($2, $1); } | |
; | |
statement | |
: tRETURN expression ';' | |
{ $$ = makeRetStmt($2); } | |
| tWRITE expression ';' | |
{ $$ = makeWriteStmt($2); } | |
| tALLOCATE variable ';' | |
{ $$ = makeAllocateStmt($2, makeExpIntconst(1)); } | |
| tALLOCATE variable tOF tLENGTH expression ';' | |
{ $$ = makeAllocateStmt($2, $5);} | |
| variable '=' expression ';' | |
{ $$ = makeAssignmentStmt($1, $3); } | |
| tIF expression tTHEN statement | |
{ $$ = makeIfThenStmt($2, $4); } | |
| tIF expression tTHEN statement tELSE statement | |
{ $$ = makeIfThenElseStmt($2, $4, $6); } | |
| tWHILE expression tDO statement | |
{ $$ = makeWhileLoopStmt($2, $4); } | |
| '{' statement_list '}' | |
{ $$ = makeBlockStmt($2); } | |
; | |
decl_list | |
: declaration decl_list { $$ = declListAppend($1, $2); } | |
| /* epsilon */ { $$ = makeDeclListNil(); } | |
; | |
declaration | |
: tTYPE tIDENTIFIER '=' type ';' | |
{ $$ = makeDeclListCons(makeDeclListNil(), makeTypeDecl($2, $4)); } | |
| tFUNC tIDENTIFIER '(' par_decl_list ')' ':' type body tEND tIDENTIFIER | |
{ | |
if (strcmp($2, $10) != 0) { | |
char foo[256]; | |
sprintf(foo, "Function declared as '%s' ended with '%s'", $2, $10); | |
yyerror(foo); | |
YYERROR; | |
} | |
$$ = makeDeclListCons(makeDeclListNil(), makeFuncDecl($2, $4, $7, $8)); | |
} | |
| tVAR var_decl_list ';' | |
{$$ = $2;} | |
; | |
var_decl_list | |
: var_type ',' var_decl_list | |
{$$ = makeDeclListCons($3, $1);} | |
| var_type | |
{$$ = makeDeclListCons(makeDeclListNil(), $1);} | |
; | |
par_decl_list | |
: var_decl_list | |
{$$ = $1;} | |
| /* epsilon */ | |
{$$ = makeDeclListNil();} | |
; | |
var_type | |
: tIDENTIFIER ':' type | |
{$$ = makeVarDecl($1, $3);} | |
; | |
type | |
: tIDENTIFIER { $$ = makeTypeCustom($1); } | |
| tBOOL { $$ = makeTypeBool(); } | |
| tINT { $$ = makeTypeInt(); } | |
| tARRAYOF type { $$ = makeTypeArray($2); } | |
| tUNIT { $$ = makeTypeUnit(); } | |
| tRECORDOF '{' var_decl_list '}' { $$ = makeTypeRecord($3); } | |
; | |
/* TODO: do something like | |
expression tSOMEOP expression { $$ = makeBinExp($1, $3, $2); } | |
or just figure out why the exact thing above doesn't work. | |
*/ | |
expression | |
: expression tPLUS expression { $$ = makeBinExp($1, $3, tPLUS); } | |
| expression tMINUS expression { $$ = makeBinExp($1, $3, tMINUS);} | |
| expression tTIMES expression { $$ = makeBinExp($1, $3, tTIMES);} | |
| expression tDIV expression { $$ = makeBinExp($1, $3, tDIV);} | |
| expression tEQUAL expression { $$ = makeBinExp($1, $3, tEQUAL);} | |
| expression tNEQUAL expression { $$ = makeBinExp($1, $3, tNEQUAL);} | |
| expression tLT expression { $$ = makeBinExp($1, $3, tLT);} | |
| expression tLTE expression { $$ = makeBinExp($1, $3, tLTE);} | |
| expression tGT expression { $$ = makeBinExp($1, $3, tGT);} | |
| expression tGTE expression { $$ = makeBinExp($1, $3, tGTE);} | |
| expression tAND expression { $$ = makeBinExp($1, $3, tAND);} | |
| expression tOR expression { $$ = makeBinExp($1, $3, tOR);} | |
| term | |
{$$ = $1;} | |
; | |
term | |
: variable | |
{$$ = makeExpVar($1);} | |
| '(' expression ')' | |
{$$ = $2;} | |
| tIDENTIFIER '(' act_list ')' | |
{$$ = makeExpApp($1, $3);} | |
| '!' term | |
{$$ = makeExpNot($2);} | |
| '|' expression '|' | |
{$$ = makeExpAbs($2);} | |
| tINTCONST | |
{$$ = makeExpIntconst($1);} | |
| tTRUE | |
{$$ = makeExpTrue();} | |
| tFALSE | |
{$$ = makeExpFalse();} | |
| tNULL | |
{$$ = makeExpNull();} | |
; | |
variable | |
: variable '[' expression ']' | |
{$$ = makeVarOffset($1, $3);} | |
| variable '.' tIDENTIFIER | |
{$$ = makeVarDot($1, $3);} | |
| tIDENTIFIER | |
{$$ = makeVarVar($1);} | |
; | |
act_list | |
: expression ',' act_list | |
{$$ = makeExpListCons($3, $1);} | |
| expression | |
{$$ = makeExpListCons(makeExpListNil(), $1); } | |
| /* epsilon */ | |
{$$ = makeExpListNil();} | |
; | |
%% |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment