
import java.io.Reader;
import java.io.InputStreamReader;
import java.util.Hashtable;

/**
 * This class demonstrates how to use a finite state machine within a
 * lexical analyzer.  It parses simple numbers in scientific notation
 * (with no +'s or -'s.  In particular, it recognizes the regular
 * expresssion 
 * [0-9]+ (.[0-9]+)? (E|e[0-9]+)?  */
public class NumReader2 {
    protected Reader _r;
    protected static int DIGIT = 0;
    protected static int DECIMAL = 1;
    protected static int EXP = 2;
    protected static int SIGN = 3;
    protected static int INVALID = 4;
    protected class Pair {
      public int state;
      public int nextchar;

      public Pair(int s, int n) {
        state = s;
        nextchar = n;
      }
    }
    protected Hashtable<Pair,Integer> transitions;

    /**
     * Try and read one number from system.in
     */
    public static void main(String args[]) {
	Reader r = new InputStreamReader(System.in);
	NumReader nr = new NumReader(r);
	if (nr.read()) {
	    System.out.println("Read a number");
	} else {
	    System.out.println("Did not read a number");
	}
    }

    public NumReader2(Reader r) {
	_r = r;
        transitions = new Hashtable<Pair,Integer>();
        transitions.put(new Pair(0, DIGIT), new Integer(1));
        transitions.put(new Pair(1, DECIMAL), new Integer(2));
        transitions.put(new Pair(1, EXP), new Integer(4));
        transitions.put(new Pair(1, DIGIT), new Integer(1));
        transitions.put(new Pair(2, DIGIT), new Integer(3));
        transitions.put(new Pair(3, DIGIT), new Integer(3));
        transitions.put(new Pair(3, EXP), new Integer(4));
        transitions.put(new Pair(4, DIGIT), new Integer(5));
    }

    /**
     * Get the next character from the input stream
     */
    protected char nextChar() {
	try {
	    return (char)_r.read();
	} catch (java.io.IOException e) {
	    System.err.println("Dying!");
	    System.exit(-1);
	}
	return 'c';
    }

    protected int nextCharClass() {
        char c = nextChar();
        if (c >= '0' && c <= '9') {
          return DIGIT;
        }
        if (c == 'E' || c == 'e') {
          return EXP;
        }
        if (c == '.') {
          return DECIMAL;
        }
        if (c == '+' || c == '-') {
          return SIGN;
        }
        return INVALID;
    }


    /**
     * Read a pascal-like literal number
     */
    public boolean read() {
	int state = 0;
	while (1 < 2) {
	    int c = nextCharClass();
            Pair key = new Pair(state, c);
            Integer nextState = transitions.get(key);
            if (nextState == null) {
              return(state == 1 || state == 3 || state == 5);
            }
            state = nextState.intValue();
	}
    }

}
