1 21 22 package net.percederberg.grammatica.test; 23 24 import java.io.StringReader ; 25 import java.util.ArrayList ; 26 import java.util.HashMap ; 27 28 import net.percederberg.grammatica.parser.Node; 29 import net.percederberg.grammatica.parser.ParseException; 30 import net.percederberg.grammatica.parser.Production; 31 import net.percederberg.grammatica.parser.Token; 32 33 39 class ArithmeticCalculator extends ArithmeticAnalyzer { 40 41 44 private HashMap variables; 45 46 49 public ArithmeticCalculator() { 50 this(new HashMap ()); 51 } 52 53 58 public ArithmeticCalculator(HashMap variables) { 59 this.variables = variables; 60 } 61 62 71 public int calculate(String expression) throws Exception { 72 ArithmeticParser parser; 73 Node node; 74 75 parser = new ArithmeticParser(new StringReader (expression), this); 76 parser.prepare(); 77 node = parser.parse(); 78 return ((Integer ) node.getValue(0)).intValue(); 79 } 80 81 88 protected Node exitAdd(Token node) { 89 node.addValue("+"); 90 return node; 91 } 92 93 100 protected Node exitSub(Token node) { 101 node.addValue("-"); 102 return node; 103 } 104 105 112 protected Node exitMul(Token node) { 113 node.addValue("*"); 114 return node; 115 } 116 117 124 protected Node exitDiv(Token node) { 125 node.addValue("/"); 126 return node; 127 } 128 129 136 protected Node exitNumber(Token node) { 137 node.addValue(new Integer (node.getImage())); 138 return node; 139 } 140 141 148 protected Node exitIdentifier(Token node) { 149 node.addValue(variables.get(node.getImage())); 150 return node; 151 } 152 153 160 protected Node exitExpression(Production node) { 161 ArrayList values = getChildValues(node); 162 Integer value1; 163 Integer value2; 164 String op; 165 int result; 166 167 if (values.size() == 1) { 168 result = ((Integer ) values.get(0)).intValue(); 169 } else { 170 value1 = (Integer ) values.get(0); 171 value2 = (Integer ) values.get(2); 172 op = (String ) values.get(1); 173 result = operate(op, value1, value2); 174 } 175 node.addValue(new Integer (result)); 176 return node; 177 } 178 179 186 protected Node exitExpressionRest(Production node) { 187 node.addValues(getChildValues(node)); 188 return node; 189 } 190 191 198 protected Node exitTerm(Production node) { 199 ArrayList values = getChildValues(node); 200 Integer value1; 201 Integer value2; 202 String op; 203 int result; 204 205 if (values.size() == 1) { 206 result = ((Integer ) values.get(0)).intValue(); 207 } else { 208 value1 = (Integer ) values.get(0); 209 value2 = (Integer ) values.get(2); 210 op = (String ) values.get(1); 211 result = operate(op, value1, value2); 212 } 213 node.addValue(new Integer (result)); 214 return node; 215 } 216 217 224 protected Node exitTermRest(Production node) { 225 node.addValues(getChildValues(node)); 226 return node; 227 } 228 229 238 protected Node exitFactor(Production node) throws ParseException { 239 int result; 240 241 if (node.getChildCount() == 1) { 242 result = getIntValue(getChildAt(node, 0), 0); 243 } else { 244 result = getIntValue(getChildAt(node, 1), 0); 245 } 246 node.addValue(new Integer (result)); 247 return node; 248 } 249 250 257 protected Node exitAtom(Production node) { 258 node.addValues(getChildValues(node)); 259 return node; 260 } 261 262 271 private int operate(String op, Integer value1, Integer value2) { 272 int i = value1.intValue(); 273 int j = value2.intValue(); 274 275 switch (op.charAt(0)) { 276 case '+': 277 return i + j; 278 case '-': 279 return i - j; 280 case '*': 281 return i * j; 282 case '/': 283 return i / j; 284 default: 285 throw new RuntimeException ("unknown operator: " + op); 286 } 287 } 288 } 289 | Popular Tags |