KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > tools > scriptengine > core > util > TreeNormalizer


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, is permitted provided that the following conditions are met: -
6  * Redistributions of source code must retain the above copyright notice, this
7  * list of conditions and the following disclaimer. - Redistributions in binary
8  * form must reproduce the above copyright notice, this list of conditions and
9  * the following disclaimer in the documentation and/or other materials
10  * provided with the distribution. - All advertising materials mentioning
11  * features or use of this software must display the following acknowledgment:
12  * "This product includes Djeneric." - Products derived from this software may
13  * not be called "Djeneric" nor may "Djeneric" appear in their names without
14  * prior written permission of Genimen BV. - Redistributions of any form
15  * whatsoever must retain the following acknowledgment: "This product includes
16  * Djeneric."
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV, DJENERIC.ORG, OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.genimen.djeneric.tools.scriptengine.core.util;
31
32 import com.genimen.djeneric.language.Messages;
33 import com.genimen.djeneric.tools.scriptengine.core.ParseException;
34 import com.genimen.djeneric.tools.scriptengine.core.SimpleNode;
35 import com.genimen.djeneric.tools.scriptengine.core.nodes.AndOrNode;
36 import com.genimen.djeneric.tools.scriptengine.core.nodes.CalculatedExpressionNode;
37 import com.genimen.djeneric.tools.scriptengine.core.nodes.ElseNode;
38 import com.genimen.djeneric.tools.scriptengine.core.nodes.ExpressionNode;
39 import com.genimen.djeneric.tools.scriptengine.core.nodes.IfNode;
40 import com.genimen.djeneric.tools.scriptengine.core.nodes.OperatorNode;
41 import com.genimen.djeneric.tools.scriptengine.core.nodes.SubExpressionNode;
42
43 public class TreeNormalizer
44 {
45
46   public TreeNormalizer()
47   {
48   }
49
50   public void normalize(SimpleNode root) throws ParseException
51   {
52     // The order of the following methods is NOT trivial
53
normalizeOperands(root);
54     pruneCalculatedExpressions(root);
55     normalizeAndOr(root);
56     pruneUnary(root);
57     checkIfElse(root);
58   }
59
60   private void pushDown(CalculatedExpressionNode expr, String JavaDoc operator)
61   {
62     int i = 1;
63
64     while (i < expr.getChildCount() - 1)
65     {
66       int increment = 1;
67       SimpleNode child = expr.getChild(i);
68       if (child instanceof OperatorNode)
69       {
70         OperatorNode opNode = (OperatorNode) child;
71         if ((operator.equals("+-") && (opNode.getOperator().equals("+") || opNode.getOperator().equals("-")))
72             || (opNode.getOperator().equals(operator)))
73         {
74           moveLeftRightDown(expr, i, opNode);
75           // We shuffled the children; the 'next' is now the current because
76
// the left node is removed from the children list.
77
increment = 0;
78         }
79       }
80       i += increment;
81       // proceed with next node
82
}
83   }
84
85   private void pushDown(ExpressionNode expr, String JavaDoc andor)
86   {
87     int i = 1;
88
89     while (i < expr.getChildCount() - 1)
90     {
91       int increment = 1;
92       SimpleNode child = expr.getChild(i);
93       if (child instanceof AndOrNode)
94       {
95         AndOrNode aoNode = (AndOrNode) child;
96         if (aoNode.getOperator().equals(andor))
97         {
98           moveLeftRightDown(expr, i, aoNode);
99           // We shuffled the children; the 'next' is now the current because
100
// the left node is removed from the children list.
101
increment = 0;
102         }
103       }
104       i += increment;
105       // proceed with next node
106
}
107   }
108
109   private void moveLeftRightDown(SimpleNode expr, int i, SimpleNode opNode)
110   {
111     SimpleNode left = expr.getChild(i - 1);
112     SimpleNode right = expr.getChild(i + 1);
113
114     expr.removeChild(left);
115     expr.removeChild(right);
116
117     left.setParent(opNode);
118     right.setParent(opNode);
119
120     opNode.addChild(left);
121     opNode.addChild(right);
122   }
123
124   private void normalizeOperands(SimpleNode root)
125   {
126     for (int i = 0; i < root.getChildCount(); i++)
127     {
128       normalizeOperands(root.getChild(i));
129     }
130
131     if (root instanceof CalculatedExpressionNode)
132     {
133       pushDown((CalculatedExpressionNode) root, ".");
134       pushDown((CalculatedExpressionNode) root, "/");
135       pushDown((CalculatedExpressionNode) root, "*");
136       pushDown((CalculatedExpressionNode) root, "%");
137       pushDown((CalculatedExpressionNode) root, "+-");
138     }
139   }
140
141   private void normalizeAndOr(SimpleNode root)
142   {
143     for (int i = 0; i < root.getChildCount(); i++)
144     {
145       normalizeAndOr(root.getChild(i));
146     }
147
148     if (root instanceof ExpressionNode)
149     {
150       pushDown((ExpressionNode) root, "&&");
151       pushDown((ExpressionNode) root, "||");
152     }
153   }
154
155   private void checkIfElse(SimpleNode root) throws ParseException
156   {
157     for (int j = 0; j < root.getChildCount(); j++)
158     {
159       checkIfElse(root.getChild(j));
160     }
161
162     int i = 0;
163     while (i < root.getChildCount())
164     {
165       int increment = 1;
166       if (root.getChild(i) instanceof ElseNode)
167       {
168         if (i == 0 || !(root.getChild(i - 1) instanceof IfNode))
169         {
170           throw new ParseException(Messages.getString("TreeNormalizer.ElseWithoutIf", String.valueOf(root.getChild(i)
171               .getLine()), String.valueOf(root.getChild(i).getColumn())), root.getChild(i));
172         }
173         root.getChild(i - 1).addChild(root.getChild(i).getChild(0));
174         root.getChild(i).setParent(root.getChild(i - 1));
175         root.removeChild(i);
176         increment = 0;
177       }
178       i += increment;
179     }
180
181   }
182
183   private boolean pruneCalculatedExpressions(SimpleNode root) throws ParseException
184   {
185     boolean doneOne = false;
186
187     int i = 0;
188     while (i < root.getChildCount())
189     {
190       if (!pruneCalculatedExpressions(root.getChild(i))) i++;
191     }
192
193     if (root instanceof CalculatedExpressionNode)
194     {
195       SimpleNode parent = root.getParent();
196       if (root.getChildCount() != 1)
197       {
198         throw new ParseException("Calculated expression with childcount != 1 found", parent);
199       }
200       parent.replaceChild(root, root.getChild(0));
201       doneOne = true;
202     }
203     return doneOne;
204   }
205
206   private void pruneUnary(SimpleNode root) throws ParseException
207   {
208     int i = 0;
209     while (i < root.getChildCount())
210     {
211       int increment = 1;
212       if (root.getChild(i) instanceof ExpressionNode)
213       {
214         ExpressionNode exprNode = (ExpressionNode) root.getChild(i);
215         if (exprNode.getChildCount() != 1) throw new ParseException("Expression (" + exprNode.toString()
216                                                                     + ") with more than 1 child found", exprNode);
217
218         SimpleNode child = exprNode.getChild(0);
219         root.replaceChild(i, child);
220         child.setParent(root);
221         increment = 0;
222       }
223       if (root.getChild(i) instanceof SubExpressionNode)
224       {
225         SubExpressionNode exprNode = (SubExpressionNode) root.getChild(i);
226         if (exprNode.isUnary())
227         {
228           SimpleNode child = exprNode.getChild(0);
229           root.replaceChild(i, child);
230           child.setParent(root);
231           increment = 0;
232         }
233       }
234       i += increment;
235     }
236
237     for (int j = 0; j < root.getChildCount(); j++)
238     {
239       pruneUnary(root.getChild(j));
240     }
241   }
242
243 }
Popular Tags