Scanner Implementation
#include <cctype> #include <iostream> #include "scan.h" using namespace std; const char *Scanner::m_codenames[] = { "tok_id", "tok_lit", "tok_left", "tok_right", "tok_splat", "tok_slash", "tok_plus", "tok_minus", "tok_asst", "tok_semi", "tok_EOF" }; /* Read and return the next token. This also updates the current token to whatever was read. */ const Scanner::Token & Scanner::next_tok() { // The text of the token. string retext; // The >> will skip leading blanks. char inch; if(!(m_in >> inch)) return m_curr = Token(tok_EOF, "$EOF"); // Let's see what we got. switch(inch) { // A _real_ language would have ranges for this. case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* A constant. */ do { retext += inch; m_in.get(inch); } while(isdigit(inch)); m_in.unget(); return m_curr = Token(tok_lit, retext); // Gak! Identifier. case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': /* A constant. */ do { retext += inch; m_in.get(inch); } while(isalpha(inch) || isdigit(inch)); m_in.unget(); return m_curr = Token(tok_id, retext); case '(': return m_curr = Token(tok_left, "("); case ')': return m_curr = Token(tok_right, ")"); case '*': return m_curr = Token(tok_splat, "*"); case '/': return m_curr = Token(tok_slash, "/"); case '+': return m_curr = Token(tok_plus, "+"); case '-': return m_curr = Token(tok_minus, "-"); case ';': return m_curr = Token(tok_semi, "-"); case ':': m_in.get(inch); if(inch == '=') return m_curr = Token(tok_asst, ":="); else throw BadInputCharacter(inch); default: throw BadInputCharacter(inch); } }