1 11 package org.eclipse.pde.internal.ui.wizards.templates; 12 13 import java.util.Hashtable ; 14 import java.util.Stack ; 15 16 import org.eclipse.pde.ui.templates.IVariableProvider; 17 18 public class PreprocessorParser { 19 private static final int T_VAR = 1; 20 private static final int T_LBR = 2; 21 private static final int T_RBR = 3; 22 private static final int T_NOT = 4; 23 private static final int T_AND = 5; 24 private static final int T_OR = 6; 25 private static final int T_EQ = 7; 26 private static final int T_NEQ = 8; 27 private static final int T_STRING = 9; 28 private static final int T_TRUE = 22; 29 private static final int T_FALSE = 23; 30 private static final int T_ERROR = 99; 31 private static final int T_EOF = 10; 32 33 private static final int OP_AND = 1; 35 private static final int OP_OR = 2; 36 private static final int OP_EQ = 3; 37 private static final int OP_NEQ = 4; 38 private static final int OP_NOT = 5; 39 41 private IVariableProvider provider; 42 private String line; 43 private Stack exprStack; 44 private int loc; 45 private String tvalue; 46 47 abstract class Node { 48 abstract Object getValue(); 49 } 50 class LeafNode extends Node { 51 Object value; 52 LeafNode(Object value) { 53 this.value = value; 54 } 55 public Object getValue() { 56 return value; 57 } 58 public String toString() { 59 if (value != null) 60 return "leaf[" + value.toString() + "]"; return "leaf[null]"; } 63 } 64 65 class ExpressionNode extends Node { 66 int opcode; 67 Node left; 68 Node right; 69 70 public ExpressionNode(Node left, Node right, int opcode) { 71 this.opcode = opcode; 72 this.left = left; 73 this.right = right; 74 } 75 76 public Object getValue() { 77 boolean result = false; 78 Object leftValue = left != null ? left.getValue() : Boolean.FALSE; 79 Object rightValue = right != null ? right.getValue() : Boolean.FALSE; 80 81 if (opcode == OP_NOT && rightValue instanceof Boolean ) { 82 result = rightValue.equals(Boolean.TRUE) ? false : true; 83 } else { 84 85 if (leftValue instanceof Boolean && rightValue instanceof Boolean ) { 86 boolean bleft = ((Boolean ) leftValue).booleanValue(); 87 boolean bright = ((Boolean ) rightValue).booleanValue(); 88 89 switch (opcode) { 90 case OP_AND : 91 result = bleft && bright; 92 break; 93 case OP_OR : 94 result = bleft || bright; 95 break; 96 case OP_EQ : 97 result = bleft == bright; 98 break; 99 case OP_NEQ : 100 result = bleft != bright; 101 break; 102 } 103 } 104 if (leftValue instanceof String && rightValue instanceof String ) { 105 switch (opcode) { 106 case OP_EQ : 107 result = leftValue.equals(rightValue); 108 break; 109 case OP_NEQ : 110 result = leftValue.equals(rightValue); 111 break; 112 } 113 } 114 } 115 return result ? Boolean.TRUE : Boolean.FALSE; 116 } 117 public String toString() { 118 String lstring = left != null ? left.toString() : "*"; String rstring = right != null ? right.toString() : "*"; return "(" + lstring + "<" + opcode + ">" + rstring + ")"; } 122 } 123 124 class RootEntry { 125 Node root; 126 } 127 public PreprocessorParser() { 128 this(null); 129 } 130 131 public PreprocessorParser(IVariableProvider provider) { 132 this.provider = provider; 133 exprStack = new Stack (); 134 } 135 136 137 public void setVariableProvider(IVariableProvider provider) { 138 this.provider = provider; 139 } 140 141 public static void main(String [] args) { 142 final Hashtable vars = new Hashtable (); 143 vars.put("a", Boolean.FALSE); vars.put("b", "3"); vars.put("c", Boolean.TRUE); PreprocessorParser parser = new PreprocessorParser(new IVariableProvider() { 147 public Object getValue(String variable) { 148 return vars.get(variable); 149 } 150 }); 151 try { 152 boolean value = parser.parseAndEvaluate("!a || (b==\"2\" && c)"); System.out.println("Result: "+value); } catch (Exception e) { 155 System.out.println(e); 156 } 157 } 158 159 public boolean parseAndEvaluate(String line) throws Exception { 160 reset(); 161 this.line = line; 162 parse(); 164 return evaluate(); 166 } 167 168 private boolean evaluate() { 169 boolean result = false; 170 if (exprStack.isEmpty()==false) { 171 RootEntry entry = (RootEntry)exprStack.peek(); 172 if (entry.root != null) { 173 Object value = entry.root.getValue(); 174 if (value!=null && value instanceof Boolean ) { 175 if (((Boolean )value).equals(Boolean.TRUE)) 176 result = true; 177 } 178 } 179 } 180 return result; 181 } 182 183 184 private void reset() { 185 loc = 0; 186 tvalue = null; 187 exprStack.clear(); 188 } 189 190 private void parse() throws Exception { 191 for (;;) { 192 int token = getNextToken(); 193 if (token == T_EOF) 195 break; 196 197 if (token == T_VAR) { 198 Node node = new LeafNode(provider.getValue(tvalue.toString())); 199 pushNode(node); 200 continue; 201 } 202 if (token == T_TRUE || token == T_FALSE) { 203 Object value = token==T_TRUE?Boolean.TRUE:Boolean.FALSE; 204 Node node = new LeafNode(value); 205 pushNode(node); 206 continue; 207 } 208 if (token == T_STRING) { 209 Node node = new LeafNode(tvalue); 210 pushNode(node); 211 continue; 212 } 213 214 if (token == T_NOT) { 215 pushNode(OP_NOT); 216 continue; 217 } 218 219 int opcode = 0; 220 221 switch (token) { 222 case T_AND : 223 opcode = OP_AND; 224 break; 225 case T_OR : 226 opcode = OP_OR; 227 break; 228 case T_EQ : 229 opcode = OP_EQ; 230 break; 231 case T_NEQ : 232 opcode = OP_NEQ; 233 break; 234 } 235 if (opcode != 0) { 236 pushNode(opcode); 237 continue; 238 } 239 if (token == T_LBR) { 240 pushRoot(); 241 continue; 242 } 243 if (token == T_RBR) { 244 if (exprStack.isEmpty()) 245 throwUnexpectedToken("not )", token); popRoot(); 247 continue; 248 } 249 } 250 } 251 252 private RootEntry getCurrentRoot() { 253 if (exprStack.isEmpty()) { 254 RootEntry entry = new RootEntry(); 255 exprStack.push(entry); 256 } 257 return (RootEntry) exprStack.peek(); 258 } 259 260 private void replaceRoot(ExpressionNode newRoot) { 261 RootEntry entry = getCurrentRoot(); 262 if (entry.root != null) 263 newRoot.left = entry.root; 264 entry.root = newRoot; 265 } 266 267 private void pushNode(Node node) { 268 RootEntry entry = getCurrentRoot(); 269 if (entry.root == null) 270 entry.root = node; 271 else { 272 ExpressionNode enode = (ExpressionNode) entry.root; 273 if (enode.opcode == OP_NOT) 274 enode.right = node; 275 else { 276 if (enode.left == null) 277 enode.left = node; 278 else 279 enode.right = node; 280 } 281 } 282 } 283 284 private void pushNode(int opcode) { 285 ExpressionNode node = new ExpressionNode(null, null, opcode); 286 replaceRoot(node); 287 } 288 289 private void pushRoot() { 290 exprStack.push(new RootEntry()); 291 } 292 293 private void popRoot() { 294 RootEntry entry = getCurrentRoot(); 295 exprStack.pop(); 296 pushNode(entry.root); 297 } 298 299 private void throwUnexpectedToken(String expected, int token) 300 throws Exception { 301 String message = "Expected " + expected + ", found " + token; throw new Exception (message); 303 } 304 305 306 private int getNextToken() { 307 boolean string = false; 308 boolean variable = false; 309 int vloc = loc; 310 tvalue = null; 311 for (;;) { 312 if (loc == line.length()) { 313 if (variable) { 315 tvalue = line.substring(vloc, loc); 316 variable = false; 317 if (tvalue.equalsIgnoreCase("false")) return T_FALSE; 319 if (tvalue.equalsIgnoreCase("true")) return T_TRUE; 321 return T_VAR; 322 } 323 if (string) { 324 string = false; 326 return T_ERROR; 327 } 328 tvalue = "EOF"; return T_EOF; 331 } 332 char c = line.charAt(loc++); 333 334 if (c == '\"') { 335 if (string) { 336 tvalue = line.substring(vloc, loc - 1); 337 string = false; 338 return T_STRING; 339 } 340 vloc = loc; 341 string = true; 342 continue; 343 } else if (string) 344 continue; 345 346 if (!variable && Character.isJavaIdentifierStart(c)) { 347 variable = true; 348 vloc = loc - 1; 349 continue; 350 } 351 if (variable) { 352 if (!Character.isJavaIdentifierPart(c)) { 353 loc--; 354 tvalue = line.substring(vloc, loc); 355 variable = false; 356 if (tvalue.equalsIgnoreCase("false")) return T_FALSE; 358 if (tvalue.equalsIgnoreCase("true")) return T_TRUE; 360 return T_VAR; 361 } 362 continue; 363 } 364 365 if (testDoubleToken(c, "!=")) return T_NEQ; 367 if (testDoubleToken(c, "==")) return T_EQ; 369 if (testDoubleToken(c, "&&")) return T_AND; 371 if (testDoubleToken(c, "||")) return T_OR; 373 if (testSingleToken(c, '!')) 374 return T_NOT; 375 if (testSingleToken(c, '(')) 376 return T_LBR; 377 if (testSingleToken(c, ')')) 378 return T_RBR; 379 if (c == ' ' || c == '\t' || c == '\n') 380 continue; 381 tvalue = "" + c; return T_ERROR; 383 } 384 } 385 private boolean testSingleToken(char c, char expected) { 386 if (c == expected) { 387 tvalue = "" + expected; return true; 389 } 390 return false; 391 } 392 private boolean testDoubleToken(char c1, String pattern) { 393 if (c1 != pattern.charAt(0)) 394 return false; 395 char c2 = line.charAt(loc); 396 if (c2 == pattern.charAt(1)) { 397 loc++; 398 tvalue = pattern; 399 return true; 400 } 401 return false; 402 } 403 } 404 | Popular Tags |