KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lsmp > djep > xjep > TreeUtils


1 /*
2  * Created on 16-Jun-2003 by Rich webmaster@pfaf.org
3  * www.comp.leeds.ac.uk/pfaf/lsmp
4  *
5  * This code is covered by a Creative Commons
6  * Attribution, Non Commercial, Share Alike license
7  * <a HREF="http://creativecommons.org/licenses/by-nc-sa/1.0">License</a>
8  */

9
10 package org.lsmp.djep.xjep;
11
12 import org.nfunk.jep.*;
13 import org.nfunk.jep.type.*;
14
15 /**
16  * A set of Utility functions for working with JEP expression trees.
17  * Main methods are
18  * <ul>
19  * <li> {@link #isConstant isConstant} test if its a constant. Many other is... methods.
20  * <li> {@link #getValue getValue} extracts the value from a node without needing to cast and check types.
21  * </ul>
22  * @author rich
23  */

24 public class TreeUtils {
25     /** Real zero. Note that this is a Double, if a different number
26      * format is needed then this class should be subclassed.
27      */

28     protected static Double JavaDoc ZERO = new Double JavaDoc(0.0);
29     /** Real One */
30     protected static Double JavaDoc ONE = new Double JavaDoc(1.0);
31     /** Real Minus One */
32     protected static Double JavaDoc MINUSONE = new Double JavaDoc(-1.0);
33     /** Complex Zero **/
34     protected static Complex CZERO = new Complex(0.0,0.0);
35     /** Complex One **/
36     protected static Complex CONE = new Complex(1.0,0.0);
37     /** Complex i **/
38     protected static Complex CI = new Complex(0.0,1.0);
39     /** Complex Minus One **/
40     protected static Complex CMINUSONE = new Complex(-1.0,0.0);
41     /** Complex Minus i **/
42     protected static Complex CMINUSI = new Complex(0.0,-1.0);
43     /** Real NaN */
44     protected static Double JavaDoc NAN = new Double JavaDoc(Double.NaN);
45     /** Real positive infinity */
46     protected static Double JavaDoc PosInf = new Double JavaDoc(Double.POSITIVE_INFINITY);
47     /** Real NaN */
48     protected static Double JavaDoc NegInf = new Double JavaDoc(Double.NEGATIVE_INFINITY);
49     
50     /**
51      * default constructor is private class can never in insantated.
52      */

53     public TreeUtils() {}
54     //public static TreeUtils getInstance() { return INSTANCE; }
55

56     /**
57      * Returns the value represented by node
58      * @throws IllegalArgumentException if given something which is not an ASTConstant
59      */

60     public String JavaDoc getName(Node node) throws IllegalArgumentException JavaDoc
61     {
62         if(isVariable(node))
63             return ((ASTVarNode) node).getName();
64         if(isFunction(node))
65             return ((ASTFunNode) node).getName();
66         
67         throw new IllegalArgumentException JavaDoc("Tried to find the name of constant node");
68     }
69
70     /** gets the PostfixMathCommand with a given name. */
71     /*
72     public PostfixMathCommandI getPfmc(String name)
73     {
74         return (PostfixMathCommandI) myFunTab.get(name);
75     }
76     */

77     
78     /**
79      * Returns the value represented by node
80      * @throws IllegalArgumentException if given something which is not an ASTConstant
81      */

82     public Object JavaDoc getValue(Node node) throws IllegalArgumentException JavaDoc
83     {
84         if(!isConstant(node)) throw new IllegalArgumentException JavaDoc("Tried to find the value of a non constant node");
85         return ((ASTConstant) node).getValue();
86     }
87     
88     /**
89      * Returns the double value represented by node
90      * @throws IllegalArgumentException if given something which is not an ASTConstant with a Double value
91      */

92     public double doubleValue(Node node) throws IllegalArgumentException JavaDoc
93     {
94         return ((Double JavaDoc) getValue(node)).doubleValue();
95     }
96     /**
97      * Returns the long value represented by node
98      * @throws IllegalArgumentException if given something which is not an ASTConstant with a Double value
99      */

100     public long longValue(Node node) throws IllegalArgumentException JavaDoc
101     {
102         return ((Number JavaDoc) getValue(node)).longValue();
103     }
104     /**
105      * Returns the int value represented by node
106      * @throws IllegalArgumentException if given something which is not an ASTConstant with a Double value
107      */

108     public int intValue(Node node) throws IllegalArgumentException JavaDoc
109     {
110         return ((Number JavaDoc) getValue(node)).intValue();
111     }
112
113     /**
114      * Returns the Complex value represented by node
115      * @throws IllegalArgumentException if given something which is not an ASTConstant with a Complex value
116      */

117     public Complex complexValue(Node node) throws IllegalArgumentException JavaDoc
118     {
119         return ((Complex) getValue(node));
120     }
121
122     /**
123      * returns true if node is a ASTConstant
124      */

125     public boolean isConstant(Node node)
126     {
127         return (node instanceof ASTConstant);
128     }
129      
130     /**
131      * returns true if node is a ASTConstant with Double value
132      */

133     public boolean isReal(Node node)
134     {
135             return (node instanceof ASTConstant)
136              && ( ((ASTConstant) node).getValue() instanceof Double JavaDoc );
137     }
138     
139     /**
140      * returns true if node is a ASTConstant with Double value representing an integer.
141      */

142     public boolean isInteger(Node node)
143     {
144             if(isReal(node))
145             {
146                 Number JavaDoc val = (Number JavaDoc) ((ASTConstant) node).getValue();
147                 double x = val.doubleValue();
148                 double xInt = Math.rint(x);
149                 return x == xInt;
150             }
151             else return false;
152     }
153
154     /**
155      * returns true if node is a ASTConstant with value Double(0) or Complex(0,0)
156      */

157     public boolean isZero(Node node)
158     {
159            return ( isReal(node)
160                     && ( ((ASTConstant) node).getValue().equals(ZERO)) )
161                 ||( isComplex(node)
162                     && ( ((Complex) ((ASTConstant) node).getValue()).equals(CZERO,0.0) ) );
163     }
164
165     /**
166      * returns true if node is a ASTConstant with value Double(0) or Complex(0,0)
167      * @param tol tolerence for testing for zero
168      */

169     
170     public boolean isZero(Node node,double tol)
171     {
172            return ( isReal(node)
173                     &&
174                     ( (((ASTConstant) node).getValue().equals(ZERO)) )
175                      || Math.abs(doubleValue(node)) < tol )
176                 ||( isComplex(node)
177                     && ( ((Complex) ((ASTConstant) node).getValue()).equals(CZERO,tol) ) );
178     }
179
180     /**
181      * returns true if node is a ASTConstant with value Double(1) or Complex(1,0)
182      */

183     public boolean isOne(Node node)
184     {
185         return ( isReal(node)
186                  && ( ((ASTConstant) node).getValue().equals(ONE)) )
187              ||( isComplex(node)
188                  && ( ((Complex) ((ASTConstant) node).getValue()).equals(CONE,0.0) ) );
189     }
190
191     /**
192      * returns true if node is a ASTConstant with value Double(-1) or Complex(-1,0)
193      */

194     public boolean isMinusOne(Node node)
195     {
196         return ( isReal(node)
197                  && ( ((ASTConstant) node).getValue().equals(MINUSONE)) )
198              ||( isComplex(node)
199                  && ( ((Complex) ((ASTConstant) node).getValue()).equals(CMINUSONE,0.0) ) );
200     }
201     /**
202      * returns true if node is a ASTConstant with a Infinite component
203      * TODO do propper treatment of signed infinity
204      */

205
206     public boolean isInfinity(Node node)
207     {
208         if(isReal(node))
209         {
210             Double JavaDoc dub = (Double JavaDoc) ((ASTConstant) node).getValue();
211             return dub.isInfinite();
212         }
213         if(isComplex(node))
214         {
215             Complex z = (Complex) ((ASTConstant) node).getValue();
216             return Double.isInfinite(z.re())
217                 || Double.isInfinite(z.im());
218         }
219         return false;
220     }
221
222     /**
223      * returns true if node is a ASTConstant with a NaN component
224      */

225     public boolean isNaN(Node node)
226     {
227         if(isReal(node))
228         {
229             Double JavaDoc dub = (Double JavaDoc) ((ASTConstant) node).getValue();
230             return dub.isNaN();
231         }
232         if(isComplex(node))
233         {
234             Complex z = (Complex) ((ASTConstant) node).getValue();
235             return Double.isNaN(z.re())
236                 || Double.isNaN(z.im());
237         }
238         return false;
239     }
240
241     /**
242      * returns true if node is an ASTConstant with a negative Double value
243      */

244     public boolean isNegative(Node node)
245     {
246             return isReal(node)
247                      && ( ((Double JavaDoc) ((ASTConstant) node).getValue()).doubleValue() < 0.0 );
248     }
249
250     /**
251      * returns true if node is an ASTConstant with a positive Double value
252      */

253     public boolean isPositive(Node node)
254     {
255             return isReal(node)
256                      && ( ((Double JavaDoc) ((ASTConstant) node).getValue()).doubleValue() > 0.0 );
257     }
258
259     /**
260      * returns true if node is an ASTConstant of type Complex
261      */

262      public boolean isComplex(Node node)
263      {
264             return isConstant(node)
265                  && ( ((ASTConstant) node).getValue() instanceof Complex );
266      }
267
268     /**
269      * returns true if node is an ASTVarNode
270      */

271     public boolean isVariable(Node node)
272     {
273        return (node instanceof ASTVarNode);
274     }
275     
276     /**
277      * returns true if node is an ASTOpNode
278      */

279     public boolean isOperator(Node node)
280     {
281        return (node instanceof ASTFunNode) && ((ASTFunNode) node).isOperator();
282     }
283
284     public boolean isBinaryOperator(Node node)
285     {
286        if(isOperator(node))
287        {
288             return ((XOperator) ((ASTFunNode) node).getOperator()).isBinary();
289        }
290        return false;
291     }
292
293     public boolean isUnaryOperator(Node node)
294     {
295        if(isOperator(node))
296        {
297             return ((XOperator) ((ASTFunNode) node).getOperator()).isUnary();
298        }
299        return false;
300     }
301
302     /**
303      * returns the operator for a node or null if it is not an operator node.
304      */

305     public Operator getOperator(Node node)
306     {
307        if(isOperator(node))
308         return ((ASTFunNode) node).getOperator();
309        else return null;
310     }
311
312     /**
313      * returns true if node is an ASTFunNode
314      */

315     public boolean isFunction(Node node)
316     {
317        return (node instanceof ASTFunNode);
318     }
319     
320     /**
321      * Sets the children of a node if they have changed for it current children.
322      */

323     public static Node copyChildrenIfNeeded(Node node,Node children[]) throws ParseException
324     {
325         int n=node.jjtGetNumChildren();
326         if(n!=children.length)
327             throw new ParseException("copyChildrenIfNeeded: umber of children of node not the same as supplied children");
328         for(int i=0;i<n;++i)
329             if(node.jjtGetChild(i) != children[i])
330             {
331                 node.jjtAddChild(children[i],i);
332                 children[i].jjtSetParent(node);
333             }
334         return node;
335     }
336
337     /** returns the children of a node as an array of nodes. */
338     static public Node[] getChildrenAsArray(Node node)
339     {
340         int n = node.jjtGetNumChildren();
341         Node[] children = new Node[n];
342         for(int i=0;i<n;++i)
343             children[i]=node.jjtGetChild(i);
344         return children;
345     }
346
347     public Object JavaDoc getCI() { return CI; }
348     public Object JavaDoc getCMINUSI() {return CMINUSI; }
349     public Object JavaDoc getCMINUSONE() {return CMINUSONE; }
350     public Object JavaDoc getCONE() {return CONE; }
351     public Object JavaDoc getCZERO() {return CZERO; }
352     public Object JavaDoc getMINUSONE() {return MINUSONE; }
353     public Object JavaDoc getONE() {return ONE; }
354     public Object JavaDoc getZERO() {return ZERO; }
355     public Object JavaDoc getNAN() { return NAN; }
356     public Object JavaDoc getPositiveInfinity() { return PosInf; }
357     public Object JavaDoc getNegativeInfinity() { return NegInf; }
358     public Object JavaDoc getNumber(double val) { return new Double JavaDoc(val); }
359 }
360
Popular Tags