Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.labeling.app / org.gvsig.labeling.app.mainplugin / src / main / java / org / gvsig / labeling / parse / LabelExpressionParser.jj @ 40673

History | View | Annotate | Download (14.2 KB)

1 40665 jldominguez
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
390
391
392
void MultiplicativeExpression():{
393
  Token x;
394
}
395
{
396
 	UnaryElement()((x = <MULTIPLY>
397
  	| x = <DIVIDE>)UnaryElement(){
398
399
    Expression rightExpression = (Expression)stack.pop();
400
    Expression leftExpression = (Expression)stack.pop();
401
    Expression func = null;
402
403
    if (x.kind == MULTIPLY)func = new MultOperator(symbols);
404
    else func = new DivOperator(symbols);
405
406
    func.addArgument(0, rightExpression);
407
    func.addArgument(0, leftExpression);
408
409
    stack.push(func);
410
  }
411
  )*
412
}
413
414
415
void UnaryElement():{
416
  Token x = null;
417
}
418
{
419
  (x = <PLUS>
420
  | x = <MINUS>)UnaryElement(){
421
  	      try{
422
                 Object A = stack.pop();
423
                         if ((((Expression) A).evaluate() instanceof Integer)) {
424
                                int a = (Integer) ((Expression) A).evaluate();
425
                                if (x.kind == PLUS)
426
                                        stack.push(new NumericalConstant(new Integer(a),symbols));
427
                                else
428
                                        stack.push(new NumericalConstant(new Integer(-a),symbols));
429
                        } else {
430
                                double a = (Double) ((Expression) A).evaluate();
431
                                if (x.kind == PLUS)
432
                                        stack.push(new NumericalConstant(new Double(a),symbols));
433
                                else
434
                                        stack.push(new NumericalConstant(new Double(-a),symbols));
435
                        }
436
                         } catch (ClassCastException ex) {
437
               ex.printStackTrace();
438
             }catch (ExpressionException ex) {
439
                 ex.printStackTrace();
440
             }
441
  }
442
443
  | BooleanUnaryElement()
444
}
445
446
void BooleanUnaryElement():
447
{
448
	Token t;
449
}
450
{
451
	 t = <NOT> UnaryElement() {
452
	 	Expression rightExpression = (Expression)stack.pop();
453
		Expression func = new NotOperator(symbols);
454
		func.addArgument(0, rightExpression);
455
		stack.push(func);
456
	}
457
| Element()
458
}
459
460
461
void Element():{
462
  Token x;
463
  String y =  "[$,A-Z,_,a-z]([$,A-Z,_,a-z]|[0-9])*";
464
}
465
{
466
467
  ("["x = <IDENTIFIER>"]"){
468
469
    ReplaceOperator func = new ReplaceOperator(symbols);
470
     func.addArgument(x.image);
471
   	stack.push(func);
472
	addClassName(x.image);
473
474
  }
475
  | (x = <INTEGER>){
476
  	NumericalConstant intC = new NumericalConstant(Integer.valueOf(x.image),symbols);
477
   	stack.push(intC);
478
  }
479
  | (x = <FLOATING_POINT>){
480
  	NumericalConstant doubleC = new NumericalConstant(Double.valueOf(x.image),symbols);
481
   	stack.push(doubleC);
482
  }
483
  |(x = <STRING>) {
484
    StringConstant stringValue = new StringConstant(x.image.substring(1, x.image.length()-1),symbols);
485
    stack.push(stringValue);
486
  }
487
  | (x = <BOOLEAN>){
488
    BooleanConstant boolValue = new BooleanConstant(x.image,symbols);
489
    stack.push(boolValue);
490
  }
491
  | x = <NULL>{
492
  	NullConstant nullValue = new NullConstant(symbols);
493
    stack.push(nullValue);
494
  }
495
  | LOOKAHEAD(2)function()
496
  | "("Expression()")"
497
}
498
void function():{
499
  String functionName;
500
  int argCount = 0;
501
  Expression function;
502
  Token x;
503
}
504
{
505
 LOOKAHEAD(2)
506
  <IDENTIFIER>{
507
    functionName = token.image;
508
  }
509
  argCount = Arguments(){
510
    try {
511
    	function = (Expression) operators.functions.get(functionName).getConstructor(new Class[] { Hashtable.class }).newInstance( new Hashtable<String, Value>());
512
    }
513
    catch (Exception e){
514
      throw new ParseException("Problem with function '"+functionName+"': "+e.toString());
515
    }
516
    if (function == null)throw new ParseException("Nonexisting function name '"+functionName+"'");
517
    for (int i = 0;
518
    i<argCount;
519
    i++){
520
      Expression arg = (Expression)stack.pop();
521
      function.addArgument(0, arg);
522
    }
523
    stack.push(function);
524
  }
525
  |(x = <IDENTIFIER>){
526
    StringConstant stringValue = new StringConstant(x.image,symbols);
527
    stack.push(stringValue);
528
  }
529
}
530
int Arguments():{
531
  int argCount = 0;
532
}
533
{
534
  <OPEN_PARENTHESIS>[argCount = ArgumentList()]<CLOSE_PARENTHESIS>{
535
    return argCount;
536
  }
537
}
538
int ArgumentList():{
539
  int argCount = 0;
540
}
541
{
542
  Expression(){
543
    argCount++;
544
  }
545
  (<COMMA>Expression(){
546
    argCount++;
547
  }
548
  )*{
549
    return argCount;
550
  }
551
}