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;
  }
}