package calculette; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.Reader; import java.io.StreamTokenizer; import java.io.StringReader; import java.util.HashMap; import java.util.Map; public class Calculette { private final Map operateurs = new HashMap(); public Calculette(Operateur[] ops) { for (Operateur op : ops) { ajouter(op); } } private double expression(StreamTokenizer st) throws ErreurSyntaxiqueException, IOException { switch (st.ttype) { case StreamTokenizer.TT_NUMBER: return st.nval; case StreamTokenizer.TT_WORD: Operateur op = (Operateur) operateurs.get(st.sval); if (op == null) { throw new ErreurSyntaxiqueException(st, "Opérateur inconnu"); } double[] operandes = new double[op.arite()]; for (int i = 0; i < op.arite(); ++i) { st.nextToken(); operandes[i] = expression(st); } return op.evaluer(operandes); default: throw new ErreurSyntaxiqueException(st); } } public void evaluer(Reader entree, PrintWriter sortie, boolean finDeLigne) throws ErreurSyntaxiqueException, IOException { StreamTokenizer st = new StreamTokenizer(entree); st.wordChars('!', '~'); st.eolIsSignificant(finDeLigne); st.nextToken(); while (st.ttype != StreamTokenizer.TT_EOF) { double valeur = expression(st); st.nextToken(); if (st.ttype != (finDeLigne ? StreamTokenizer.TT_EOL : StreamTokenizer.TT_EOF)) { throw new ErreurSyntaxiqueException(st); } sortie.println(valeur); if (finDeLigne) { st.nextToken(); } } } public void ajouter(Operateur op) { operateurs.put(op.symbole(), op); } private static void usage() { System.err.println("java Calculette "); System.exit(1); } public static void main(String[] args) throws FileNotFoundException, IOException, ErreurSyntaxiqueException { if (args.length > 2) { usage(); } Calculette calculette = new Calculette(Operateurs.QUATRE_OPERATIONS); PrintWriter sortie = (args.length == 2 ? new PrintWriter(new FileWriter(args[1])) : new PrintWriter(System.out, true)); // autoflush BufferedReader entree = null; if (args.length >= 1) { entree = new BufferedReader(new FileReader(args[0])); calculette.evaluer(entree, sortie, true); } else { entree = new BufferedReader(new InputStreamReader(System.in)); for (String s = entree.readLine(); s != null; s = entree.readLine()) { calculette.evaluer(new StringReader(s), sortie, false); } } entree.close(); sortie.close(); } }