/* File: parse.c Parse arithmetic expressions involving +, -, *, / and (). */ #include #include "token.h" /* Local Types */ enum expr_type {EXPR, TERM, FACTOR, ERROR} ; typedef struct{ enum expr_type type ; int value ; char *err_mesg ; } result_t ; /* Function Prototypes */ result_t ParseEverything(input_t *) ; result_t ParseExpression(input_t *) ; result_t ParseTerm(input_t *) ; result_t ParseFactor(input_t *) ; /* Everything -> Expression EOL */ result_t ParseEverything(input_t *input) { result_t result ; token_t next ; result = ParseExpression(input) ; if (result.type == ERROR) return result ; next = LookAhead(input) ; if (next.kind != EOL) { result.type = ERROR ; result.err_mesg = "Garbage at the end" ; return result ; } return result ; } /* Expression -> Term + Expression -> Term - Expression */ result_t ParseExpression(input_t *input) { int expr_value = 0, sign = 1 ; token_t next ; result_t result ; while(1) { result = ParseTerm(input) ; if (result.type == ERROR) return result ; expr_value = expr_value + sign * result.value ; next = LookAhead(input) ; switch(next.kind) { case UNDEF : /* Bogus, bogus */ fprintf(stderr,"Oops, caught internal error\n") ; exit(1) ; case PLUS : EatToken(input) ; /* consume the '+' */ sign = 1 ; break ; case MINUS : EatToken(input) ; /* consume the '-' */ sign = -1 ; break ; default : result.type = EXPR ; result.value = expr_value ; return result ; } } } /* Term -> Factor * Term -> Factor / Term */ result_t ParseTerm(input_t *input) { int term_value = 1, power = 1 ; token_t next ; result_t result ; while(1) { result = ParseFactor(input) ; if (result.type == ERROR) return result ; if (power == 1) { term_value *= result.value ; } else { term_value /= result.value ; } next = LookAhead(input) ; switch(next.kind) { case UNDEF : /* Bogus, bogus */ fprintf(stderr,"Yikes, caught internal error\n") ; exit(1) ; case TIMES : EatToken(input) ; /* consume the '*' */ power = 1 ; break ; case DIVIDE : EatToken(input) ; /* consume the '/' */ power = -1 ; break ; default : result.type = TERM ; result.value = term_value ; return result ; } } } /* Factor -> ( Expression ) -> Number */ result_t ParseFactor(input_t *input) { int factor_value ; token_t next ; result_t result ; next = LookAhead(input) ; if (next.kind == NUMBER) { EatToken(input) ; /* consume the number */ result.type = FACTOR ; result.value = next.value ; return result ; } if (next.kind != L_PAREN) { result.type = ERROR ; result.err_mesg = "Expecting a number or '('" ; return result ; } EatToken(input) ; /* consume the '(' */ result = ParseExpression(input) ; if (result.type == ERROR) return result ; next = LookAhead(input) ; if (next.kind != R_PAREN) { result.type = ERROR ; result.err_mesg = "Expecting ')'" ; return result ; } EatToken(input) ; /* consume ')' */ result.type = FACTOR ; return result ; } main() { result_t result ; input_t *input ; printf("Enter an expression (<255 char): ") ; input = ReadInput() ; result = ParseEverything(input) ; if (result.type == ERROR) { PrintError(input) ; printf("%s\n", result.err_mesg) ; } else { printf("Value = %d\n", result.value) ; } }