Skip to content

Commit

Permalink
copy from lab3 for lab4
Browse files Browse the repository at this point in the history
  • Loading branch information
hzqmwne committed Nov 2, 2017
1 parent ed51556 commit c91f468
Show file tree
Hide file tree
Showing 2 changed files with 342 additions and 0 deletions.
150 changes: 150 additions & 0 deletions lab4/tiger.lex
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
%{
/* Lab2 Attention: You are only allowed to add code in this file and start at Line 26.*/
#include <string.h>
#include "util.h"
#include "symbol.h"
#include "errormsg.h"
#include "absyn.h"
#include "y.tab.h"

int charPos=1;

int yywrap(void)
{
charPos=1;
return 1;
}

void adjust(void)
{
EM_tokPos=charPos;
charPos+=yyleng;
}

/*
* Please don't modify the lines above.
* You can add C declarations of your own below.
*/

/* @function: getstr
* @input: a string literal
* @output: the string value for the input which has all the escape sequences
* translated into their meaning.
*/
char *getstr(const char *str)
{
//optional: implement this function if you need it
return NULL;
}

static int input(void);

char *stringToken() {
yyleng = 1;
int maxlen = 128;
char *s = (char *)malloc(maxlen);
int pos = 0;
char c;
while((c = (char)input()) != EOF) {
++yyleng;
if(c == '\"') {
break;
}
if(c == '\n') {
break;
}
if(c == '\\') {
c = (char)input();
++yyleng;
switch(c) { // still have other conditions
case 'n':
c = '\n';
break;
case 't':
c = '\t';
break;
default:
break;
}
}
if(pos >= maxlen) {
s = (char *)realloc(s, maxlen * 2);
maxlen = maxlen * 2;
}
s[pos] = (char)c;
++pos;
}
s[pos] = '\0';
return s;
}

int commentStartCount = 0;

%}
/* You can add lex definitions here. */

%Start COMMENT
%%
/*
* Below is an example, which you can wipe out
* and write reguler expressions and actions of your own.
*/

"\n" {adjust(); EM_newline(); continue;}
<INITIAL>(" "|"\t")+ {adjust();}

<INITIAL>while {adjust(); return WHILE;}
<INITIAL>for {adjust(); return FOR;}
<INITIAL>to {adjust(); return TO;}
<INITIAL>break {adjust(); return BREAK;}
<INITIAL>let {adjust(); return LET;}
<INITIAL>in {adjust(); return IN;}
<INITIAL>end {adjust(); return END;}
<INITIAL>function {adjust(); return FUNCTION;}
<INITIAL>var {adjust(); return VAR;}
<INITIAL>type {adjust(); return TYPE;}
<INITIAL>array {adjust(); return ARRAY;}
<INITIAL>if {adjust(); return IF;}
<INITIAL>then {adjust(); return THEN;}
<INITIAL>else {adjust(); return ELSE;}
<INITIAL>do {adjust(); return DO;}
<INITIAL>of {adjust(); return OF;}
<INITIAL>nil {adjust(); return NIL;}

<INITIAL>\x22 {yylval.sval=stringToken(); adjust(); return STRING;}
<INITIAL>"/*" {adjust(); ++commentStartCount; BEGIN COMMENT;}

<INITIAL>":=" {adjust(); return ASSIGN;}
<INITIAL>"," {adjust(); return COMMA;}
<INITIAL>":" {adjust(); return COLON;}
<INITIAL>";" {adjust(); return SEMICOLON;}
<INITIAL>"(" {adjust(); return LPAREN;}
<INITIAL>")" {adjust(); return RPAREN;}
<INITIAL>"[" {adjust(); return LBRACK;}
<INITIAL>"]" {adjust(); return RBRACK;}
<INITIAL>"{" {adjust(); return LBRACE;}
<INITIAL>"}" {adjust(); return RBRACE;}
<INITIAL>"." {adjust(); return DOT;}
<INITIAL>"+" {adjust(); return PLUS;}
<INITIAL>"-" {adjust(); return MINUS;}
<INITIAL>"*" {adjust(); return TIMES;}
<INITIAL>"/" {adjust(); return DIVIDE;}
<INITIAL>"=" {adjust(); return EQ;}
<INITIAL>"!="|"<>" {adjust(); return NEQ;}
<INITIAL>"<=" {adjust(); return LE;}
<INITIAL>"<" {adjust(); return LT;}
<INITIAL>">=" {adjust(); return GE;}
<INITIAL>">" {adjust(); return GT;}
<INITIAL>"&" {adjust(); return AND;}
<INITIAL>"|" {adjust(); return OR;}

<INITIAL>[A-Za-z][A-Za-z0-9_]* {adjust(); yylval.sval=String(yytext); return ID;}
<INITIAL>[0-9]+ {adjust(); yylval.ival=atoi(yytext); return INT;}

