#include #include #include #include "grammar.h" // forward declarations void program(void); int stmt_list(void); int stmt(void); int expr(void); int term_tail(void); int term(void); int factor_tail(void); int factor(void); int add_op(void); int mult_op(void); int match(int x); int epsilon(void); void fail(void) __attribute__ ((noreturn)) ; void get_nexttoken(); void emit(const char *label,int self,int count, ...); extern int nextToken; int nodecount = 0; void program() { int B = stmt_list(); int C = match(0); emit("program",nodecount,2,B,C); } int stmt_list() { int self = nodecount; nodecount++; if(nextToken == ID || nextToken == READ || nextToken == WRITE) { int B = stmt(); int C = stmt_list(); emit("stmt_list",self,2,B,C); } else { int B = epsilon(); emit("stmt_list",self,1,B); } return(self); } int stmt() { int self = nodecount; nodecount++; if(nextToken == ID) { int B = match(ID); int C = match(ASSIGN); int D = expr(); emit("stmt",self,3,B,C,D); } else if(nextToken == READ) { int B = match(READ); int C = match(ID); emit("stmt",self,2,B,C); } else if(nextToken == WRITE) { int B = match(WRITE); int C = expr(); emit("stmt",self,2,B,C); } else { fail(); } return(self); } int expr() { int self = nodecount; nodecount++; int B = term(); int C = term_tail(); emit("expr",self,2,B,C); return(self); } int term_tail() { int self = nodecount; nodecount++; if(nextToken == PLUS || nextToken == MINUS) { int B = add_op(); int C = term(); int D = term_tail(); emit("term_tail",self,3,B,C,D); } else { int B = epsilon(); emit("term_tail",self,1,B); } return(self); } int term() { int self = nodecount; nodecount++; int B = factor(); int C = factor_tail(); emit("term",self,2,B,C); return(self); } int factor_tail() { int self = nodecount; nodecount++; if(nextToken == DIVIDE || nextToken == MULTIPLY) { int B = mult_op(); int C = factor(); int D = factor_tail(); emit("factor_tail",self,3,B,C,D); } else { int B = epsilon(); emit("factor_tail",self,1,B); } return(self); } int factor() { int self = nodecount; nodecount++; if(nextToken == LPAREN) { int B = match(LPAREN); int C = expr(); int D = match(RPAREN); emit("factor",self,3,B,C,D); } else if(nextToken == ID) { int B = match(ID); emit("factor",self,1,B); } else if(nextToken == NUMBER) { int B = match(NUMBER); emit("factor",self,1,B); } else { fail(); } return(self); } int add_op() { int self = nodecount; nodecount++; if(nextToken == PLUS) { int B = match(PLUS); emit("factor",self,1,B); } else if(nextToken == MINUS) { int B = match(MINUS); emit("factor",self,1,B); } else { fail(); } return(self); } int mult_op() { int self = nodecount; nodecount++; if(nextToken == MULTIPLY) { int B = match(MULTIPLY); emit("mult_op",self,1,B); } else if(nextToken == DIVIDE) { int B = match(DIVIDE); emit("mult_op",self,1,B); } else { fail(); } return(self); } int epsilon() { int self = nodecount; nodecount++; emit("EPSILON",self,0); return(self); } int match(int x) { int self = nodecount; nodecount++; const char *string = "NO MATCH"; switch(x) { case 0: string = "$$"; break; case PLUS: string = "+"; break; case MINUS: string = "-"; break; case DIVIDE: string = "/"; break; case MULTIPLY: string = "*"; break; case ASSIGN: string = ":="; break; case ID: string = "ID"; break; case READ: string = "read"; break; case WRITE: string = "write"; break; case LPAREN: string = "("; break; case RPAREN: string = ")"; break; case NUMBER: string = "NUMBER"; break; } emit(string,self,0); if(nextToken == x) { get_nexttoken(); } else { fail(); } return(self); } void fail() { fprintf(stderr,"Parsing failed!\n"); exit(99); } void emit(const char *label,int self,int count, ...) { va_list ap; va_start(ap,count); printf("node%d [label=\"%s\"]\n",self,label); int i; for(i=0; i node%d\n",self,child); } va_end(ap); }