////////////////////////////////////////////////////////////////////////////////////////////////// //Programmer: Jason Bouchard //Project: Project 1 //Course: CS 343 //Description: // Recursive - Descent Parser to parse and evaluate arithmetic expressions // involving integer constants. // //Compile Instructions: gcc -Wall -lm //Execution Instructions: then follow instructions: input legal expressions, hit enter. // ////////////////////////////////////////////////////////////////////////////////////////////////// //Include statements. #include #include #include #include //Global Variables, Structures, and Type Definitions typedef enum { PLUS, MINUS, DIVIDE, MULT, REMAINDER, POWER, LPAREN, RPAREN, NUMBER, ERROR, EOL }TokenType; struct Token{ TokenType type; //holds the typedef int i_value; //holds the int value int i_curr_char;//holds the curr char }; struct Token token; //Method Prototype void command(void); int expr(void); int term(void); int power(void); int factor(void); int factor1(void); void error(void); void parse(void); void match(TokenType tkType); TokenType getToken(void); void list(); //***************************************************** //Method: main //***************************************************** int main (){ printf("\nInput:\n"); parse(); return 0; }// end main //***************************************************** //Method: parse // // void parse(void){ getToken(); command(); printf("parseend\n"); } // // end parse. //***************************************************** //***************************************************** //Method: getToken // // TokenType getToken(void){ //printf("\nOutput:\n"); while ((token.i_curr_char=getchar()) == ' '); //Skip Blanks if(isdigit(token.i_curr_char)){ token.type=NUMBER; token.i_value=0; while(isdigit(token.i_curr_char)){ token.i_value=10*token.i_value+token.i_curr_char - '0'; token.i_curr_char=getchar(); }//end while ungetc(token.i_curr_char, stdin); printf("%d\tNUMBER \n", token.i_value); return NUMBER; }else{ switch(token.i_curr_char){ case '(': token.type=LPAREN; printf("%c\tLPAREN\n",token.i_curr_char); return LPAREN; break; case ')': token.type=RPAREN; printf("%c\tRPAREN\n",token.i_curr_char); return RPAREN; break; case '+': token.type=PLUS; printf("%c\tPLUS\n",token.i_curr_char); return PLUS; break; case '-': token.type=MINUS; printf("%c\tMINUS\n",token.i_curr_char); return MINUS; break; case '/': token.type=DIVIDE; printf("%c\tDIVIDE\n",token.i_curr_char); return DIVIDE; break; case '*': token.type=MULT; printf("%c\tMULT\n",token.i_curr_char); return MULT; break; case '^': token.type=POWER; printf("%c\tPOWER\n",token.i_curr_char); return POWER; break; case '%': token.type=REMAINDER; printf("%c\tREMAINDER\n",token.i_curr_char); return REMAINDER; break; case '\n': token.type=EOL; printf("EOL\n"); return EOL; break; default: token.type=ERROR; printf("ERROR: %c\n", token.i_curr_char); return ERROR; break; }//end switch return ERROR; }//end if else }//end getToken. // // end getToken. //***************************************************** //***************************************************** //Method: command // // void command(void){ //command -> expr '\n' int result = expr(); if (token.type == EOL){ printf("\n\nResult: %d\n", result); }else{ printf("Command Error\n"); error(); // parse error. }//end if } // // end command. //***************************************************** //***************************************************** //Method: expr // // int expr(void){ //expr -> term{+term | -term} int result = term(); while (token.type == PLUS || token.type == MINUS){ if(token.type == PLUS){ match(PLUS); result+=term(); }else{ match(MINUS); result=result-term(); }//end if else }//end while return result; } // // end expr. //***************************************************** //***************************************************** //Method: term // // int term(void){ //term -> power {*power|/power|%power} int result = power(); while (token.type == MULT || token.type == DIVIDE || token.type == REMAINDER){ if(token.type == MULT){ match(MULT); result=result*power(); }else if (token.type == DIVIDE){ match(DIVIDE); result=result/power(); }else{ match(REMAINDER); result=result%power(); }//end if else }//end while. return result; } // // end term. //***************************************************** //***************************************************** //Method: power // // int power(void){ //power -> factor[^power] int result = factor(); if (token.type == POWER){ match(POWER); result = (int)pow((double)result,(double)power()); }//end if return result; } // // end power. //***************************************************** //***************************************************** //Method: factor // // int factor(void){ //factor -> [-]factor1 int result;// = factor1(); if(token.type == MINUS){ match(MINUS); result=(-1)*factor1(); return result; } result=factor1(); return result; } // // end factor. //***************************************************** //***************************************************** //Method: factor1 // // int factor1(void){ //factor1 -> (expr)|Number int result; if(token.type == LPAREN){ match(LPAREN); result=expr(); match(RPAREN); }else{ //match(NUMBER); getToken(); result=token.i_value; } return result; } // // end factor. //***************************************************** //***************************************************** //Method: error // // void error(void){ printf("\n!?!?Parse Error!?!?\n"); exit(1); } // // end error. //***************************************************** //***************************************************** //Method: match // // void match(TokenType tkType){ if(token.type == tkType){ getToken(); }else{ printf("match ERROR: %c\n", token.i_curr_char); list(); error(); }//end if } // // end match. //***************************************************** //method list used in debugging to view variables in the struct. void list(){ switch(token.type){ case PLUS: printf("Token Type: PLUS\n"); break; case MINUS: printf("Token Type: MINUS\n"); break; case DIVIDE: printf("Token Type: DIVIDE\n"); break; case MULT: printf("Token Type: MULT\n"); break; case REMAINDER: printf("Token Type: REMAINDER\n"); break; case POWER: printf("Token Type: POWER\n"); break; case LPAREN: printf("Token Type: LPAREN\n"); break; case RPAREN: printf("Token Type: RPAREN\n"); break; case NUMBER: printf("Token Type: NUMBER\n"); break; case EOL: printf("Token Type: EOL\n"); break; default: printf("ERROR\n"); }//end switch printf("Token value: %d\n",token.i_value); printf("Token curr char: %c\n\n",token.i_curr_char); }