<INITIAL>. {adjust(); EM_error(charPos, "illegal character");}

<COMMENT>"/*" {adjust(); ++commentStartCount;}
<COMMENT>"*/" {adjust(); --commentStartCount; if(commentStartCount==0) {BEGIN INITIAL;}}
<COMMENT>(" "|"\t")+ {adjust();}
<COMMENT>. {adjust();}

192 changes: 192 additions & 0 deletions lab4/tiger.y
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
%{
#include <stdio.h>
#include "util.h"
#include "errormsg.h"
#include "symbol.h"
#include "absyn.h"

int yylex(void); /* function prototype */

A_exp absyn_root;

void yyerror(char *s)
{
EM_error(EM_tokPos, "%s", s);
}
%}


%union {
int pos;
int ival;
string sval;
A_exp exp;
A_expList explist;
A_var var;
A_decList declist;
A_dec dec;
A_efieldList efieldlist;
A_efield efield;
A_namety namety;
A_nametyList nametylist;
A_fieldList fieldlist;
A_field field;
A_fundecList fundeclist;
A_fundec fundec;
A_ty ty;
}

%token <sval> ID STRING
%token <ival> INT

%token
COMMA COLON SEMICOLON LPAREN RPAREN LBRACK RBRACK
LBRACE RBRACE DOT
PLUS MINUS TIMES DIVIDE EQ NEQ LT LE GT GE
AND OR ASSIGN
ARRAY IF THEN ELSE WHILE FOR TO DO LET IN END OF
BREAK NIL
FUNCTION VAR TYPE

%type <exp> exp expseq
%type <explist> actuals nonemptyactuals sequencing sequencing_exps
%type <var> lvalue one oneormore
%type <declist> decs decs_nonempty
%type <dec> decs_nonempty_s vardec
%type <efieldlist> rec rec_nonempty
%type <efield> rec_one
%type <nametylist> tydec
%type <namety> tydec_one
%type <fieldlist> tyfields tyfields_nonempty
%type <ty> ty
%type <fundeclist> fundec
%type <fundec> fundec_one

%nonassoc ASSIGN
%left OR
%left AND
%nonassoc EQ NEQ LT LE GT GE
%left PLUS MINUS
%left TIMES DIVIDE
%left UMINUS

%start program

%%

program: exp {absyn_root = $1;};

exp: lvalue {$$ = A_VarExp(EM_tokPos, $1);}
|NIL {$$ = A_NilExp(EM_tokPos);}
|LPAREN sequencing_exps RPAREN {$$ = A_SeqExp(EM_tokPos, $2);}
|LPAREN exp RPAREN {$$ = $2;}
|INT {$$ = A_IntExp(EM_tokPos, $1);}
|STRING {$$ = A_StringExp(EM_tokPos, $1);}
|MINUS exp %prec UMINUS {$$ = A_OpExp(EM_tokPos, A_minusOp, A_IntExp(EM_tokPos, 0), $2);}
|ID LPAREN actuals RPAREN {$$ = A_CallExp(EM_tokPos, S_Symbol($1), $3);}
|exp PLUS exp {$$ = A_OpExp(EM_tokPos, A_plusOp, $1, $3);}
|exp MINUS exp {$$ = A_OpExp(EM_tokPos, A_minusOp, $1, $3);}
|exp TIMES exp {$$ = A_OpExp(EM_tokPos, A_timesOp, $1, $3);}
|exp DIVIDE exp {$$ = A_OpExp(EM_tokPos, A_divideOp, $1, $3);}
|exp EQ exp {$$ = A_OpExp(EM_tokPos, A_eqOp, $1, $3);}
|exp NEQ exp {$$ = A_OpExp(EM_tokPos, A_neqOp, $1, $3);}
|exp LT exp {$$ = A_OpExp(EM_tokPos, A_ltOp, $1, $3);}
|exp LE exp {$$ = A_OpExp(EM_tokPos, A_leOp, $1, $3);}
|exp GT exp {$$ = A_OpExp(EM_tokPos, A_gtOp, $1, $3);}
|exp GE exp {$$ = A_OpExp(EM_tokPos, A_geOp, $1, $3);}
|exp AND exp {$$ = A_IfExp(EM_tokPos, $1, $3, A_IntExp(EM_tokPos, 0));}
|exp OR exp {$$ = A_IfExp(EM_tokPos, $1, A_IntExp(EM_tokPos, 1), $3);}
|ID LBRACE rec RBRACE {$$ = A_RecordExp(EM_tokPos, S_Symbol($1), $3);}
|ID LBRACK exp RBRACK OF exp {$$ = A_ArrayExp(EM_tokPos, S_Symbol($1), $3, $6);}
|lvalue ASSIGN exp {$$ = A_AssignExp(EM_tokPos, $1, $3);}
|IF exp THEN exp ELSE exp {$$ = A_IfExp(EM_tokPos, $2, $4, $6);}
|IF exp THEN exp {$$ = A_IfExp(EM_tokPos, $2, $4, NULL);}
|WHILE exp DO exp {$$ = A_WhileExp(EM_tokPos, $2, $4);}
|FOR ID ASSIGN exp TO exp DO exp {$$ = A_ForExp(EM_tokPos, S_Symbol($2), $4, $6, $8);}
|BREAK {$$ = A_BreakExp(EM_tokPos);}
|LET decs IN expseq END {$$ = A_LetExp(EM_tokPos, $2, $4);}
;

