CS 3723
 Programming Languages 
   Evaluate  Arithmetic  
Expressions (Java)  


Evaluate Arithmetic Expressions as doubles: The program below processes arithmetic expressions made up of single-digit operands. Everything is treated as a double. Using synthesis (that is, using returns from functions to pass information up the parse tree), values are propagated up the tree from the operands at leaves to the root, where the final value is printed.

The Java code below is a quick translation from the C version, which in turn is a modification of "our" standard parser. Here the output is essentially the same as on the previous page.

// Eval.java: evaluate arith. exprs.
class Eval {
   private GetChar getChar = new GetChar();
   private char next;

   private void P() {
      double res;
      scan();
      res = E();
      if (next != '$') error(1);
      else System.out.println("Result: " +
          res);
   }

   private double E() {
      char save;
      double res, arg1, arg2;
      res = T();
      while (next == '+' || next == '-') {
         save = next;
         arg1 = res;
         scan();
         arg2 = T();
         res = evaluate(arg1, save, arg2);
      }
      return res;
   }

   private double T() {
      char save;
      double res, arg1, arg2;
      res = S();
      while (next == '*' || next == '/') {
         save = next;
         arg1 = res;
         scan();
         arg2 = S();
         res = evaluate(arg1, save, arg2);
      }
      return res;
   }

   private double S() {
      char save;
      double res, arg1, arg2;
      res = F();
      if (next == '^') {
         save = next;
         arg1 = res;
         scan();
         arg2 = S();
         res = evaluate(arg1, save, arg2);
      }
      return res;
   }

   private void error(int n) {
      System.out.print("ERROR: " + n + ",");
      System.out.println(" Next: " + next);
      System.exit(1);
   }
   private double F() {
      char save;
      double res;
      if (Character.isDigit(next)) {
         save = next;
         scan();
         return (double)(save - '0');
      }
      else if (next == '(') {
         scan();
         res = E();
         if (next == ')') scan();
         else error(2);
         return res;
      }
      else {
         error(3);
         return 0;
      }  
   }

   private void scan() {
      while (Character.isWhitespace(next =
            getChar.getNextChar()))
         ;
   }

   double evaluate(double arg1, char op,
         double arg2) {
      switch (op) {
      case '+': return arg1 + arg2;
      case '-': return arg1 - arg2;
      case '*': return arg1 * arg2;
      case '/': return arg1 / arg2;
      case '^': return Math.pow(arg1, arg2);
      default: error(4); return 0;
   }
}
   public static void main(String[] args) {
      Eval eval = new Eval();
      eval.P();
   }
}

// GetChar: fetch next char import java.io.*; public class GetChar { private Reader in; // internal file name public GetChar () { in = new InputStreamReader(System.in); } public char getNextChar() { char ch = ' '; // = ' ' for compiler try { ch = (char)in.read(); } catch (IOException e) { System.out.println("Exception"); } return ch; } }


Revision date: 2014-01-01. (Please use ISO 8601, the International Standard.)