svn-gvsig-desktop / trunk / extensions / extSymbology / src / org / gvsig / symbology / fmap / rendering / filter / parser / ExpressionParser.jj @ 22513
History | View | Annotate | Download (11.2 KB)
1 |
|
---|---|
2 |
options{ |
3 |
STATIC = false; |
4 |
LOOKAHEAD = 1; |
5 |
} |
6 |
PARSER_BEGIN(ExpressionParser) |
7 |
|
8 |
/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana |
9 |
* |
10 |
* Copyright (C) 2004 IVER T.I. and Generalitat Valenciana. |
11 |
* |
12 |
* This program is free software; you can redistribute it and/or |
13 |
* modify it under the terms of the GNU General Public License |
14 |
* as published by the Free Software Foundation; either version 2 |
15 |
* of the License, or (at your option) any later version. |
16 |
* |
17 |
* This program is distributed in the hope that it will be useful, |
18 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 |
* GNU General Public License for more details. |
21 |
* |
22 |
* You should have received a copy of the GNU General Public License |
23 |
* along with this program; if not, write to the Free Software |
24 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA. |
25 |
* |
26 |
* For more information, contact: |
27 |
* |
28 |
* Generalitat Valenciana |
29 |
* Conselleria d'Infraestructures i Transport |
30 |
* Av. Blasco Ib��ez, 50 |
31 |
* 46010 VALENCIA |
32 |
* SPAIN |
33 |
* |
34 |
* +34 963862235 |
35 |
* gvsig@gva.es |
36 |
* www.gvsig.gva.es |
37 |
* |
38 |
* or |
39 |
* |
40 |
* IVER T.I. S.A |
41 |
* Salamanca 50 |
42 |
* 46005 Valencia |
43 |
* Spain |
44 |
* |
45 |
* +34 963163400 |
46 |
* dac@iver.es |
47 |
*/ |
48 |
package org.gvsig.symbology.fmap.rendering.filter.parser; |
49 |
import java.util.*; |
50 |
import java.io.*; |
51 |
|
52 |
|
53 |
import com.hardcode.gdbms.engine.values.*; |
54 |
import org.gvsig.symbology.fmap.rendering.filter.operations.*; |
55 |
|
56 |
/** |
57 |
* |
58 |
* @author Pepe Vidal Salvador - jose.vidal.salvador@iver.es |
59 |
* |
60 |
*/ |
61 |
public class ExpressionParser{ |
62 |
|
63 |
private Stack stack = new Stack(); |
64 |
private static OperatorsFactory operators = OperatorsFactory.getInstance(); |
65 |
private Hashtable<String, Value> symbols = new Hashtable<String, Value>(); |
66 |
private ArrayList<String> classNames = new ArrayList<String>(); |
67 |
|
68 |
|
69 |
public ArrayList<String> getClassNames (){ |
70 |
return classNames; |
71 |
} |
72 |
|
73 |
public void addClassName(String name){ |
74 |
for (int i = 0; i < classNames.size(); i++) { |
75 |
if(classNames.get(i).compareTo(name)==0) |
76 |
return; |
77 |
} |
78 |
classNames.add(name); |
79 |
} |
80 |
public Expression getExpression(){ |
81 |
return (Expression)stack.pop(); |
82 |
} |
83 |
|
84 |
public Stack getStack(){ |
85 |
|
86 |
return this.stack; |
87 |
} |
88 |
|
89 |
public ExpressionParser(StringReader reader, Hashtable<String, Value> symbolsTable) { |
90 |
this(reader); |
91 |
this.symbols = symbolsTable; |
92 |
} |
93 |
|
94 |
public void putSymbol(String string, Value value){ |
95 |
this.symbols.put(string,value); |
96 |
} |
97 |
|
98 |
public static void main(String[]args)throws ParseException,ExpressionException{ |
99 |
ExpressionParser parser = new ExpressionParser(new StringReader("true && true")); |
100 |
parser.Expression(); |
101 |
parser.getStack(); |
102 |
Expression exp = parser.getExpression(); |
103 |
|
104 |
} |
105 |
} |
106 |
PARSER_END(ExpressionParser) |
107 |
SKIP : |
108 |
{ |
109 |
" " |
110 |
| "\r" |
111 |
| "\t" |
112 |
| "\n" |
113 |
} |
114 |
|
115 |
|
116 |
TOKEN : /* OPERATORS */ |
117 |
{ |
118 |
< PLUS: "+" > |
119 |
| < MINUS: "-" > |
120 |
| < MULTIPLY: "*" > |
121 |
| < DIVIDE: "/" > |
122 |
| < GT: ">" > |
123 |
| < LT: "<" > |
124 |
| < NOT: "!" > |
125 |
| < EQ: "==" > |
126 |
| < LE: "<=" > |
127 |
| < GE: ">=" > |
128 |
| < NE: "!=" > |
129 |
| < OR: "||" > |
130 |
| < AND: "&&" > |
131 |
} |
132 |
TOKEN : /* MISC */ |
133 |
{ |
134 |
< #DOT: "." > |
135 |
| < OPEN_SQ_BRACKETS : "[" > |
136 |
| < CLOSE_SQ_BRACKETS : "]" > |
137 |
| < OPEN_PARENTHESIS : "(" > |
138 |
| < CLOSE_PARENTHESIS : ")" > |
139 |
| < DOUBLE_QUOTE : "\"" > |
140 |
| < COMMA : "," > |
141 |
| < EOFIELD : ":" > |
142 |
| < EOEXPR : ";" > |
143 |
} |
144 |
TOKEN : /* CONSTANTS AND IDENTIFIERS */ |
145 |
{ |
146 |
< BOOLEAN: "true" | "false" > |
147 |
| < NULL: "null"> |
148 |
| < IDENTIFIER: ( <LETTER> ) ( <LETTER>|<DIGIT> )* > |
149 |
| < #LETTER: ( ["_","$","%"] | ( ["a"-"z"] ) | ( ["A"-"Z"] ) ) > |
150 |
} |
151 |
TOKEN : /* NUMBER */ |
152 |
{ |
153 |
< #DIGIT: ["0"-"9"] > |
154 |
| < INTEGER: ( <DIGIT> )+ > |
155 |
| < FLOATING_POINT: (<DIGIT>)+ "." (<DIGIT>)* (<EXPONENT>)? (["f","F","d","D"])? |
156 |
| <DOT> (<DIGIT>)+ (<EXPONENT>)? (["f","F","d","D"])? |
157 |
| (<DIGIT>)+ <EXPONENT> (["f","F","d","D"])? |
158 |
| (<DIGIT>)+ (<EXPONENT>)? ["f","F","d","D"] > |
159 |
| < #EXPONENT: ["e","E"] (["+","-"])? (<DIGIT>)+ > |
160 |
} |
161 |
TOKEN: /* STRING */ |
162 |
{ |
163 |
< STRING: ( <DOUBLE_QUOTE> ( <CHAR_STRING> )* <DOUBLE_QUOTE> )> |
164 |
| < CHAR_STRING : ~[ "\"", ";","\n","\r"] > |
165 |
} |
166 |
void Expression():{}{ |
167 |
AndExpression()(<OR>AndExpression(){ |
168 |
Expression leftExpression = (Expression)stack.pop(); |
169 |
Expression rightExpression = (Expression)stack.pop(); |
170 |
|
171 |
Expression orExpr = new OrOperator(symbols); |
172 |
orExpr.addArgument(0, rightExpression); |
173 |
orExpr.addArgument(0, leftExpression); |
174 |
|
175 |
stack.push(orExpr); |
176 |
|
177 |
} |
178 |
)* |
179 |
} |
180 |
void AndExpression():{ |
181 |
Token x; |
182 |
} |
183 |
{ |
184 |
EqCompExpression()((x = <AND>)EqCompExpression(){ |
185 |
Expression rightExpression = (Expression)stack.pop(); |
186 |
Expression leftExpression = (Expression)stack.pop(); |
187 |
|
188 |
Expression func = new AndOperator(symbols); |
189 |
|
190 |
func.addArgument(0, rightExpression); |
191 |
func.addArgument(0, leftExpression); |
192 |
|
193 |
stack.push(func); |
194 |
} |
195 |
)* |
196 |
} |
197 |
void EqCompExpression():{ |
198 |
Token x; |
199 |
} |
200 |
{ |
201 |
ComparisonExpression()((x = <EQ> |
202 |
| x = <NE>)ComparisonExpression(){ |
203 |
Expression rightExpression = (Expression)stack.pop(); |
204 |
Expression leftExpression = (Expression)stack.pop(); |
205 |
Expression func = null; |
206 |
|
207 |
if (x.kind == EQ)func = new EqOperator(symbols); |
208 |
else if (x.kind == NE)func = new NeOperator(symbols); |
209 |
|
210 |
func.addArgument(0, rightExpression); |
211 |
func.addArgument(0, leftExpression); |
212 |
|
213 |
stack.push(func); |
214 |
} |
215 |
)* |
216 |
} |
217 |
void ComparisonExpression():{ |
218 |
Token x; |
219 |
} |
220 |
{ |
221 |
AdditiveExpression()((x = <LT> |
222 |
| x = <LE> |
223 |
| x = <GT> |
224 |
| x = <GE>)AdditiveExpression(){ |
225 |
Expression rightExpression = (Expression)stack.pop(); |
226 |
Expression leftExpression = (Expression)stack.pop(); |
227 |
Expression func = null; |
228 |
|
229 |
|
230 |
if (x.kind == LT)func = new LessThanOperator(symbols); |
231 |
else if (x.kind == LE)func = new LessThanOrEqualsOperator(symbols); |
232 |
else if (x.kind == GT)func = new GreaterThanOperator(symbols); |
233 |
else if (x.kind == GE)func = new GreaterThanOrEqualsOperator(symbols); |
234 |
|
235 |
func.addArgument(0, rightExpression); |
236 |
func.addArgument(0, leftExpression); |
237 |
|
238 |
stack.push(func); |
239 |
} |
240 |
)* |
241 |
} |
242 |
void AdditiveExpression():{ |
243 |
Token x; |
244 |
} |
245 |
{ |
246 |
MultiplicativeExpression()((x = <PLUS> |
247 |
| x = <MINUS>)MultiplicativeExpression(){ |
248 |
Expression rightExpression = (Expression)stack.pop(); |
249 |
Expression leftExpression = (Expression)stack.pop(); |
250 |
Expression func = null; |
251 |
|
252 |
if (x.kind == PLUS)func = new AddOperator(symbols); |
253 |
else func = new MinusOperator(symbols); |
254 |
|
255 |
func.addArgument(0, rightExpression); |
256 |
func.addArgument(0, leftExpression); |
257 |
|
258 |
stack.push(func); |
259 |
} |
260 |
)* |
261 |
} |
262 |
void MultiplicativeExpression():{ |
263 |
Token x; |
264 |
} |
265 |
{ |
266 |
UnaryElement()((x = <MULTIPLY> |
267 |
| x = <DIVIDE>)UnaryElement(){ |
268 |
try{ |
269 |
Expression A = (Expression) stack.pop(); |
270 |
Expression B = (Expression) stack.pop(); |
271 |
boolean aInt = (((Expression) A).evaluate() instanceof Integer); |
272 |
boolean bInt = (((Expression) B).evaluate() instanceof Integer); |
273 |
if (aInt && bInt) { |
274 |
int a = (Integer) A.evaluate(); |
275 |
int b = (Integer) B.evaluate(); |
276 |
if (x.kind == MULTIPLY) |
277 |
stack.push(new NumericalConstant(new Integer(b * a),symbols)); |
278 |
else |
279 |
stack.push(new NumericalConstant(new Integer(b / a),symbols)); |
280 |
} else { |
281 |
|
282 |
double a = new Double(((Expression)A).evaluate().toString()); |
283 |
double b = new Double(((Expression)B).evaluate().toString()); |
284 |
if (x.kind == MULTIPLY) |
285 |
stack.push(new NumericalConstant(new Double(b * a),symbols)); |
286 |
else |
287 |
stack.push(new NumericalConstant(new Double(b / a),symbols)); |
288 |
}}catch (ClassCastException ex) { |
289 |
ex.printStackTrace(); |
290 |
} catch (ExpressionException e) { |
291 |
e.printStackTrace(); |
292 |
} |
293 |
|
294 |
})* |
295 |
} |
296 |
void UnaryElement():{ |
297 |
Token x = null; |
298 |
} |
299 |
{ |
300 |
(x = <PLUS> |
301 |
| x = <MINUS>)UnaryElement(){ |
302 |
try{ |
303 |
Object A = stack.pop(); |
304 |
if ((((Expression) A).evaluate() instanceof Integer)) { |
305 |
int a = (Integer) ((Expression) A).evaluate(); |
306 |
if (x.kind == PLUS) |
307 |
stack.push(new NumericalConstant(new Integer(a),symbols)); |
308 |
else |
309 |
stack.push(new NumericalConstant(new Integer(-a),symbols)); |
310 |
} else { |
311 |
double a = (Double) ((Expression) A).evaluate(); |
312 |
if (x.kind == PLUS) |
313 |
stack.push(new NumericalConstant(new Double(a),symbols)); |
314 |
else |
315 |
stack.push(new NumericalConstant(new Double(-a),symbols)); |
316 |
} |
317 |
} catch (ClassCastException ex) { |
318 |
ex.printStackTrace(); |
319 |
}catch (ExpressionException ex) { |
320 |
ex.printStackTrace(); |
321 |
} |
322 |
} |
323 |
|
324 |
| BooleanUnaryElement() |
325 |
} |
326 |
|
327 |
void BooleanUnaryElement(): |
328 |
{ |
329 |
Token t; |
330 |
} |
331 |
{ |
332 |
t = <NOT> UnaryElement() { |
333 |
Expression rightExpression = (Expression)stack.pop(); |
334 |
Expression func = new NotOperator(symbols); |
335 |
func.addArgument(0, rightExpression); |
336 |
stack.push(func); |
337 |
} |
338 |
| Element() |
339 |
} |
340 |
void Element():{ |
341 |
Token x; |
342 |
String y = "[$,A-Z,_,a-z]([$,A-Z,_,a-z]|[0-9])*"; |
343 |
} |
344 |
{ |
345 |
|
346 |
("["x = <IDENTIFIER>"]"){ |
347 |
|
348 |
ReplaceOperator func = new ReplaceOperator(symbols); |
349 |
func.addArgument(x.image); |
350 |
stack.push(func); |
351 |
addClassName(x.image); |
352 |
|
353 |
} |
354 |
| (x = <INTEGER>){ |
355 |
NumericalConstant intC = new NumericalConstant(Integer.valueOf(x.image),symbols); |
356 |
stack.push(intC); |
357 |
} |
358 |
| (x = <FLOATING_POINT>){ |
359 |
NumericalConstant doubleC = new NumericalConstant(Double.valueOf(x.image),symbols); |
360 |
stack.push(doubleC); |
361 |
} |
362 |
|(x = <STRING>) { |
363 |
StringConstant stringValue = new StringConstant(x.image.substring(1, x.image.length()-1),symbols); |
364 |
stack.push(stringValue); |
365 |
} |
366 |
| (x = <BOOLEAN>){ |
367 |
BooleanConstant boolValue = new BooleanConstant(x.image,symbols); |
368 |
stack.push(boolValue); |
369 |
} |
370 |
| x = <NULL>{ |
371 |
NullConstant nullValue = new NullConstant(symbols); |
372 |
stack.push(nullValue); |
373 |
} |
374 |
| LOOKAHEAD(2)function() |
375 |
| "("Expression()")" |
376 |
} |
377 |
void function():{ |
378 |
String functionName; |
379 |
int argCount = 0; |
380 |
Expression function; |
381 |
Token x; |
382 |
} |
383 |
{ |
384 |
LOOKAHEAD(2) |
385 |
<IDENTIFIER>{ |
386 |
functionName = token.image; |
387 |
} |
388 |
argCount = Arguments(){ |
389 |
try { |
390 |
function = (Expression) operators.getOperator(functionName); |
391 |
} |
392 |
catch (Exception e){ |
393 |
throw new ParseException("Problem with function '"+functionName+"': "+e.toString()); |
394 |
} |
395 |
if (function == null)throw new ParseException("Nonexisting function name '"+functionName+"'"); |
396 |
for (int i = 0; |
397 |
i<argCount; |
398 |
i++){ |
399 |
Expression arg = (Expression)stack.pop(); |
400 |
function.addArgument(0, arg); |
401 |
} |
402 |
stack.push(function); |
403 |
} |
404 |
|(x = <IDENTIFIER>){ |
405 |
StringConstant stringValue = new StringConstant(x.image,symbols); |
406 |
stack.push(stringValue); |
407 |
} |
408 |
} |
409 |
int Arguments():{ |
410 |
int argCount = 0; |
411 |
} |
412 |
{ |
413 |
<OPEN_PARENTHESIS>[argCount = ArgumentList()]<CLOSE_PARENTHESIS>{ |
414 |
return argCount; |
415 |
} |
416 |
} |
417 |
int ArgumentList():{ |
418 |
int argCount = 0; |
419 |
} |
420 |
{ |
421 |
Expression(){ |
422 |
argCount++; |
423 |
} |
424 |
(<COMMA>Expression(){ |
425 |
argCount++; |
426 |
} |
427 |
)*{ |
428 |
return argCount; |
429 |
} |
430 |
} |