/* FILE: parser.c * PURPOSE: * Functions that implement a Predictive Parser. * The grammar implemented is Program Grammar #1. * (CST 8152 - 98W - Assignment 4) * HISTORY: * Ian D. Allen idallen@freenet.carleton.ca */ //FIXME-- add system includes here //FIXME-- add your local includes here /* Static storage local to this parser: * - the look ahead token * - a statement counter * - the fd of the output stream * - the name of the output stream */ static Token token; /* look-ahead token returned by scanner */ static long stmtcounter = 0; /* count statements parsed */ static char *pinfname = "UNKNOWN-IN"; static FILE *poutfd = NULL; static char *poutfname = "UNKNOWN-OUT"; /* Some macros that make the parser code nicer to read. * We cast the line number into a long int so that it has a known * width when passed to varargs functions on different architectures. */ #define LOOKAHEAD token.type #define LEXEME token.lexeme #define LINENO (long int)token.lineno #define GET_LOOKAHEAD {token = scanner();} //FIXME-- Your prototypes for your static functions go here. /* FUNCTION: * PURPOSE: * A matching function (similar to match() in text figure 2.17). * ALGORITHM: * Check that the lookahead token type matches the TokenType argument. * If it doesn't, print an error message that includes the line * number of the token, the type of token that was expected, and the * type of token that was found; then, exit indicating failure. * Load the next lookahead token. */ //FIXME-- your code goes here /* FUNCTION: * PURPOSE: * Recognize a FACTOR. * ALGORITHM: * * Error messages contain the line number of the token, * the type(s) of token(s) that was/were expected, and the * type of token that was found; then, exit indicating failure. * Load the next lookahead token. */ //FIXME-- your code goes here /* FUNCTION: * PURPOSE: * Recognize a TERM. * ALGORITHM: * * No errors can be detected here. */ //FIXME-- your code goes here /* FUNCTION: * PURPOSE: * Recognize an EXPR. * ALGORITHM: * * No errors can be detected here. */ //FIXME-- your code goes here /* FUNCTION: * PURPOSE: * Recognize an ASST. * ALGORITHM: * */ //FIXME-- your code goes here /* FUNCTION: * PURPOSE: * Recognize a STMT. * ALGORITHM: * * Additional actions to perform: * Save the line number and lexeme that starts the statement. * When the end of the STMT is found, print a message to the * parser output stream indicating the statement number, the * lexeme starting the statement, and the line number of the * start of the statement. */ //FIXME-- your code goes here /* FUNCTION: * PURPOSE: * Recognize a PROGRAM. * ALGORITHM: * * This is the top-level, root parsing function. */ //FIXME-- your code goes here /* FUNCTION: parser() * PURPOSE: * Parse an open input stream. * ALGORITHM: * Initialize the scanner. * Set the statement counter to zero. * Pre-load the first look-ahead token. * Call the root parsing function. * Terminate the scanner. */ void parser( FILE *infd, /* IN: open input file descriptor to read */ char *infname, /* IN: name of open input stream */ FILE *outfd, /* IN: open output file descriptor to write */ char *outfname /* IN: name of open output stream */ ){ /* Save static copies of initialization data for use by Parser. * We don't have to save a copy of the infd since only the * scanner_init call in this function uses it. */ poutfd = outfd; pinfname = infname; poutfname = outfname; fprintf(poutfd, "PARSER: Now parsing '%s' to '%s'\n", pinfname, poutfname); //FIXME-- your code goes here fprintf(poutfd, "PARSER: Parsed %ld statements from '%s' to '%s'.\n", stmtcounter, pinfname, poutfname); /* Undo what was done during the Parser initialization. */ poutfd = NULL; pinfname = NULL; poutfname = NULL; }