KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > wizards > templates > PreprocessorParser


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.pde.internal.ui.wizards.templates;
12
13 import java.util.Hashtable JavaDoc;
14 import java.util.Stack JavaDoc;
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_LEAF = -1;
34
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     //private static final int OP_DEFER = 55;
40

41     private IVariableProvider provider;
42     private String JavaDoc line;
43     private Stack JavaDoc exprStack;
44     private int loc;
45     private String JavaDoc tvalue;
46
47     abstract class Node {
48         abstract Object JavaDoc getValue();
49     }
50     class LeafNode extends Node {
51         Object JavaDoc value;
52         LeafNode(Object JavaDoc value) {
53             this.value = value;
54         }
55         public Object JavaDoc getValue() {
56             return value;
57         }
58         public String JavaDoc toString() {
59             if (value != null)
60                 return "leaf[" + value.toString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
61
return "leaf[null]"; //$NON-NLS-1$
62
}
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 JavaDoc getValue() {
77             boolean result = false;
78             Object JavaDoc leftValue = left != null ? left.getValue() : Boolean.FALSE;
79             Object JavaDoc rightValue = right != null ? right.getValue() : Boolean.FALSE;
80
81             if (opcode == OP_NOT && rightValue instanceof Boolean JavaDoc) {
82                 result = rightValue.equals(Boolean.TRUE) ? false : true;
83             } else {
84
85                 if (leftValue instanceof Boolean JavaDoc && rightValue instanceof Boolean JavaDoc) {
86                     boolean bleft = ((Boolean JavaDoc) leftValue).booleanValue();
87                     boolean bright = ((Boolean JavaDoc) 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 JavaDoc && rightValue instanceof String JavaDoc) {
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 JavaDoc toString() {
118             String JavaDoc lstring = left != null ? left.toString() : "*"; //$NON-NLS-1$
119
String JavaDoc rstring = right != null ? right.toString() : "*"; //$NON-NLS-1$
120
return "(" + lstring + "<" + opcode + ">" + rstring + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
121
}
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 JavaDoc();
134     }
135
136     
137     public void setVariableProvider(IVariableProvider provider) {
138         this.provider = provider;
139     }
140
141     public static void main(String JavaDoc[] args) {
142         final Hashtable JavaDoc vars = new Hashtable JavaDoc();
143         vars.put("a", Boolean.FALSE); //$NON-NLS-1$
144
vars.put("b", "3"); //$NON-NLS-1$ //$NON-NLS-2$
145
vars.put("c", Boolean.TRUE); //$NON-NLS-1$
146
PreprocessorParser parser = new PreprocessorParser(new IVariableProvider() {
147             public Object JavaDoc getValue(String JavaDoc variable) {
148                 return vars.get(variable);
149             }
150         });
151         try {
152             boolean value = parser.parseAndEvaluate("!a || (b==\"2\" && c)"); //$NON-NLS-1$
153
System.out.println("Result: "+value); //$NON-NLS-1$
154
} catch (Exception JavaDoc e) {
155             System.out.println(e);
156         }
157     }
158
159     public boolean parseAndEvaluate(String JavaDoc line) throws Exception JavaDoc {
160         reset();
161         this.line = line;
162         //System.out.println("Line: " + line);
163
parse();
164         //printExpression();
165
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 JavaDoc value = entry.root.getValue();
174                 if (value!=null && value instanceof Boolean JavaDoc) {
175                     if (((Boolean JavaDoc)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 JavaDoc {
191         for (;;) {
192             int token = getNextToken();
193             //System.out.println("Token: " + token + ", val=\"" + tvalue+"\"");
194
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 JavaDoc 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); //$NON-NLS-1$
246
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 JavaDoc expected, int token)
300         throws Exception JavaDoc {
301         String JavaDoc message = "Expected " + expected + ", found " + token; //$NON-NLS-1$ //$NON-NLS-2$
302
throw new Exception JavaDoc(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                 // check if we have panding identifier
314
if (variable) {
315                     tvalue = line.substring(vloc, loc);
316                     variable = false;
317                     if (tvalue.equalsIgnoreCase("false")) //$NON-NLS-1$
318
return T_FALSE;
319                     if (tvalue.equalsIgnoreCase("true")) //$NON-NLS-1$
320
return T_TRUE;
321                     return T_VAR;
322                 }
323                 if (string) {
324                     // EOF in string
325
string = false;
326                     return T_ERROR;
327                 }
328                 // regular end of line
329
tvalue = "EOF"; //$NON-NLS-1$
330
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")) //$NON-NLS-1$
357
return T_FALSE;
358                     if (tvalue.equalsIgnoreCase("true")) //$NON-NLS-1$
359
return T_TRUE;
360                     return T_VAR;
361                 }
362                 continue;
363             }
364
365             if (testDoubleToken(c, "!=")) //$NON-NLS-1$
366
return T_NEQ;
367             if (testDoubleToken(c, "==")) //$NON-NLS-1$
368
return T_EQ;
369             if (testDoubleToken(c, "&&")) //$NON-NLS-1$
370
return T_AND;
371             if (testDoubleToken(c, "||")) //$NON-NLS-1$
372
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; //$NON-NLS-1$
382
return T_ERROR;
383         }
384     }
385     private boolean testSingleToken(char c, char expected) {
386         if (c == expected) {
387             tvalue = "" + expected; //$NON-NLS-1$
388
return true;
389         }
390         return false;
391     }
392     private boolean testDoubleToken(char c1, String JavaDoc 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