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