expseq : sequencing {$$ = A_SeqExp(EM_tokPos, $1);}
;

sequencing : {$$ = NULL;}
|exp {$$ = A_ExpList($1, NULL);}
|sequencing_exps {$$ = $1;}
;

sequencing_exps : exp SEMICOLON exp {$$ = A_ExpList($1, A_ExpList($3, NULL));}
|exp SEMICOLON sequencing_exps {$$ = A_ExpList($1, $3);}
;

actuals : {$$ = NULL;}
|nonemptyactuals {$$ = $1;}
;

nonemptyactuals : exp {$$ = A_ExpList($1, NULL);}
|exp COMMA nonemptyactuals {$$ = A_ExpList($1, $3);}
;

rec : {$$ = NULL;}
|rec_nonempty {$$ = $1;}
;

rec_nonempty : rec_one {$$ = A_EfieldList($1, NULL);}
|rec_one COMMA rec_nonempty {$$ = A_EfieldList($1, $3);}
;

rec_one : ID EQ exp {$$ = A_Efield(S_Symbol($1), $3);}
;

decs : {$$ = NULL;}
|decs_nonempty {$$ = $1;}
;

decs_nonempty : decs_nonempty_s {$$ = A_DecList($1, NULL);}
|decs_nonempty_s decs_nonempty {$$ = A_DecList($1, $2);}
;

decs_nonempty_s : tydec {$$ = A_TypeDec(EM_tokPos, $1);}
|vardec {$$ = $1;}
|fundec {$$ = A_FunctionDec(EM_tokPos, $1);}
;

tydec : tydec_one {$$ = A_NametyList($1, NULL);}
|tydec_one tydec {$$ = A_NametyList($1, $2);}
;

tydec_one : TYPE ID EQ ty {$$ = A_Namety(S_Symbol($2), $4);}
;

ty : ID {$$ = A_NameTy(EM_tokPos, S_Symbol($1));}
|LBRACE tyfields RBRACE {$$ = A_RecordTy(EM_tokPos, $2);}
|ARRAY OF ID {$$ = A_ArrayTy(EM_tokPos, S_Symbol($3));}
;

tyfields : {$$ = NULL;}
|tyfields_nonempty {$$ = $1;}
;

tyfields_nonempty : ID COLON ID {$$ = A_FieldList(A_Field(EM_tokPos, S_Symbol($1), S_Symbol($3)), NULL);}
|ID COLON ID COMMA tyfields_nonempty {$$ = A_FieldList(A_Field(EM_tokPos, S_Symbol($1), S_Symbol($3)), $5);}
;

vardec : VAR ID ASSIGN exp {$$ = A_VarDec(EM_tokPos,S_Symbol($2),S_Symbol(""),$4);}
|VAR ID COLON ID ASSIGN exp {$$ = A_VarDec(EM_tokPos,S_Symbol($2),S_Symbol($4),$6);}
;

fundec : fundec_one {$$ = A_FundecList($1, NULL);}
|fundec_one fundec {$$ = A_FundecList($1, $2);}
;

fundec_one : FUNCTION ID LPAREN tyfields RPAREN EQ exp {$$ = A_Fundec(EM_tokPos, S_Symbol($2), $4, S_Symbol(""), $7);}
|FUNCTION ID LPAREN tyfields RPAREN COLON ID EQ exp {$$ = A_Fundec(EM_tokPos, S_Symbol($2), $4, S_Symbol($7), $9);}
;


lvalue : ID {$$ = A_SimpleVar(EM_tokPos, S_Symbol($1));}
|lvalue DOT ID {$$ = A_FieldVar(EM_tokPos, $1, S_Symbol($3));}
|lvalue LBRACK exp RBRACK {$$ = A_SubscriptVar(EM_tokPos, $1, $3);}
|ID LBRACK exp RBRACK {$$ = A_SubscriptVar(EM_tokPos, A_SimpleVar(EM_tokPos, S_Symbol($1)), $3);}
;

0 comments on commit c91f468

Please sign in to comment.