/*scanner.c This lexical scanner for arithmetic expressions is part of the term project for the MIT SIPB Crash Course in C for IAP 1999. Copyright (c) 1998 Matthew Belmonte.*/ #include "scanner.h" #include #include #include static char current_char; /*next character to be scanned*/ Token token; /*the token most recently scanned*/ int number; /*if token==NumberToken, here's the #*/ static char next_char() /*all input comes through here*/ { current_char = getchar(); } /*sets the token type and gets the next character*/ static void make_token(t) Token t; { next_char(); token = t; } /*On entry, 'current_char' is a digit. Set the global variable 'number' to the integer represented by the string of digits, and set the global variable 'token' to NumberToken.*/ static void string_to_number() { token = NumberToken; number = 0; /*invariant: The portion of the digit string that is to the left of the position of 'current_char' is the base-ten representation of 'number'. (For ease of specification, define the null string as a valid base-ten representation of the integer 0.)*/ /*In other, less declarative words, 'number' is accumulating the digits by place value.*/ /*bound: the number of digits that remain to be processed*/ do { number = 10*number + (current_char - '0'); next_char(); } while(isdigit(current_char)); } /*initialise the scanner by loading the first character*/ void init_scanner() { next_char(); } /*top-level scanner function*/ void next_token() { while(isspace(current_char)) next_char(); /*skip blanks*/ if(isdigit(current_char)) string_to_number(); else switch(current_char) { case '+': make_token(PlusToken); break; case '-': make_token(MinusToken); break; case '*': make_token(TimesToken); break; case '/': make_token(DivideToken); break; case '(': make_token(LeftParenToken); break; case ')': make_token(RightParenToken); break; case '.': token = PeriodToken; break; /*don't wait for more input*/ default: fprintf(stderr, "Illegal character %c (hex %x)\n", current_char, current_char); } } /*print the type and value of the token - useful in debugging*/ void print_token(t) Token t; { switch(t) { case NumberToken: printf("%d", number); break; case PlusToken: putchar('+'); break; case MinusToken: putchar('-'); break; case TimesToken: putchar('*'); break; case DivideToken: putchar('/'); break; case LeftParenToken: putchar('('); break; case RightParenToken: putchar(')'); break; case PeriodToken: putchar('.'); break; default: printf("undefined token %d", (int)t); } }