fork download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.util.*;
  4. import java.lang.*;
  5. import java.io.*;
  6.  
  7. /* Name of the class has to be "Main" only if the class is public. */
  8. class Ideone
  9. {
  10. public static void main (String[] args) throws java.lang.Exception
  11. {
  12. System.out.println(eval("2^3^2")); // this should be 512, i.e. 2^(3^2)
  13. System.out.println(eval("2*3^2")); // this should be 18, i.e. 2*(3^2)
  14. }
  15. static double eval(final String str) {
  16. return new Object() {
  17. int pos = -1, ch;
  18.  
  19. void nextChar() {
  20. ch = (++pos < str.length()) ? str.charAt(pos) : -1;
  21. }
  22.  
  23. boolean eat(int charToEat) {
  24. while (ch == ' ') nextChar();
  25. if (ch == charToEat) {
  26. nextChar();
  27. return true;
  28. }
  29. return false;
  30. }
  31.  
  32. double parse() {
  33. nextChar();
  34. double x = parseExpression();
  35. if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
  36. return x;
  37. }
  38.  
  39. // Grammar:
  40. // expression = term | expression `+` term | expression `-` term
  41. // term = factor | term `*` factor | term `/` factor
  42. // factor = `+` factor | `-` factor | `(` expression `)`
  43. // | number | functionName factor | factor `^` factor
  44.  
  45. double parseExpression() {
  46. double x = parseTerm();
  47. for (;;) {
  48. if (eat('+')) x += parseTerm(); // addition
  49. else if (eat('-')) x -= parseTerm(); // subtraction
  50. else return x;
  51. }
  52. }
  53.  
  54. double parseTerm() {
  55. double x = parseFactor();
  56. for (;;) {
  57. if (eat('*')) x *= parseFactor(); // multiplication
  58. else if (eat('/')) x /= parseFactor(); // division
  59. else if (eat('^')) x = Math.pow(x, parseFactor()); //exponentiation -> Moved in to here. So the problem is fixed
  60. else return x;
  61. }
  62. }
  63.  
  64. double parseFactor() {
  65. if (eat('+')) return parseFactor(); // unary plus
  66. if (eat('-')) return -parseFactor(); // unary minus
  67.  
  68. double x;
  69. int startPos = this.pos;
  70. if (eat('(')) { // parentheses
  71. x = parseExpression();
  72. eat(')');
  73. } else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
  74. while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
  75. x = Double.parseDouble(str.substring(startPos, this.pos));
  76. } else if (ch >= 'a' && ch <= 'z') { // functions
  77. while (ch >= 'a' && ch <= 'z') nextChar();
  78. String func = str.substring(startPos, this.pos);
  79. x = parseFactor();
  80. if (func.equals("sqrt")) x = Math.sqrt(x);
  81. else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
  82. else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
  83. else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
  84. else throw new RuntimeException("Unknown function: " + func);
  85. } else {
  86. throw new RuntimeException("Unexpected: " + (char)ch);
  87. }
  88.  
  89. //if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation -> This is causing a bit of problem
  90.  
  91. return x;
  92. }
  93. }.parse();
  94. }
  95. }
Success #stdin #stdout 0.06s 28092KB
stdin
Standard input is empty
stdout
64.0
36.0