From c91f468216f183ad2e449fb908480be5b7cdbfcb Mon Sep 17 00:00:00 2001 From: hzqmwne Date: Thu, 2 Nov 2017 14:21:47 +0800 Subject: [PATCH] copy from lab3 for lab4 --- lab4/tiger.lex | 150 ++++++++++++++++++++++++++++++++++++++ lab4/tiger.y | 192 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 342 insertions(+) create mode 100644 lab4/tiger.lex create mode 100644 lab4/tiger.y diff --git a/lab4/tiger.lex b/lab4/tiger.lex new file mode 100644 index 0000000..36d34ff --- /dev/null +++ b/lab4/tiger.lex @@ -0,0 +1,150 @@ +%{ +/* Lab2 Attention: You are only allowed to add code in this file and start at Line 26.*/ +#include +#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;} +(" "|"\t")+ {adjust();} + +while {adjust(); return WHILE;} +for {adjust(); return FOR;} +to {adjust(); return TO;} +break {adjust(); return BREAK;} +let {adjust(); return LET;} +in {adjust(); return IN;} +end {adjust(); return END;} +function {adjust(); return FUNCTION;} +var {adjust(); return VAR;} +type {adjust(); return TYPE;} +array {adjust(); return ARRAY;} +if {adjust(); return IF;} +then {adjust(); return THEN;} +else {adjust(); return ELSE;} +do {adjust(); return DO;} +of {adjust(); return OF;} +nil {adjust(); return NIL;} + +\x22 {yylval.sval=stringToken(); adjust(); return STRING;} +"/*" {adjust(); ++commentStartCount; BEGIN COMMENT;} + +":=" {adjust(); return ASSIGN;} +"," {adjust(); return COMMA;} +":" {adjust(); return COLON;} +";" {adjust(); return SEMICOLON;} +"(" {adjust(); return LPAREN;} +")" {adjust(); return RPAREN;} +"[" {adjust(); return LBRACK;} +"]" {adjust(); return RBRACK;} +"{" {adjust(); return LBRACE;} +"}" {adjust(); return RBRACE;} +"." {adjust(); return DOT;} +"+" {adjust(); return PLUS;} +"-" {adjust(); return MINUS;} +"*" {adjust(); return TIMES;} +"/" {adjust(); return DIVIDE;} +"=" {adjust(); return EQ;} +"!="|"<>" {adjust(); return NEQ;} +"<=" {adjust(); return LE;} +"<" {adjust(); return LT;} +">=" {adjust(); return GE;} +">" {adjust(); return GT;} +"&" {adjust(); return AND;} +"|" {adjust(); return OR;} + +[A-Za-z][A-Za-z0-9_]* {adjust(); yylval.sval=String(yytext); return ID;} +[0-9]+ {adjust(); yylval.ival=atoi(yytext); return INT;} + +. {adjust(); EM_error(charPos, "illegal character");} + +"/*" {adjust(); ++commentStartCount;} +"*/" {adjust(); --commentStartCount; if(commentStartCount==0) {BEGIN INITIAL;}} +(" "|"\t")+ {adjust();} +. {adjust();} + diff --git a/lab4/tiger.y b/lab4/tiger.y new file mode 100644 index 0000000..22ae0aa --- /dev/null +++ b/lab4/tiger.y @@ -0,0 +1,192 @@ +%{ +#include +#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 ID STRING +%token 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 expseq +%type actuals nonemptyactuals sequencing sequencing_exps +%type lvalue one oneormore +%type decs decs_nonempty +%type decs_nonempty_s vardec +%type rec rec_nonempty +%type rec_one +%type tydec +%type tydec_one +%type tyfields tyfields_nonempty +%type ty +%type fundec +%type 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);} + ; +