PROGRAM 3
/**************************************************************************/ /* author: anthony f. ortiz */ /* program: scanner.l */ /* class: cs 6110 theory and design of compilers */ /* date: november 9, 1998 */ /* description: this program implements the scanner and symbol table */ /* part of a compiler. */ /**************************************************************************/ #include "defs.h" #include "y.tab.h" #include #include #include int hash_it (char * word); struct word * add_symtable (char * word); struct word * lookup_symtable (char * word); void print_symtable (); void update_program (char * str); void update_procedure (char * str); void update_function (char * str, type_t type); void update_parameters (type_t type, int ref); void destroy_paramlist (); void decrement_address (); void increment_address (); void start_addressing (int start); void set_dim0 (); void increment_dim (); void update_variables (char * str, type_t type, int d, int low, int high); void update_varlist (char * str); void destroy_varlist (); void update_variables2 (type_t type, int d, int low, int high); void write_file(void); int a_type(type_t t1); void write_file(void); void print_quad (quad_t qq); void print_prog(void); int start_program (); void quit_program (int top); void handle_integers (type_t type, int value); void handle_reals (type_t type, double value); void handle_variables (type_t type, int first, int index); void handle_assignments (type_t type, int first, int index, type_t type2, int first2); void handle_writes (type_t type, int first); void handle_reads (type_t type, int first, int index); void handle_calculations (type_t type, int first, int sign, type_t type2, int first2); void handle_inequalities (type_t type, int first, int sign, type_t type2, int first2); void handle_bool (type_t type, int first, int sign, type_t type2, int first2); int handle_then (int first); int handle_else (int instr); void handle_end (int instr); int save_loc (); int start_while (int first); void end_while (int start, int end); int declaring = 0; %} %% "and" { yylval.ival = AND; printf (" "); return (AND); } "array" { printf (" "); return (ARRAY); } "boolean" { printf (" "); return (BOOL); } "break" { printf (" "); return (BREAK); } "continue" { printf (" "); return (CONT); } "case" { printf (" "); return (CASE); } "declare" { declaring = 1; printf (" "); return (DECLARE); } "div" { yylval.ival = DIV; printf (" "); return (MULTOP); } "do" { printf (" "); return (DO); } "else" { printf (" "); return (ELSE); } "end" { if (declaring == 1) declaring = 0; printf (" "); return (END); } "function" { declaring = 1; printf (" "); return (FUNCTION); } "if" { printf (" "); return (IF); } "integer" { printf (" "); return (INT); } "mod" { yylval.ival = MOD; printf (" "); return (MULTOP); } "not" { yylval.ival = NOT; printf (" "); return (NOT); } "of" { printf (" "); return (OF); } "or" { yylval.ival = OR; printf (" "); return (OR); } "procedure" { declaring = 1; printf (" "); return (PROCEDURE); } "program" { printf ("\nTOKENS: "); return (PROGRAM); } "read" { printf (" "); return (READ); } "real" { printf (" "); return (REAL); } "ref" { printf (" "); return (REF); } "return" { printf (" "); return (RETURN); } "returns" { printf (" "); return (RETURNS); } "then" { printf (" "); return (THEN); } "while" { printf (" "); return (WHILE); } "write" { printf (" "); return (WRITE); } "true" { yylval.ival = TRUE; printf ("", yylval.ival); return (BCONST); } "false" { yylval.ival = FALSE; printf ("", yylval.ival); return (BCONST); } [ \n\t]+ {/* white space */} "//".*"\n" {/* comments */} ":=" { printf (" "); return (ASSGN); } ":" { printf (" "); return (COL); } "," { printf (" "); return (COMMA); } "=" { yylval.ival = EQ; printf (" "); return (RELOP); } "/" { yylval.ival = FDIV; printf (" "); return (MULTOP); } ">=" { yylval.ival = GEQ; printf (" "); return (RELOP); } ">" { yylval.ival = GR; printf (" "); return (RELOP); } [A-Za-z_][A-Za-z0-9_]* { yylval.pval = lookup_symtable (yytext); if (yylval.pval == NULL || declaring == 1) { yylval.pval = add_symtable (yytext); } printf (" ", yytext); return (IDENT); } [0-9]+ { yylval.ival = atoi (yytext); printf (" ", yylval.ival); return (INTCONST); } "[" { printf (" "); return (LBRACK); } "{" { printf (""); return (LBRACE); } "<=" { yylval.ival = LEQ; printf (" "); return (RELOP); } "<" { yylval.ival = LESS; printf (" "); return (RELOP); } "(" { printf (" "); return (LP); } "-" { yylval.ival = MINUS; printf (" "); return (ADDOP); } "!=" { yylval.ival = NEQ; printf (" "); return (RELOP); } "+" { yylval.ival = PLUS; printf (" "); return (ADDOP); } ".." { printf (" "); return (RANGE); } "]" { printf (" "); return (RBRACK); } "}" { printf (" "); return (RBRACE); } ")" { printf (" "); return (RP); } (([0-9]+)|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { yylval.rval = (float) (atof (yytext)); printf ("", yylval.rval); return (REALCONST); } ";" { if (declaring == 1) declaring = 0; printf (" "); return (SC); } "*" { yylval.ival = TIMES; printf (" "); return (MULTOP); } %% /* my main function is in the parse.y file. */ /* my structures and enumerations are in defs.h. */ int scope = 1; int address = 1; int dim = 0; int next_instr = 2; char * op_name [] = {"add", "sub", "mult", "idiv", "neg", "less", "equ", "fadd", "fsub", "fmult", "fdiv", "fneg", "fless", "fequ", "itor", "mov", "inxld", "inxst", "movim", "movad", "movabs", "bnot", "band", "bor", "bequ", "gto", "jmp", "iread", "rread", "iwrite", "rwrite", "call", "ret", "halt"}; mem_t mem [MAXMEM]; /* main memory */ mem_t * p; /* working pointer */ struct word * word_list [211]; /* the hash table with open chaining */ struct p_struct * par_type; /* linked list of parameters */ struct v_struct * var_type; /* linked list of variables */ /* hash word using formula in aho, sethi, and ullman. */ int hash_it (char * word) { char * p; unsigned h = 0; unsigned g; for (p = word; * p != '\0'; p = p + 1) { h = (h << 4) + (* p); if (g = h&0xf0000000) { h = h ^ (g >> 24); h = h ^ g; } } return h % 211; } /* add identifier to symbol table. */ struct word * add_symtable (char * word) { struct word * wp; int h = hash_it (word); /* word not there, allocate a new entry and link it on the list. */ wp = (struct word *) malloc (sizeof (struct word)); wp -> next = word_list [h]; /* have to copy the word itself as well. */ wp -> word_name = (char *) malloc (strlen (word) + 1); strcpy (wp -> word_name, word); word_list [h] = wp; return wp; /* it worked. */ } /* lookup identifier in symbol table, return 0 if not found, 1 if found. */ struct word * lookup_symtable (char * word) { struct word * wp; int h = hash_it (word); wp = word_list [h]; /* search down the list looking for the word. */ for (; wp; wp = wp -> next) { if (strcmp (wp -> word_name, word) == 0) return wp; } return NULL; /* not found. */ } /* print identifiers in symbol table. */ void print_symtable () { struct word * wp; int h; printf ("\n\nSymbol Table\n\n"); /* print list. */ printf (" name scope type dim low"); printf (" high first return\n\n"); for (h = 0; h < 211; h++) { wp = word_list [h]; for (; wp; wp = wp -> next) { printf ("%10s %8d %8d", wp -> word_name, wp -> sc_level, wp -> type); if (wp -> type >= 1 && wp -> type <= 3) { printf ("%8d %8d %8d %8d\n", wp -> dim, wp -> low, wp -> high, wp -> first); } else if (wp -> type == 4) { printf ("%8d %34d\n", wp -> dim, wp -> ret_type); } else if (wp -> type == 5) { printf ("%8d\n", wp -> dim); } else printf ("\n"); if ((wp -> type == 4 || wp -> type == 5) && wp -> params != NULL) { for (; wp -> params; wp -> params = wp -> params -> next) { printf ("params, type: %d location: %d ref: %d\n", wp -> params -> type, wp -> params -> p_loc, wp -> params -> isref); } } } } printf ("\n"); } /* increment scope by 1. */ increment_scope () { scope = scope + 1; } /* decrement scope by 1. */ decrement_scope () { scope = scope - 1; } /* update program. */ void update_program (char * str) { struct word * wp; int h = hash_it (str); wp = word_list [h]; /* search down the list looking for the word. */ for (; wp; wp = wp -> next) { if (strcmp (wp -> word_name, str) == 0) { wp -> sc_level = scope; wp -> type = program_t; break; } } } /* update procedure. */ void update_procedure (char * str) { struct word * wp; int h = hash_it (str); wp = word_list [h]; /* search down the list looking for the word. */ for (; wp; wp = wp -> next) { if (strcmp (wp -> word_name, str) == 0) { wp -> sc_level = scope; wp -> type = proc_t; wp -> dim = dim; wp -> params = par_type; break; } } } /* update function. */ void update_function (char * str, type_t type) { struct word * wp; int h = hash_it (str); wp = word_list [h]; /* search down the list looking for the word. */ for (; wp; wp = wp -> next) { if (strcmp (wp -> word_name, str) == 0) { wp -> sc_level = scope; wp -> type = funct_t; wp -> dim = dim; wp -> ret_type = type; wp -> dim = dim; wp -> params = par_type; break; } } } /* update parameters. */ void update_parameters (type_t type, int ref) { struct p_struct * pp; pp = (struct p_struct *) malloc (sizeof (struct p_struct)); pp -> next = par_type; /* have to copy it as well. */ pp -> type = type; pp -> p_loc = address; pp -> isref = ref; par_type = pp; } /* destroy parameter list. */ void destroy_paramlist () { par_type = NULL; } /* decrement address. */ void decrement_address () { address = address - 1; } /* increment_address. */ void increment_address () { address = address + 1; } /* start address at 1 or -4. */ void start_addressing (int start) { address = start; } /* start dim at 0. */ void set_dim0 () { dim = 0; } /* increment dim for procedures and functions. */ void increment_dim () { dim = dim + 1; } /* update variables. */ void update_variables (char * str, type_t type, int d, int low, int high) { struct word * wp; int h = hash_it (str); wp = word_list [h]; /* search down the list looking for the word. */ for (; wp; wp = wp -> next) { if (strcmp (wp -> word_name, str) == 0) { wp -> sc_level = scope; wp -> type = type; wp -> first = address; wp -> dim = d; if (wp -> dim == 1) { wp -> low = low; wp -> high = high; address = address + high - low + 1; } else if (wp -> first < 0) { decrement_address (); } else if (wp -> first >= 1) { increment_address (); } break; } } } /* update variable list. */ void update_varlist (char * str) { struct v_struct * vp; vp = (struct v_struct *) malloc (sizeof (struct v_struct)); vp -> next = var_type; /* have to copy it as well. */ vp -> name = str; var_type = vp; } /* destroy variable list. */ void destroy_varlist () { var_type = NULL; } /* update variables in symbol table. */ void update_variables2 (type_t type, int d, int low, int high) { struct v_struct * vp; vp = var_type; /* update each variable in variable list linked list to symbol table. */ for (; vp; vp = vp -> next) { update_variables (vp -> name, type, d, low, high); } } /* this simply generates the next quad and updates a global counter, which i have called "next_instr" and kept pointing to the next free mem space. */ void put_quad (op_t operator, int operand1, int operand2, int destination) { /* this generates the next quad in the array mem and increments the next_instr index, which is kept pointing to the next free space. */ mem_t *p; p = &(mem[next_instr++]); /* get address and increment index. */ p->op = operator; p->opd1 = operand1; p->opd2 = operand2; p->dest = destination; } /* this is a small boolean function to check if something has an "arithmetic" type. (the typenames are *mine*; yours may be different.) */ int a_type(type_t t1) { return ( (t1 == int_t) || (t1 == real_t)) ; } /* this is my utility to dump the quad array (mem) to a file. it requires that you #include in order to get the definitions for the constants o_wronly, etc. this version has a default filename "hard coded", but that, of course, could be changed. */ void write_file(void) { int ofd; int n; if((ofd = open("outfile.exec", O_WRONLY | O_TRUNC |O_CREAT, 0600)) <= 0) { perror(" Can't write outfile"); exit(1); } n = write(ofd, mem, next_instr * sizeof(mem_t)); fprintf(stderr, "Wrote out %d instructions\n", n / sizeof(mem_t)); } /* this will print out a single quad. */ void print_quad(quad_t qq) { printf("(%7s, %4d, %4d, %4d)\n", op_name[qq._op], qq._opd1,qq._opd2, qq._dest); } /* this can be used to print out the quads you have generated while they are still in memory. it is what i have called at the end of my compiler in order to produce the output i have included on class handouts. */ void print_prog(void) { int n; printf("PC = %d\n", mem[0].ival); printf("SP = %d\n", mem[1].ival); for(n=2; n < next_instr; n++) { printf("%4d: ", n); print_quad(mem[n].quad); if(mem[n].op == movim) { ++n; printf("%4d: (** %8d // %e **)\n", n, mem[n].ival, mem[n].rval); } } } /* start program. */ int start_program () { put_quad (movim, 0, 0, -1); next_instr++; /* skip the constant top and fill it in at end. */ return (next_instr - 1); } /* quit program. */ void quit_program (int top) { put_quad (halt, 0, 0, 0); PC = top - 1; SP = next_instr + 4; mem [top].ival = address; } /* handle integers. */ void handle_integers (type_t type, int value) { i.type = type; i.first = address; i.index = 0; put_quad (movim, 0, 0, address); if (type == int_t) { mem [next_instr].ival = value; } else if (type == bool_t && value == TRUE) { mem [next_instr].ival = true; } else if (type == bool_t && value == FALSE) { mem [next_instr].bval = false; } next_instr = next_instr + 1; address = address + 1; } /* handle reals. */ void handle_reals (type_t type, double value) { i.type = type; i.first = address; i.index = 0; put_quad (movim, 0, 0, address); if (type == real_t) { printf ("here it is %f", value); mem [next_instr].rval = value; } next_instr = next_instr + 1; address = address + 1; } /* handle variables. */ void handle_variables (type_t type, int first, int index) { if (index == 0) { i.type = type; i.first = first; i.index = index; } else if (index > 0) { i.type = type; i.first = address; i.index = 0; put_quad (inxld, first , index , address); address = address + 1; } } /* handle assignments. */ void handle_assignments (type_t type, int first, int index, type_t type2, int first2) { if (type == real_t && type2 == int_t) { put_quad (itor, first2, 0, address); first2 = address; type2 = real_t; address++; } if (index == 0 && type == type2) { put_quad (mov, first2, 0, first); } else if (type == type2) { put_quad (inxst, first2, index, first); } } /* handle writes. */ void handle_writes (type_t type, int first) { if (type == int_t) { put_quad (iwrite, first, 0, 0); } else if (type == real_t) { put_quad (rwrite, first, 0, 0); } } /* handle reads. */ void handle_reads (type_t type, int first, int index) { if (type == int_t && index == 0) { put_quad (iread, 0, 0, first); } else if (type == real_t && index == 0) { put_quad (rread, 0, 0, first); } else if (type == int_t && index > 0) { put_quad (iread, 0, 0, address); put_quad (inxst, address, index, first); address++; } else if (type == real_t && index > 0) { put_quad (rread, 0, 0, address); put_quad (inxst, address, index, first); address++; } } /* handle calculations. */ void handle_calculations (type_t type, int first, int sign, type_t type2, int first2) { if (type == int_t && type2 == real_t) { put_quad (itor, first, 0, address); first = address; type = real_t; address++; } else if (type == real_t && type2 == int_t) { put_quad (itor, first2, 0, address); first2 = address; type2 = real_t; address++; } if (sign == PLUS && type == int_t && type2 == int_t) { put_quad (add, first, first2, address); } else if (sign == PLUS && type == real_t && type2 == real_t) { put_quad (fadd, first, first2, address); } else if (sign == MINUS && type == int_t && type2 == int_t) { put_quad (sub, first, first2, address); } else if (sign == MINUS && type == real_t && type2 == real_t) { put_quad (fsub, first, first2, address); } else if (sign == TIMES && type == int_t && type2 == int_t) { put_quad (mult, first, first2, address); } else if (sign == TIMES && type == real_t && type2 == real_t) { put_quad (fmult, first, first2, address); } else if ((sign == DIV || sign == FDIV) && type == int_t && type2 == int_t) { put_quad (idiv, first, first2, address); } else if (sign == FDIV && type == real_t && type2 == real_t) { put_quad (fdiv, first, first2, address); } else if (sign == MINUS && type == int_t) { put_quad (neg, first, 0, address); } else if (sign == MINUS && type == real_t) { put_quad (fneg, first, 0, address); } if ((type == type2 || type2 == 0) && (type == real_t || type == int_t)) { i.type = type; i.first = address; i.index = 0; address++; } } /* handle inequalities. */ void handle_inequalities (type_t type, int first, int sign, type_t type2, int first2) { if (type == int_t && type2 == real_t) { put_quad (itor, first, 0, address); first = address; type = real_t; address++; } else if (type == real_t && type2 == int_t) { put_quad (itor, first2, 0, address); first2 = address; type2 = real_t; address++; } if (sign == LESS && type == int_t && type2 == int_t) { put_quad (less, first, first2, address); } else if (sign == LESS && type == real_t && type2 == real_t) { put_quad (fless, first, first2, address); } else if (sign == GR && type == int_t && type2 == int_t) { put_quad (less, first2, first, address); } else if (sign == GR && type == real_t && type2 == real_t) { put_quad (fless, first2, first, address); } else if (sign == EQ && type == bool_t && type2 == bool_t) { put_quad (bequ, first, first2, address); } else if (sign == EQ && type == int_t && type2 == int_t) { put_quad (equ, first, first2, address); } else if (sign == EQ && type == real_t && type2 == real_t) { put_quad (fequ, first, first2, address); } else if (sign == NEQ && type == int_t && type2 == int_t) { int temp; put_quad (equ, first, first2, address); temp = address; address++; put_quad (bnot, temp, 0, address); } else if (sign == NEQ && type == real_t && type2 == real_t) { int temp; put_quad (fequ, first, first2, address); temp = address; address++; put_quad (bnot, temp, 0, address); } else if (sign == LEQ && type == int_t && type2 == int_t) { int temp; put_quad (less, first2, first, address); temp = address; address++; put_quad (bnot, temp, 0, address); } else if (sign == LEQ && type == real_t && type2 == real_t) { int temp; put_quad (fless, first2, first, address); temp = address; address++; put_quad (bnot, temp, 0, address); } else if (sign == GEQ && type == int_t && type2 == int_t) { int temp; put_quad (less, first, first2, address); temp = address; address++; put_quad (bnot, temp, 0, address); } else if (sign == GEQ && type == real_t && type2 == real_t) { int temp; put_quad (fless, first, first2, address); temp = address; address++; put_quad (bnot, temp, 0, address); } if (type == type2 && (type == int_t || type == real_t || type == bool_t)) { i.type = bool_t; i.first = address; i.index = 0; address++; } } /* handle boolean algebra. */ void handle_bool (type_t type, int first, int sign, type_t type2, int first2) { if (sign == AND && type == bool_t && type2 == bool_t) { put_quad (band, first, first2, address); } else if (sign == OR && type == bool_t && type2 == bool_t) { put_quad (bor, first, first2, address); } else if (sign == NOT && type == bool_t) { put_quad (bnot, first, 0, address); } if ((type == type2 || type2 == 0) && type == bool_t) { i.type = type; i.first = address; i.index = 0; address++; } } /* handle then. */ int handle_then (int first) { put_quad (bnot, first, 0, address); put_quad (jmp, address, 0, 0); address++; return next_instr - 1; } /* handle else. */ int handle_else (int instr) { int i; put_quad (gto, 0, 0, 0); mem [instr].quad._dest = next_instr; return next_instr - 1; } /* handle end. */ void handle_end (int instr) { mem [instr].quad._dest = next_instr; } /* save location of beginning while. */ int save_loc () { return next_instr; } /* start while. */ int start_while (int first) { put_quad (bnot, first, 0, address); put_quad (jmp, address, 0, 0); address++; return next_instr - 1; } /* end while. */ void end_while (int begin, int end) { put_quad (gto, 0, 0, begin); mem [end].quad._dest = next_instr; } /**************************************************************************/ /* author: anthony f. ortiz */ /* program: parser.y */ /* class: cs6110-01 */ /* date: november 9, 1998 */ /* description: this program describes and parses a grammar. */ /**************************************************************************/ %{ #include "defs.h" #include #include #include %} %token AND %token ARRAY %token BOOL /* "boolean" */ %token BREAK %token CONT /* "continue" */ %token CASE %token DECLARE %token DIV %token DO %token ELSE %token END %token FUNCTION %token IF %token INT /* "integer" */ %token MOD %token NOT %token OF %token OR %token PROCEDURE %token PROGRAM %token READ %token REAL %token REF %token RETURN %token RETURNS %token THEN %token WHILE %token WRITE %token TRUE %token FALSE %token ADDOP %token ASSGN /* ":=" */ %token BCONST /* boolean constant */ %token COL /* ":" */ %token COMMA /* "," */ %token EQ /* "=" */ %token FDIV /* "/" */ %token GEQ /* ">=" */ %token GR /* ">" */ %token IDENT /* identifier */ %token INTCONST /* integer constant */ %token LBRACK /* "[" */ %token LBRACE /* "{" */ %token LEQ /* "<=" */ %token LESS /* "<" */ %token LP /* "(" */ %token MINUS /* "-" */ %token MULTOP %token NEQ /* "!=" */ %token PLUS /* "+" */ %token RANGE /* ".." */ %token RBRACK /* "]" */ %token RBRACE /* "}" */ %token RELOP %token RP /* ")" */ %token REALCONST /* real constant */ %token SC /* ";" */ %token TIMES /* "*" */ %type simpletype %type variable %type expression %type ifstatement %type statement /* yystype structure */ %union {int ival; float rval; bool bval; type_t tval; struct info infoval; struct word * pval;} %left OR %left AND %nonassoc RELOP %left ADDOP %left MULTOP %right NOT %right UMINUS %% start : program; program : PROGRAM IDENT SC vardeclar procdeclist LBRACE {start_program ();} statlist RBRACE {update_program ($2 -> word_name); quit_program ();} ; vardeclar : {start_addressing (1);} DECLARE vardeclist END SC | /* empty */ ; vardeclist : decl vardeclist | /* empty */ ; decl : identlist COL simpletype SC {update_variables2 ($3, 0, 0, 0); destroy_varlist ();} | identlist COL arraytype SC {destroy_varlist ();} ; identlist : identlist COMMA IDENT {update_varlist ($3 -> word_name);} | IDENT {update_varlist ($1 -> word_name);} ; simpletype : INT {$$ = int_t;} | REAL {$$ = real_t;} | BOOL {$$ = bool_t;} ; arraytype : ARRAY LBRACK INTCONST RANGE INTCONST RBRACK OF simpletype {update_variables2 ($8, 1, $3, $5);} ; procdeclist : procdecl procdeclist | /* empty */ ; procdecl : {increment_scope ();} procheader vardeclar procdeclist LBRACE statlist RBRACE {decrement_scope ();} ; procheader : {start_addressing (-4);} PROCEDURE IDENT params SC {update_procedure ($3 -> word_name); destroy_paramlist (); set_dim0 ();} | {start_addressing (-4);} FUNCTION IDENT params RETURNS simpletype SC {update_function ($3 -> word_name, $6); destroy_paramlist (); set_dim0 ();} ; params : LP paramlist RP | /* empty */ ; paramlist : parameter | paramlist COMMA parameter ; parameter : IDENT COL simpletype {update_parameters ($3, 0); update_variables ($1 -> word_name, $3, 0, 0, 0); increment_dim ();} | REF IDENT COL simpletype {update_parameters ($4, 1); update_variables ($2 -> word_name, $4, 0, 0, 0); increment_dim ();} ; block : {increment_scope ();} LBRACE vardeclar statlist RBRACE {decrement_scope ();} ; statlist : statlist statement | statement ; statement : variable ASSGN expression SC {handle_assignments ($1.type, $1.first, $1.index, $3.type, $3. first);} | ifstatement {} | WHILE {$$ = save_loc ();} expression DO {$$ = start_while ($3.first);} statlist END {end_while ($2, $5);} | CASE expression OF caselist END SC {} | RETURN expression SC {} | BREAK SC {} | CONT SC {} | READ variable SC {handle_reads ($2.type, $2.first, $2.index);} | WRITE expression SC {handle_writes ($2.type, $2.first);} | procedurecall SC {} | block {} | SC /* empty */ {} ; ifstatement : IF expression THEN {$$ = handle_then ($2.first);} statlist {$$ = handle_else ($4);} elsepart {handle_end ($6);} ; elsepart : ELSE statlist END SC | END SC /* empty */ ; caselist : casebranch caselist | /* empty */ ; casebranch : labellist COL statement ; labellist : INTCONST COMMA labellist | INTCONST ; procedurecall : IDENT | callwithparameters ; callwithparameters : IDENT LP actuals RP ; actuals : actuals COMMA expression | expression ; variable : IDENT LBRACK expression RBRACK {$$.type = $1 -> type; $$.first = $1 -> first; $$.index = $3.first;} | IDENT {$$.type = $1 -> type; $$.first = $1 -> first; $$.index = $1 -> dim;} | callwithparameters {} ; expression : expression OR expression {handle_bool ($1.type, $1.first, $2, $3.type, $3.first); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | expression AND expression {handle_bool ($1.type, $1.first, $2, $3.type, $3.first); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | expression RELOP expression {handle_inequalities ($1.type, $1.first, $2, $3.type, $3.first); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | expression ADDOP expression {handle_calculations ($1.type, $1.first, $2, $3.type, $3.first); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | expression MULTOP expression {handle_calculations ($1.type, $1.first, $2, $3.type, $3.first); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | ADDOP expression %prec UMINUS {handle_calculations ($2.type, $2.first, $1, 0, 0); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | NOT expression {handle_bool ($2.type, $2.first, $1, 0, 0); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | variable {handle_variables ($1.type, $1.first, $1.index); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | BCONST {handle_integers (bool_t, $1); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | INTCONST {handle_integers (int_t, $1); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | REALCONST {handle_reals (real_t, $1); $$.type = i.type; $$.first = i.first; $$.index = i.index;} | LP expression RP {$$ = $2;} ; %% extern FILE * yyin; /* read from a file specified by the command line and parse. */ main (int argc, char ** argv) { if (argc > 1) { FILE *file; file = fopen (argv [1], "r"); if (!file) { fprintf (stderr, "could not open %s\n", argv [1]); } yyin = file; } yyparse (); print_symtable (); write_file (); } /* print a error message. */ yyerror (s) char * s; { printf ("%s\n", s); } /* filename: defs.h */ /* see program 1. */ /* data file: test1.dat */ program t6; declare x: integer; end; // ------------------------------- procedure print; { write x; } // ------------------------------- procedure q; // -------------------------- procedure qq; // ------------------ procedure qqq; { x := 12; } // end of qqq // ------------------ { qqq; } // end of qq // ------------------------- procedure rr; // ----------------- procedure rrr; { print; } // end of rrr; // ----------------- { rrr; } // end of rr; // ------------------------- { // begin of q qq; rr; } // end of q // ------------------------------- { // begin of t6 q; } /* outfile: prog3.out */ TOKENS: Symbol Table name scope type dim low high first return t6 1 6 qq 3 5 0 18 print 2 5 0 2 rr 3 5 0 55 qqq 4 5 0 7 rrr 4 5 0 33 q 2 5 0 70 x 1 1 0 0 0 1 Wrote out 112 instructions Read program into 112 mem locations. 97: ( movim, 0, 0, -1) 98: (** 6 // 8.407791e-45 **) Dest_val = (*** 6: 8.407791e-45 ***) 99: ( mov, -1, 0, 2) Dest_val = (*** 6: 8.407791e-45 ***) 100: ( neg, 2, 0, 2) Dest_val = -6 101: ( movim, 0, 0, 3) 102: (** 4 // 5.605194e-45 **) Dest_val = (*** 4: 5.605194e-45 ***) 103: ( sub, 2, 3, 2) Dest_val = -10 104: ( inxst, 2, -1, 2) Dest_val = (*** -10: -NaN ***) 105: ( movabs, 1, 0, 4) Dest_val = (*** 116: 1.625506e-43 ***) 106: ( inxst, 4, -1, 4) Dest_val = (*** 116: 1.625506e-43 ***) 107: ( movim, 0, 0, 5) 108: (** 111 // 1.555441e-43 **) Dest_val = (*** 111: 1.555441e-43 ***) 109: ( inxst, 5, -1, 1) Dest_val = (*** 111: 1.555441e-43 ***) 110: ( call, 70, 0, 0) 70: ( movim, 0, 0, -1) 71: (** 9 // 1.261169e-44 **) Dest_val = (*** 9: 1.261169e-44 ***) 72: ( mov, -1, 0, 1) Dest_val = (*** 9: 1.261169e-44 ***) 73: ( neg, 1, 0, 1) Dest_val = -9 74: ( movim, 0, 0, 2) 75: (** 4 // 5.605194e-45 **) Dest_val = (*** 4: 5.605194e-45 ***) 76: ( sub, 1, 2, 1) Dest_val = -13 77: ( inxst, 1, -1, 2) Dest_val = (*** -13: -NaN ***) 78: ( movabs, 1, 0, 3) Dest_val = (*** 126: 1.765636e-43 ***) 79: ( inxst, 3, -1, 4) Dest_val = (*** 126: 1.765636e-43 ***) 80: ( movim, 0, 0, 4) 81: (** 84 // 1.177091e-43 **) Dest_val = (*** 84: 1.177091e-43 ***) 82: ( inxst, 4, -1, 1) Dest_val = (*** 84: 1.177091e-43 ***) 83: ( call, 18, 0, 0) 18: ( movim, 0, 0, -1) 19: (** 5 // 7.006492e-45 **) Dest_val = (*** 5: 7.006492e-45 ***) 20: ( mov, -1, 0, 1) Dest_val = (*** 5: 7.006492e-45 ***) 21: ( neg, 1, 0, 1) Dest_val = -5 22: ( movim, 0, 0, 2) 23: (** 4 // 5.605194e-45 **) Dest_val = (*** 4: 5.605194e-45 ***) 24: ( sub, 1, 2, 1) Dest_val = -9 25: ( inxst, 1, -1, 2) Dest_val = (*** -9: -NaN ***) 26: ( movabs, 1, 0, 3) Dest_val = (*** 139: 1.947805e-43 ***) 27: ( inxst, 3, -1, 4) Dest_val = (*** 139: 1.947805e-43 ***) 28: ( movim, 0, 0, 4) 29: (** 32 // 4.484155e-44 **) Dest_val = (*** 32: 4.484155e-44 ***) 30: ( inxst, 4, -1, 1) Dest_val = (*** 32: 4.484155e-44 ***) 31: ( call, 7, 0, 0) 7: ( movim, 0, 0, -1) 8: (** 4 // 5.605194e-45 **) Dest_val = (*** 4: 5.605194e-45 ***) 9: ( mov, -2, 0, 1) Dest_val = (*** -9: -NaN ***) 10: ( inxld, -2, 1, 2) Dest_val = (*** -13: -NaN ***) 11: ( add, 2, 1, 1) Dest_val = -22 12: ( inxld, -2, 1, 2) Dest_val = (*** -10: -NaN ***) 13: ( add, 2, 1, 1) Dest_val = -32 14: ( movim, 0, 0, 3) 15: (** 12 // 1.681558e-44 **) Dest_val = (*** 12: 1.681558e-44 ***) 16: ( inxst, 3, 1, 1) Dest_val = (*** 12: 1.681558e-44 ***) 17: ( ret, 0, 0, 0) 32: ( ret, 0, 0, 0) 84: ( mov, -1, 0, 5) Dest_val = (*** 9: 1.261169e-44 ***) 85: ( neg, 5, 0, 5) Dest_val = -9 86: ( movim, 0, 0, 6) 87: (** 4 // 5.605194e-45 **) Dest_val = (*** 4: 5.605194e-45 ***) 88: ( sub, 5, 6, 5) Dest_val = -13 89: ( inxst, 5, -1, 2) Dest_val = (*** -13: -NaN ***) 90: ( movabs, 1, 0, 7) Dest_val = (*** 126: 1.765636e-43 ***) 91: ( inxst, 7, -1, 4) Dest_val = (*** 126: 1.765636e-43 ***) 92: ( movim, 0, 0, 8) 93: (** 96 // 1.345247e-43 **) Dest_val = (*** 96: 1.345247e-43 ***) 94: ( inxst, 8, -1, 1) Dest_val = (*** 96: 1.345247e-43 ***) 95: ( call, 55, 0, 0) 55: ( movim, 0, 0, -1) 56: (** 5 // 7.006492e-45 **) Dest_val = (*** 5: 7.006492e-45 ***) 57: ( mov, -1, 0, 1) Dest_val = (*** 5: 7.006492e-45 ***) 58: ( neg, 1, 0, 1) Dest_val = -5 59: ( movim, 0, 0, 2) 60: (** 4 // 5.605194e-45 **) Dest_val = (*** 4: 5.605194e-45 ***) 61: ( sub, 1, 2, 1) Dest_val = -9 62: ( inxst, 1, -1, 2) Dest_val = (*** -9: -NaN ***) 63: ( movabs, 1, 0, 3) Dest_val = (*** 139: 1.947805e-43 ***) 64: ( inxst, 3, -1, 4) Dest_val = (*** 139: 1.947805e-43 ***) 65: ( movim, 0, 0, 4) 66: (** 69 // 9.668959e-44 **) Dest_val = (*** 69: 9.668959e-44 ***) 67: ( inxst, 4, -1, 1) Dest_val = (*** 69: 9.668959e-44 ***) 68: ( call, 33, 0, 0) 33: ( movim, 0, 0, -1) 34: (** 5 // 7.006492e-45 **) Dest_val = (*** 5: 7.006492e-45 ***) 35: ( mov, -2, 0, 1) Dest_val = (*** -9: -NaN ***) 36: ( inxld, -2, 1, 2) Dest_val = (*** -13: -NaN ***) 37: ( add, 1, 2, 1) Dest_val = -22 38: ( inxld, -2, 1, 2) Dest_val = (*** -10: -NaN ***) 39: ( add, 1, 2, 1) Dest_val = -32 40: ( inxld, -2, 1, 2) Dest_val = (*** 0: 0.000000e+00 ***) 41: ( add, 1, 2, 1) Dest_val = -32 42: ( movim, 0, 0, 2) 43: (** 4 // 5.605194e-45 **) Dest_val = (*** 4: 5.605194e-45 ***) 44: ( sub, 1, 2, 1) Dest_val = -36 45: ( mov, -1, 0, 2) Dest_val = (*** 5: 7.006492e-45 ***) 46: ( sub, 1, 2, 1) Dest_val = -41 47: ( inxst, 1, -1, 2) Dest_val = (*** -41: -NaN ***) 48: ( movabs, 1, 0, 3) Dest_val = (*** 148: 2.073922e-43 ***) 49: ( inxst, 3, -1, 4) Dest_val = (*** 148: 2.073922e-43 ***) 50: ( movim, 0, 0, 4) 51: (** 54 // 7.567012e-44 **) Dest_val = (*** 54: 7.567012e-44 ***) 52: ( inxst, 4, -1, 1) Dest_val = (*** 54: 7.567012e-44 ***) 53: ( call, 2, 0, 0) 2: ( movim, 0, 0, -1) 3: (** 2 // 2.802597e-45 **) Dest_val = (*** 2: 2.802597e-45 ***) 4: ( inxld, 1, -2, 1) Dest_val = (*** 12: 1.681558e-44 ***) 5: ( iwrite, 1, 0, 0) >> 12 6: ( ret, 0, 0, 0) 54: ( ret, 0, 0, 0) 69: ( ret, 0, 0, 0) 96: ( ret, 0, 0, 0) 111: ( halt, 0, 0, 0) *** Execution complete ***
BACK TO CS6110 PAGE.