import java.io.*; import java.util.Set; import java.util.HashSet; public class Parser { private static final Set BINOPS = new HashSet(); { BINOPS.add('+'); BINOPS.add('-'); BINOPS.add('*'); BINOPS.add('/'); } private static final Object _ = new Parser(); // We have to instanciate // Parser once for the static // initialiser above to run public static class ParseException extends Exception { public ParseException () { super(); } public ParseException (Throwable cause) { super(cause); } } protected static BinOp parseBinOp (ExprTokenizer stream) throws ParseException { Expr left = parseExpression(stream); stream.skipWhitespace(); char op = stream.read(); if (!BINOPS.contains(op)) throw new ParseException(); Expr right = parseExpression(stream); switch (op) { case '+': return new Add(left, right); case '-': return new Subtract(left, right); case '*': return new Multiply(left, right); case '/': return new Divide(left, right); default: System.out.println("The impossible has happened."); System.exit(1); return null; } } protected static Operator parseOperator (ExprTokenizer stream) throws ParseException { char disambiguate = stream.peek(); if (disambiguate == '+') { stream.read(); return new Plus(parseExpression(stream)); } else if (disambiguate == '-') { stream.read(); return new Minus(parseExpression(stream)); } if (disambiguate == '&') { stream.read(); return new Exp(parseExpression(stream)); } else { return parseBinOp (stream); } } public static Expr parseExpression (ExprTokenizer stream) throws ParseException { stream.skipWhitespace(); Character disambiguate = stream.peek(); if (disambiguate.equals('(')) { // Compound Expression stream.read(); Expr e = parseOperator(stream); stream.skipWhitespace(); Character trailing = stream.read(); if (!trailing.equals(')')) throw new ParseException(); return e; } else if (Character.isDigit(disambiguate)) { String token = stream.readToken(); if (null == token) throw new ParseException(); return new Number(Double.parseDouble(token)); } else { throw new ParseException(); } } public static Expr parseExpression (InputStream stream) throws ParseException { return parseExpression(new ExprTokenizer(stream)); } public static Expr parseExpression () throws ParseException { return parseExpression(System.in); } public static void main (String args[]) { PrintInfix printer = new PrintInfix(); while (true) try { ((Writer)(Parser .parseExpression() .accept(printer))) .flush(); System.out.println("\nPrinted"); } catch (Exception e) { e.printStackTrace(); } } }