KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > idl > ConstExprEvaluator


1 package org.jacorb.idl;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1997-2004 Gerald Brose.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23
24 import java.util.HashMap JavaDoc;
25 import java.lang.Double JavaDoc;
26
27 /**
28  * Based on the MathEvaluator class by The-Son LAI,
29  * <a HREF="mailto:Lts@writeme.com">Lts@writeme.com</a>
30  *
31  * <i>Expression evaluator for IDL constant expression</i>
32  *
33  * Supports the following functions:
34  * +, -, *, /, ^, %, ^, | , <<, >> <br>
35  *
36  * When the getValue() is called, a Double object is returned.
37  * If it returns null, an error occured.<p>
38
39  * @version $Id: ConstExprEvaluator.java,v 1.4 2004/05/06 12:39:58 nicolas Exp $
40  * @author Gerald Brose,
41  * The-Son LAI <a HREF="mailto:Lts@writeme.com">Lts@writeme.com</a>
42  */

43
44 public class ConstExprEvaluator
45 {
46     protected static Operator[] operators = null;
47     private Node node = null;
48     private String JavaDoc expression = null;
49     private HashMap JavaDoc variables = new HashMap JavaDoc();
50
51     /**
52      * creates an empty ConstExprEvaluator.
53      * You need to use setExpression(String s) to assign an expression string to it.
54      */

55
56     public ConstExprEvaluator()
57     {
58         init();
59     }
60
61     /**
62      * creates a ConstExprEvaluator and assign the expression string.
63      */

64
65     public ConstExprEvaluator(String JavaDoc s)
66     {
67         init();
68         setExpression(s);
69     }
70
71     private void init()
72     {
73         if ( operators == null )
74             initializeOperators();
75     }
76
77     /**
78      * sets the expression
79      */

80
81     public void setExpression(String JavaDoc s)
82     {
83         expression = s;
84     }
85
86     /**
87      * resets the evaluator
88      */

89
90     public void reset()
91     {
92         node = null;
93         expression = null;
94         variables = new HashMap JavaDoc();
95     }
96
97
98     /**
99      * evaluates and returns the value of the expression
100      */

101
102     public Double JavaDoc getValue()
103     {
104         if (expression == null)
105             return null;
106
107         try
108         {
109             node = new Node(expression);
110             return evaluate(node);
111         }
112         catch (Exception JavaDoc e)
113         {
114             e.printStackTrace();
115             return null;
116         }
117     }
118
119     private static Double JavaDoc evaluate(Node n)
120     {
121         if ( n.hasOperator() && n.hasChild() )
122         {
123             if ( n.getOperator().getType() == 1 )
124                 n.setValue ( evaluateExpression( n.getOperator(), evaluate( n.getLeft() ), null ) );
125             else if ( n.getOperator().getType() == 2 )
126                 n.setValue( evaluateExpression( n.getOperator(), evaluate( n.getLeft() ), evaluate( n.getRight() ) ) );
127         }
128         return n.getValue();
129     }
130
131
132     private static Double JavaDoc evaluateExpression( Operator o, Double JavaDoc f1, Double JavaDoc f2)
133     {
134         String JavaDoc op = o.getOperator();
135         Double JavaDoc res = null;
136
137         if ( "+".equals(op) )
138             res = new Double JavaDoc( f1.doubleValue() + f2.doubleValue() );
139         else if ( "-".equals(op) )
140             res = new Double JavaDoc( f1.doubleValue() - f2.doubleValue() );
141         else if ( "*".equals(op) )
142             res = new Double JavaDoc( f1.doubleValue() * f2.doubleValue() );
143         else if ( "/".equals(op) )
144             res = new Double JavaDoc( f1.doubleValue() / f2.doubleValue() );
145         else if ( "%".equals(op) )
146             res = new Double JavaDoc( f1.doubleValue() % f2.doubleValue() );
147         else if ( "|".equals(op) )
148             res = new Double JavaDoc(Double.longBitsToDouble( Double.doubleToLongBits( f1.doubleValue()) | Double.doubleToLongBits( f2.doubleValue() ) ));
149         else if ( "&".equals(op) )
150             res = new Double JavaDoc( Double.longBitsToDouble( Double.doubleToLongBits( f1.doubleValue() ) & Double.doubleToLongBits( f2.doubleValue() ) ));
151         else if ( "^".equals(op) )
152             res = new Double JavaDoc( Double.longBitsToDouble( Double.doubleToLongBits( f1.doubleValue() ) ^ Double.doubleToLongBits( f2.doubleValue() ) ));
153         else if ( "<<".equals(op) )
154             res = new Double JavaDoc( Double.longBitsToDouble( Double.doubleToLongBits( f1.doubleValue() ) << Double.doubleToLongBits( f2.doubleValue() ) ));
155         else if ( ">>".equals(op) )
156             res = new Double JavaDoc( Double.longBitsToDouble( Double.doubleToLongBits( f1.doubleValue() ) >> Double.doubleToLongBits( f2.doubleValue() ) ));
157
158         return res;
159     }
160
161     private void initializeOperators()
162     {
163         operators = new Operator[10];
164
165         // bit-wise operators
166
operators[0] = new Operator("|" , 2, 0);
167
168         operators[1] = new Operator("^" , 2, 2);
169
170         operators[2] = new Operator("&" , 2, 4);
171
172         operators[3] = new Operator(">>" , 2, 6);
173         operators[4] = new Operator("<<" , 2, 6);
174         // arithmetic operators
175
operators[5] = new Operator("+" , 2, 8);
176         operators[6] = new Operator("-" , 2, 8);
177
178         operators[7] = new Operator("*" , 2, 10);
179         operators[8] = new Operator("/" , 2, 10);
180         operators[9] = new Operator("%" , 2, 10);
181
182
183     }
184
185     /**
186      * gets the variable's value that was assigned previously
187      */

188
189     public Double JavaDoc getVariable(String JavaDoc s)
190     {
191         return( Double JavaDoc )variables.get(s);
192     }
193
194     private Double JavaDoc getDouble(String JavaDoc s)
195     {
196         if ( s == null )
197             return null;
198
199         Double JavaDoc res = null;
200         try
201         {
202             res = new Double JavaDoc(Double.parseDouble(s));
203         }
204         catch(Exception JavaDoc e)
205         {
206             return getVariable(s);
207         }
208
209         return res;
210     }
211
212     protected Operator[] getOperators()
213     {
214         return operators;
215     }
216
217     protected class Operator
218     {
219         private String JavaDoc op;
220         private int type;
221         private int priority;
222
223         public Operator(String JavaDoc o, int t, int p)
224         {
225             op = o;
226             type = t;
227             priority = p;
228         }
229
230         public String JavaDoc getOperator()
231         {
232             return op;
233         }
234
235         public void setOperator(String JavaDoc o)
236         {
237             op = o;
238         }
239
240         public int getType()
241         {
242             return type;
243         }
244
245         public int getPriority()
246         {
247             return priority;
248         }
249     }
250
251     protected class Node
252     {
253         public String JavaDoc nString = null;
254         public Operator nOperator = null;
255         public Node nLeft = null;
256         public Node nRight = null;
257         public Node nParent = null;
258         public int nLevel = 0;
259         public Double JavaDoc nValue = null;
260
261         public Node(String JavaDoc s) throws Exception JavaDoc
262         {
263             init(null, s, 0);
264         }
265
266         public Node(Node parent, String JavaDoc s, int level) throws Exception JavaDoc
267         {
268             init(parent, s, level);
269         }
270
271         private void init(Node parent, String JavaDoc s, int level) throws Exception JavaDoc
272         {
273             s = removeIllegalCharacters(s);
274             s = removeBrackets(s);
275             s = addZero(s);
276             if ( checkBrackets(s) != 0 )
277                 throw new Exception JavaDoc("Wrong number of brackets in [" + s + "]");
278
279             nParent = parent;
280             nString = s;
281             nValue = getDouble(s);
282             nLevel = level;
283             int sLength = s.length();
284             int inBrackets = 0;
285             int startOperator = 0;
286
287             for (int i=0; i<sLength; i++)
288             {
289                 if ( s.charAt(i) == '(' )
290                     inBrackets++;
291                 else if ( s.charAt(i) == ')' )
292                     inBrackets--;
293                 else
294                 {
295                     // the expression must be at "root" level
296
if ( inBrackets == 0 )
297                     {
298                         Operator o = getOperator(nString,i);
299                         if ( o != null )
300                         {
301                             // if first operator or lower priority operator
302
if ( nOperator == null || nOperator.getPriority() >= o.getPriority() )
303                             {
304                                 nOperator = o;
305                                 startOperator = i;
306                             }
307                         }
308                     }
309                 }
310             }
311
312             if ( nOperator != null )
313             {
314                 // one operand, should always be at the beginning
315
if ( startOperator==0 && nOperator.getType() == 1 )
316                 {
317                     // the brackets must be ok
318
if ( checkBrackets( s.substring( nOperator.getOperator().length() ) ) == 0 )
319                     {
320                         nLeft =
321                         new Node( this, s.substring( nOperator.getOperator().length() ) , nLevel + 1);
322                         nRight = null;
323                         return;
324                     }
325                     else
326                         throw new Exception JavaDoc("Error during parsing... missing brackets in [" + s + "]");
327                 }
328                 // two operands
329
else if ( startOperator > 0 && nOperator.getType() == 2 )
330                 {
331                     nOperator = nOperator;
332                     nLeft =
333                     new Node( this, s.substring(0, startOperator), nLevel + 1 );
334                     nRight =
335                     new Node( this, s.substring(startOperator + nOperator.getOperator().length()), nLevel + 1);
336                 }
337             }
338         }
339
340         private Operator getOperator(String JavaDoc s, int start)
341         {
342             Operator[] operators = getOperators();
343             String JavaDoc temp = s.substring(start);
344             temp = getNextWord(temp);
345             for (int i=0; i<operators.length; i++)
346             {
347                 if ( temp.startsWith(operators[i].getOperator()) )
348                     return operators[i];
349             }
350             return null;
351         }
352
353         private String JavaDoc getNextWord(String JavaDoc s)
354         {
355             int sLength = s.length();
356             for (int i=1; i<sLength; i++)
357             {
358                 char c = s.charAt(i);
359                 if ( (c > 'z' || c < 'a') && (c > '9' || c < '0') )
360                     return s.substring(0, i);
361             }
362             return s;
363         }
364
365         /**
366          * checks if there is any missing brackets
367          * @return true if s is valid
368          */

369         protected int checkBrackets(String JavaDoc s)
370         {
371             int sLength = s.length();
372             int inBracket = 0;
373
374             for (int i=0; i<sLength; i++)
375             {
376                 if ( s.charAt(i) == '(' && inBracket >= 0 )
377                     inBracket++;
378                 else if ( s.charAt(i) == ')' )
379                     inBracket--;
380             }
381
382             return inBracket;
383         }
384
385         /**
386          * returns a string that doesnt start with a + or a -
387          */

388         protected String JavaDoc addZero(String JavaDoc s)
389         {
390             if ( s.startsWith("+") || s.startsWith("-") )
391             {
392                 int sLength = s.length();
393                 for (int i=0; i<sLength; i++)
394                 {
395                     if ( getOperator(s, i) != null )
396                         return "0" + s;
397                 }
398             }
399
400             return s;
401         }
402
403
404         protected boolean hasChild()
405         {
406             return ( nLeft != null || nRight != null );
407         }
408
409         protected boolean hasOperator()
410         {
411             return ( nOperator != null );
412         }
413
414         protected boolean hasLeft()
415         {
416             return ( nLeft != null );
417         }
418
419         protected Node getLeft()
420         {
421             return nLeft;
422         }
423
424         protected boolean hasRight()
425         {
426             return ( nRight != null );
427         }
428
429         protected Node getRight()
430         {
431             return nRight;
432         }
433
434         protected Operator getOperator()
435         {
436             return nOperator;
437         }
438
439         protected int getLevel()
440         {
441             return nLevel;
442         }
443
444         protected Double JavaDoc getValue()
445         {
446             return nValue;
447         }
448
449         protected void setValue(Double JavaDoc f)
450         {
451             nValue = f;
452         }
453
454         protected String JavaDoc getString()
455         {
456             return nString;
457         }
458
459         /**
460          * Removes spaces, tabs and brackets at the begining
461          */

462
463         public String JavaDoc removeBrackets(String JavaDoc s)
464         {
465             String JavaDoc res = s;
466             if ( s.length() > 2 && res.startsWith("(") && res.endsWith(")") && checkBrackets(s.substring(1,s.length()-1)) == 0 )
467             {
468                 res = res.substring(1, res.length()-1 );
469             }
470             if ( res != s )
471                 return removeBrackets(res);
472             else
473                 return res;
474         }
475
476         /**
477          * Removes illegal characters
478          */

479
480         public String JavaDoc removeIllegalCharacters(String JavaDoc s)
481         {
482             char[] illegalCharacters = { ' ' };
483             String JavaDoc res = s;
484
485             for ( int j=0; j<illegalCharacters.length; j++)
486             {
487                 int i = res.lastIndexOf(illegalCharacters[j], res.length());
488                 while ( i != -1 )
489                 {
490                     String JavaDoc temp = res;
491                     res = temp.substring(0,i);
492                     res += temp.substring(i + 1);
493                     i = res.lastIndexOf(illegalCharacters[j], s.length());
494                 }
495             }
496             return res;
497         }
498
499     }
500 }
501
Popular Tags