Java LISP implementation almost working -


package pj2; import java.util.*;  public class simplelispexpressionevaluator {     // current input lisp expression     private string inputexpr;      // main expression stack & current operation stack, see algorithm in evaluate()     private stack<object> exprstack;     private stack<double> currentopstack;       // default constructor     // set inputexpr ""      // create stack objects     public simplelispexpressionevaluator()     {     // add statements         inputexpr = "";         exprstack = new stack<object>();         currentopstack = new stack<double>();     }      // default constructor     // set inputexpr inputexpression      // create stack objects     public simplelispexpressionevaluator(string inputexpression)      {     // add statements         if(inputexpression == null)         {             throw new simplelispexpressionevaluatorexception();         }          inputexpr = inputexpression;         exprstack = new stack<object>();         currentopstack = new stack<double>();      }      // set inputexpr inputexpression      // clear stack objects     public void reset(string inputexpression)      {     // add statements      if(inputexpression == null)      {          throw new simplelispexpressionevaluatorexception();      }       inputexpr = inputexpression;      exprstack.clear();      currentopstack.clear();     }      // function evaluate current operator operands     // see complete algorithm in evaluate()     //     // main steps:     //      pop operands exprstack , push them onto      //          currentopstack until find operator     //      apply operator operands on currentopstack     //          push result exprstack     //     private void evaluatecurrentoperation()     {     // add statements         string currop;         boolean numeric = true;         do{             currop = (string.valueof(exprstack.pop()));              try{                 double number = double.parsedouble(currop);                 currentopstack.push(number);              }catch(numberformatexception nfe){                 numeric = false;             }         } while(numeric);           double result;         switch (currop) {             case "*":                 result = currentopstack.pop();                 while(!currentopstack.isempty()){                     result *= currentopstack.pop();                 }                 break;             case "/":                 result = currentopstack.pop();                 while(!currentopstack.isempty()){                     result /= currentopstack.pop();                 }                 break;             case "+":                 result = currentopstack.pop();                 while(!currentopstack.isempty()){                     result += currentopstack.pop();                 }                 break;             case "-":                 result = currentopstack.pop();                 while(!currentopstack.isempty()){                     result -= currentopstack.pop();                 }                 break;              default:                 result = currentopstack.pop();                 break;         }          exprstack.push(result);      }      /**      * function evaluates current lisp expression in inputexpr      * return result of expression       *      * algorithm:        *      * step 1   scan tokens in string.      * step 2       if see operand, push operand object onto exprstack      * step 3           if see "(", next token should operator      * step 4       if see operator, push operator object onto exprstack      * step 5       if see ")", steps 6,7,8 in evaluatecurrentoperation() :      * step 6           pop operands , push them onto currentopstack       *                  until find operator      * step 7           apply operator operands on currentopstack      * step 8           push result exprstack      * step 9    if run out of tokens, value on top of exprstack      *           result of expression.      */     public double evaluate()     {         // outline given...         // need add statements/local variables         // may delete or modify statements in method          // use scanner tokenize inputexpr         scanner inputexprscanner = new scanner(inputexpr);          // use 0 or more white space delimiter,         // breaks string single character tokens         inputexprscanner = inputexprscanner.usedelimiter("\\s*");          // step 1: scan tokens in string.         while (inputexprscanner.hasnext())         {              // step 2: if see operand, push operand object onto exprstack             if (inputexprscanner.hasnextint())             {                 // force scanner grab of digits                 // otherwise, 1 char                 string datastring = inputexprscanner.findinline("\\d+");          // more ...                 exprstack.push(double.parsedouble(datastring));             }             else             {                 // next token, 1 char in string token                 string atoken = inputexprscanner.next();                 char item = atoken.charat(0);                  switch (item)                 {                 case '(':                     break;                  case ')':                     evaluatecurrentoperation();                     break;                   case'*':                     exprstack.push("*");                     break;                  case'+':                     exprstack.push("+");                     break;                   case'/':                     exprstack.push("/");                     break;                  case'-':                     exprstack.push("-");                     break;                    // step 3: if see "(", next token shoube operator                 // step 4: if see operator, push operator object onto exprstack                 // step 5: if see ")"  steps 6,7,8 in evaluatecurrentoperation() :                     default:  // error                         throw new simplelispexpressionevaluatorexception(item + " not legal expression operator");                 } // end switch             } // end else         } // end while          // step 9: if run out of tokens, value on top of exprstack         //         result of expression.         //         //         return result         return double.parsedouble(string.valueof(exprstack.pop()));     }       //=====================================================================      // static method used main()     private static void evaluateexprtest(string s, simplelispexpressionevaluator expr)     {         double result;         system.out.println("expression " + s);     expr.reset(s);         result = expr.evaluate();         system.out.printf("result %.2f\n", result);         system.out.println("-----------------------------");     }      // define few test cases, exception may happen      public static void main (string args[])     {         simplelispexpressionevaluator expr= new simplelispexpressionevaluator();         string test1 = "(+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)))";         string test2 = "(+ (- 632) (* 21 3 4) (/ (+ 32) (* 1) (- 21 3 1)))";         string test3 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 1) (- 2 1 )))";         string test4 = "(+ (/2))";         string test5 = "(+ (/2 3 0))";         string test6 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 3) (- 2 1 ))))";         string test7 = "( + 100 )";         string test8 = "( + 100 5 5 5 )";         string test9 = "(*(/100 5)4      10)";         string test10 ="( + 100 )";         string test11 ="( + ( - 6 ) ( * 2 3 4 ) ( / ( + 3 ) ( * 1 ) ( - 2 3 1 ) ) )";         string test12 ="( + ( - 632 ) ( * 21 3 4 ) ( / ( + 32 ) ( * 1 ) ( - 21 3 1 ) ) )";         string test13 ="";         string test14 ="";      evaluateexprtest(test1, expr);     evaluateexprtest(test2, expr);     evaluateexprtest(test3, expr);     evaluateexprtest(test4, expr);     evaluateexprtest(test5, expr);     evaluateexprtest(test6, expr);     evaluateexprtest(test7, expr);     evaluateexprtest(test8, expr);     evaluateexprtest(test9, expr);     evaluateexprtest(test10, expr);     evaluateexprtest(test11, expr);     evaluateexprtest(test12, expr);     //evaluateexprtest(test13, expr);     //evaluateexprtest(test14, expr);     } } 

when run tests 3,4,5,7,8,9,10 work correctly based on: http://joeganley.com/code/jslisp.html

expression (+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1))) result 28.50 ----------------------------- expression (+ (- 632) (* 21 3 4) (/ (+ 32) (* 1) (- 21 3 1))) result 885.88 ----------------------------- expression (+ (/ 2) (* 2) (/ (+ 1) (+ 1) (- 2 1 ))) result 5.00 ----------------------------- expression (+ (/2)) result 2.00 ----------------------------- expression (+ (/2 3 0)) result infinity ----------------------------- expression ( + 100 ) result 100.00 ----------------------------- expression ( + 100 5 5 5 ) result 115.00 ----------------------------- expression (*(/100 5)4      10) result 800.00 ----------------------------- expression ( + 100 ) result 100.00 ----------------------------- expression ( + ( - 6 ) ( * 2 3 4 ) ( / ( + 3 ) ( * 1 ) ( - 2 3 1 ) ) ) result 28.50 ----------------------------- expression ( + ( - 632 ) ( * 21 3 4 ) ( / ( + 32 ) ( * 1 ) ( - 21 3 1 ) ) ) result 885.88 ----------------------------- 

