/** Parser supporting Program 0.5 in Comp 411. Adapted from Java 5.0 code. */ import java.io._ // Boolean Simplifier // This program reads a stream of formulas expressed in parenthesized // prefix syntax and outputs a corresponding stream of simplified formulas. // All tautologies are simplified to "T" and all contradictions to "F". /* The Parser class for the boolean simplifier. The parse routine is a method in Parser called read(); it returns * an instance of the BoolExp abstract syntax Interface. */ class Parser(r: Reader) extends StreamTokenizer(r) { // A Parser is a file containing a textual (ASCII) representation of a BoolExp object. // short names for StreamTokenizer codes import StreamTokenizer.{TT_WORD => WORD, TT_EOF => EOF, TT_EOL => EOL} import BoolExp._ // Convenience constructors def this(text: String) = this(new StringReader(text)); def this(file: File) = this(new BufferedReader(new FileReader(file))); // configure StreamTokenizer portion of this super.resetSyntax(); // the super prefix is forced by a LL type checking bug wordChars('0','9'); wordChars('a','z'); wordChars('A','Z'); whitespaceChars(0,' '); /** Parses the formula expressed in "abbreviated Scheme syntax" in the reader r (a String or a File). It throws * a ParseException if it encounters a syntax error. */ def read(): BoolExp = { var token: Int = nextToken(); if (token == WORD) { if (sval.equals("T")) return Val(true); else if (sval.equals("F")) return Val(false); else return Var(sval); } else if (token == '(') { token = nextToken(); if (token == '!') { val arg: BoolExp = read(); token = nextToken(); // read trailing parenthesis if (token != ')') throw new ParseException("wrong number of arguments to !"); return Not(arg); } else if (token == '&') { val arg1: BoolExp = read(); val arg2: BoolExp = read(); token = nextToken(); // read trailing parenthesis if (token != ')') throw new ParseException("wrong number of arguments to &"); return And(arg1,arg2); } else if (token == '|') { val arg1: BoolExp = read(); val arg2: BoolExp = read(); token = nextToken(); // read trailing parenthesis if (token != ')') throw new ParseException("wrong number of arguments to |"); return Or(arg1,arg2); } else if (token == '>') { val arg1: BoolExp = read(); val arg2: BoolExp = read(); token = nextToken(); // read trailing parenthesis if (token != ')') throw new ParseException("wrong number of arguments to >"); return Implies(arg1,arg2); } else if (token == '?') { val arg1: BoolExp = read(); val arg2: BoolExp = read(); val arg3: BoolExp = read(); token = nextToken(); // read trailing parenthesis if (token != ')') throw new ParseException("wrong number of arguments to ?"); return If(arg1,arg2,arg3); } else throw new ParseException("operator " + toString + " not recognized"); } else if (token == EOF) return null; else if (token == ')') throw new ParseException("unbalanced ')'"); else throw new ParseException("operator " + toString + " not recognized"); } def reduce: String = { val g: BoolExp = read(); val h: IfExp = convertToIf(g); val i: NormExp = normalize(h); val j: NormExp = eval(i, Map.empty); val k: BoolExp = convertToBool(j); k.toString; } } /** Exception class for Parser syntax errors. */ class ParseException(s: String) extends IOException(s)