/* PURPOSE: * The MAIN function: * Open an input stream; scan, count, and print tokens until EOF. * HISTORY: * Ian D. Allen idallen@freenet.carleton.ca * ALGORITHM: * Initialize a file name buffer * LOOP: * Clear the file name buffer * CALL a function to prompt for a good file name and open the file * UNTIL we have an open stream, or no file name, or hit EOF * IF we have no open stream, quit the program * Initialize the scanner * LOOP: * CALL the scanner to get a token from the stream * PRINT the token and its characteristics * UNTIL we see the final EOF token * PRINT some statistics * Terminate the scanner * Close streams and tidy up buffers * END */ #include #include #include "misc.h" #include "cover.h" #include "buffer.h" #include "my.h" #include "scanner.h" #define FNAME_INIT 20 /* initial size of file name buffer */ #define FNAME_INCR 10 /* incremental increase for file name buffer */ char *cmdname = "UNKNOWN"; /* set by main; used by eprintf */ int main(int argc, char **argv) { FILE *fd; /* descriptor of input stream */ Buffer *fbuf; /* file name buffer */ Token token; /* returned by scanner */ int countIds; /* count of identifiers */ int countOther; /* count of other things */ if( argc >= 1) cmdname = argv[0];/* save command name for eprintf */ /* Note the order of operations here is (1), (2), (3). * * (1) Allocate a File Name Buffer. * LOOP: * Clear the file name buffer. * Prompt for an input file and try (2) to open the input file. * (Note that my_open() may return stdin itself as the open fd.) * UNTIL we have an open stream, or no file name, or hit EOF * IF no stream is open, simply say goodbye and exit. * (3) Initialize the Scanner to read from the open stream. */ fbuf = bf_alloc(FNAME_INIT, FNAME_INCR); /* (1) */ do { bf_clear(fbuf); fd = my_open(fbuf, NULL, MY_READONLY, TRUE); /* (2) */ } while ( fd == NULL && ! BF_EMPTY(fbuf) && ! feof(stdin) ); if( fd == NULL ){ eprintf("No file name given. Goodbye."); return EXIT_SUCCESS;/* not an error */ } printf("Successfully opened input stream '%s'\n", fbuf->buf); scanner_init(fd,fbuf->buf); /* (3) */ printf("Now scanning for tokens from '%s'\n", fbuf->buf); countIds = countOther = 0; /* LOOP: Scan, count, and print tokens until seeing the TT_EOF token. */ do { int count; token = scanner(); count = (token.type == TT_ID) ? ++countIds : ++countOther; printf("%05d type %d '%-12s' line %ld is '%s'\n", count, token.type, token_name(token.type), token.lineno, token.lexeme); } while( token.type != TT_EOF ); printf("File '%s': Identifiers %d, Other %d\n", fbuf->buf, countIds, countOther); /* Note the order of operations following is the exact reverse * of the complementary operations above: (3), (2), (1). * * (3) Terminate the Scanner. * (2) Close or flush the input stream. * (1) Free the file name buffer. */ scanner_term(); /* (3) */ my_close(fd, fbuf->buf); /* (2) */ bf_free(fbuf); /* (1) */ return EXIT_SUCCESS; }