these results occur when remove test 6 because gives exception , stops executing. idea on i've gone wrong?

error if 6 uncommented out:

exception in thread "main" java.util.emptystackexception     @ java.util.stack.peek(unknown source)     @ java.util.stack.pop(unknown source)     @ pj2.simplelispexpressionevaluator.evaluatecurrentoperation(simplelispexpressionevaluator.java:143)     @ pj2.simplelispexpressionevaluator.evaluate(simplelispexpressionevaluator.java:248)     @ pj2.simplelispexpressionevaluator.evaluateexprtest(simplelispexpressionevaluator.java:292)     @ pj2.simplelispexpressionevaluator.main(simplelispexpressionevaluator.java:321) 

that's not lisp. that's arithmetic expressions in prefix form. 0.1% of lisp. lisp bit more: functions, symbols, cons cells, list operations, ...

your test expression 6 has parenthesis @ end.

generally should develop code syntax errors can detected. means error detection, error handling , error reporting. typical lisp system (say, sbcl, clisp, ...) report parenthesis user in plain english.


Comments

Popular posts from this blog

android - getbluetoothservice() called with no bluetoothmanagercallback -

sql - ASP.NET SqlDataSource, like on SelectCommand -

ios - Undefined symbols for architecture armv7: "_OBJC_CLASS_$_SSZipArchive" -