#include #include "recdesc.h" /* global variables */ int tok; extern FILE *yyin; void start (void) { yyin = fopen("recdesc_in.txt", "r"); tok = yylex(); printf("Recognized %d\n", tok); } void advance(void) { tok = yylex(); printf("Recognized %d\n", tok); } void stop (void) { fclose(yyin); } void error(void) { printf("Error in token %4d\n", tok); } void eat(enum token t) { /* printf("Reading token %4d, expecting %4d\n", tok, t); */ if (tok == t) advance(); else error(); } /* Implementation of the grammar */ void E (void) { eat(NUM); eat(EQ); eat(NUM); printf("Recognized rule E\n"); } /* The original grammar is ambiguous because of - associativity. Solution: introduced right-associativity - construct 'if e then c1 else c2; c3' Solution: Introduced 'begin .. end' Thus, S -> print NUM | if E then S else S | begin S end | S; S is transformed to: S -> print NUM | print NUM ; S if E then S else S | if E then S else S ; S begin S end omitting a rule of the form S -> begin S end; S */ void S (void) { switch (tok) { case PRINT: eat(PRINT); eat(NUM); switch (tok) { case SEMI: eat(SEMI); S(); printf("Recognized rule S 1 semi\n"); break; default: printf("Recognized rule S 1\n"); } break; case IF: eat(IF); E(); eat(THEN); S(); eat(ELSE); S(); switch (tok) { case SEMI: eat(SEMI); S(); printf("Recognized rule S 2 semi\n"); break; default: printf("Recognized rule S 2\n"); } break; case BEG: eat(BEG); S(); eat(END); printf("Recognized rule S 3\n"); break; default: error(); } } /* Main function */ int main (void) { start(); S(); stop(); return 0; }