1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | /* SI 413 Fall 2012 * This is a hand-coded scanner for the simple calculator * language in the slides. It is based explicitly on the * finite automaton. */ #include <iostream> #include <string> #include <cstdlib> //-- I need this for atoi #include <cstdio> //-- Needed for EOF constant using namespace std; #include "bisoncalc.tab.hpp" // Header file generated by bison /* This is the scanner. It reads in characters and returns * the type of the token, as an integer code. */ int yylex() { bool done = false; int state = 0; // this is the start state. string val; while(!done) { char c = cin.get(); switch(state) { case 0: switch(c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': val += c; state = 1; break; case '+': case '-': val += c; state = 2; break; case '*': case '/': val += c; state = 3; break; case ';': val += c; state = 4; break; case '(': val += c; state = 5; break; case ')': val += c; state = 6; break; case ' ': case '\t': case '\n': state = 0; break; case EOF: return 0; break; default: cin.putback(c); done = true; break; } break; case 1: switch(c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': val += c; state = 1; break; default: cin.putback(c); done = true; break; } break; case 2: switch(c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': val += c; state = 1; break; default: cin.putback(c); done = true; break; } break; case 3: case 4: case 5: case 6: cin.putback(c); done = true; break; } // end switch(state) } // end while(!done) // Now we're done. The only non-final state is 0. switch(state) { case 0: cerr << "Unrecognized token!" << endl; exit(1); case 1: yylval.val = atoi(val.c_str()); return NUM; case 2: yylval.sym = val[0]; return OPA; case 3: yylval.sym = val[0]; return OPM; case 4: return STOP; case 5: return LP; case 6: return RP; } } |