// Prefix.java: translates to prefix form
import java.io.*;
public class Prefix {
   PrefixScan S;
   char next = 0;
   // Prefix: constructor providing input file name
   public Prefix(PrefixScan s) {
      S = s;
   }
   public void Trans() {
      String res;
      res = P();
      System.out.println(res);
   }
   private String P() {
      String res;
      Scan();
      res = E();
      if (next != '#') Error(1);
      return res;
   } 

   private String E() {
      char save;
      String res, arg1, arg2;
      res = T();
      while (next == '+' || next == '-') {
         save = next;
         arg1 = res;
         Scan();
         arg2 = T();
         res = "(" + save + " " + arg1 + " " + arg2 + ")";
      }
      return res;
   }
   private String T() {
      char save;
      String res, arg1, arg2;
      res = S();
      while (next == '*' || next == '/') {
         save = next;
         arg1 = res;
         Scan();
         arg2 = S();
         res = "(" + save + " " + arg1 + " " + arg2 + ")";
      }
      return res;
   }
   private String S() {
      String res, arg1, arg2;
      res = F();
      if (next == '^') {
         arg1 = res;
         Scan();
         arg2 = S();
         res = "(^ " + arg1 + " " + arg2 + ")";
      }
      return res;
   }
   private String F() {
      char save;
      String res;
      if (Character.isLetter(next) || 
          Character.isDigit(next) ) {
         save = next;
         Scan();
         res = save + "";
      }
      else if (next == '(') {
         Scan();
         res = E();
         if (next == ')') Scan();
         else Error(3);
      }
      else {
         Error(4); res = "keep compiler happy";
      }
      return res;
   } 
   private void Scan() {
      char ch;
      do {
         ch = S.getNextChar();
         if (ch == 65535) System.exit(0);
      } while (Character.isWhitespace((char)ch));
      next = (char)ch;
   }
   private void Error(int n) {
      System.out.println("\n*** ERROR *** " + n);
      System.exit(1);
   }

}

// PrefixScan.java: fetch next character
import java.io.*;
public class PrefixScan {
   private Reader in; // internal file name for input stream
   private boolean fileOpen = false; // is the file open yet?
   private String fileName; // name of input file, if present
   private char ch; // holds next char

   // PrefixScan(): constructor providing no input file name
   public PrefixScan() {
      fileName = "";
   }

   // PrefixScan(String ): constructor providing input file name
   public PrefixScan(String f) {
      fileName = f;
   }

   // getNextChar: fetches next char.  Also opens input file
   public char getNextChar() {
      if (!fileOpen) {
         try {
            fileOpen = true;
            if (fileName == "")
               in = new InputStreamReader(System.in);
            else
               in = new FileReader(fileName);
         }
         catch (IOException exception) {
            System.out.println("Error opening file");
            System.exit(1);
         }
      }
      try {
         ch = (char)in.read();
      }
      catch (IOException exception) {
         System.out.println("Error reading character");
         ch = ' ';
      }
      return ch;
   }
}

// PrefixTest.java: Test the translator to prefix code
import java.io.*;
public class PrefixTest {
   public static void main(String[] args) {
      PrefixScan S; // the scanner
      Prefix P; // the translator
      // pass an input file name if present on command line
      if (args.length > 0)
         S = new PrefixScan(args[0]);
      else
         S = new PrefixScan();
      P = new Prefix(S);
      P.Trans();
   }
}

ten42% java PrefixTest
2+3*4#
(+ 2 (* 3 4))
ten42% java PrefixTest
3*4+5#
(+ (* 3 4) 5)
ten42% java PrefixTest
(2+3)*4#
(* (+ 2 3) 4)
ten42% java PrefixTest
(3*(2+4)/(5+1))-2#
(- (/ (* 3 (+ 2 4)) (+ 5 1)) 2)
ten42% java PrefixTest
(5+3)^(2+1)^2#
(^ (+ 5 3) (^ (+ 2 1) 2))
ten42% java PrefixTest
2+3*4^5*6+7#
(+ (+ 2 (* (* 3 (^ 4 5)) 6)) 7)
ten42% java PrefixTest
2 + (3*(4^5)*6) + 7#
(+ (+ 2 (* (* 3 (^ 4 5)) 6)) 7)
ten42% java PrefixTest
((3^2-4*1*2)^(1/2)-3)/(2*1)#
(/ (- (^ (- (^ 3 2) (* (* 4 1) 2)) (/ 1 2)) 3) (* 2 1))
ten42% java PrefixTest
((2-3)^((4+1)*5)/6-(2-4)*7)-8#
(- (- (/ (^ (- 2 3) (* (+ 4 1) 5)) 6) (* (- 2 4) 7)) 8)
ten42% java PrefixTest
3^4^2#
(^ 3 (^ 4 2))
ten42% java PrefixTest
3^(4^2)#
(^ 3 (^ 4 2))
ten42% java PrefixTest
(3^4)^2#
(^ (^ 3 4) 2)
ten42% java PrefixTest
9 - 5 - 3 #
(- (- 9 5) 3)
ten42% java PrefixTest
8/3/5#
(/ (/ 8 3) 5)
ten42% java PrefixTest
8/(3/5)#
(/ 8 (/ 3 5))
ten42% java PrefixTest
3+1/(7+1/(5*3+1/(1+1/((4*(9*8+1))  ))))#
(+ 3 (/ 1 (+ 7 (/ 1 (+ (* 5 3) (/ 1 (+ 1 (/ 1 (* 4 (+ (* 9 8) 1))))))))))
ten42% java PrefixTest
3+1/(7+1/(5*3+1/(1+1/((4*(9*8+1))+1/(1+1/(1+1/(1+1/(2
+1/(1+1/(3+1/(1+1/(2*7+1/(2+1) ))))))))))))#
(+ 3 (/ 1 (+ 7 (/ 1 (+ (* 5 3) (/ 1 (+ 1 (/ 1 (+ (* 4 (+ (* 9 8) 1)) (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 2 (/ 1 (+ 1 (/ 1 (+ 3 (/ 1 (+ 1 (/ 1 (+ (* 2 7) (/ 1 (+ 2 1)))))))))))))))))))))))))))
ten42% java PrefixTest
1+1/(2+1/(2+1/(2+1/(2+1/(2+1/(2+1/(2+1/(2+1/(2+1/(2+1
/(2+1/(2+1/(2+1/(2+1/(2+1/(2+1/(2+1/(2+1/(2+1/(2  
))))))))))))))))))))#
(+ 1 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 (+ 2 (/ 1 2))))))))))))))))))))))))))))))))))))))))
ten42% java PrefixTest
2+1/(1+1/(2+1/(1+1/(1+1/(4+1/(1+1/(1+1/(6+1/(1+1/(1+1
/(8+1/(1+1/(1+1/(2*5+1/(1+1/(1+1/(2*6+1/(1+1/(1+1/(2*
7+1  ))))))))))))))))))))#
(+ 2 (/ 1 (+ 1 (/ 1 (+ 2 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 4 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 6 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 8 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ (* 2 5) (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ (* 2 6) (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ (* 2 7) 1)))))))))))))))))))))))))))))))))))))))))
ten42% java PrefixTest
1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1
/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1
/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1/(1+1
)))))))))))))))))))))))))))))))))))#
(+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 1 1)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))

In each case above, the prefix output was fed into Lisp and gave
exactly the same result as with the evaluator.
(It was necessary to translate "^" to "expt" and to change one
"1" to a "1.0" in each expression to force evaluation as
a floating point number, rather than as a fraction.)