Statistics
| Revision:

root / trunk / extensions / extSymbology / src / org / gvsig / symbology / fmap / labeling / parse / LabelExpressionParser.jj @ 22278

History | View | Annotate | Download (13.2 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
	protected Stack stack = new Stack();
65
	protected static OperatorsFactory operators = OperatorsFactory.getInstance();
66
	protected Hashtable<String, Value> symbols = new Hashtable<String, Value>();
67
	protected 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(symbols);
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
		Hashtable<String, Value> symbols = new Hashtable<String, Value>();
149
		LabelExpressionParser parser = new LabelExpressionParser(new StringReader("3:4:2:Substring(\"My taylor is rich!\", 3, 9):(true && false);"));
150
		symbols.put("RD_6",ValueFactory.createValue(2));
151
		operators.addOperator(IndexOfFunction.class);
152
		operators.addOperator(SubstringFunction.class);
153
		parser.setOperatorsFactory(operators);
154
		parser.LabelExpression();
155
		parser.getStack();
156
		Object[] result = (Object[]) ((Expression)(parser.getStack().pop())).evaluate(symbols);
157
		for (int i = 0; i < result.length; i++) {
158
			System.out.print(result[i].toString()+"\n");
159
		}
160
	}
161
}
162
PARSER_END(LabelExpressionParser)
163
SKIP :
164
{
165
 	" "
166
|	"\r"
167
|	"\t"
168
|	"\n"
169
}
170

    
171

    
172
TOKEN : /* OPERATORS */
173
{
174
	< PLUS: "+" >
175
|	< MINUS: "-" >
176
|	< MULTIPLY: "*" >
177
|	< DIVIDE: "/" >
178
|	< GT: ">" >
179
|	< LT: "<" >
180
|	< NOT: "!" >
181
|	< EQ: "==" >
182
|	< LE: "<=" >
183
|	< GE: ">=" >
184
|	< NE: "!=" >
185
|	< OR: "||" >
186
|	< AND: "&&" >
187
}
188
TOKEN : /* MISC */
189
{
190
	< #DOT: "." >
191
|	< OPEN_SQ_BRACKETS : "[" >
192
|	< CLOSE_SQ_BRACKETS : "]" >
193
|	< OPEN_PARENTHESIS : "(" >
194
|	< CLOSE_PARENTHESIS : ")" >
195
|	< DOUBLE_QUOTE : "\"" >	
196
|	< COMMA : "," >
197
|   < EOFIELD : ":" >
198
|	< EOEXPR : ";" >
199
}
200
TOKEN : /* CONSTANTS AND IDENTIFIERS */
201
{
202
	< BOOLEAN: "true" | "false" >	
203
|   < NULL: "null">
204
|	< IDENTIFIER: ( <LETTER> ) ( <LETTER>|<DIGIT> )* >
205
|	< #LETTER: ( ["_","$","%"] | ( ["a"-"z"] ) | ( ["A"-"Z"] ) ) >
206
}
207
TOKEN : /* NUMBER */
208
{
209
    < #DIGIT: ["0"-"9"] >
210
|	< INTEGER: ( <DIGIT> )+ >
211
|	< FLOATING_POINT: (<DIGIT>)+ "." (<DIGIT>)* (<EXPONENT>)? (["f","F","d","D"])?
212
      | <DOT> (<DIGIT>)+ (<EXPONENT>)? (["f","F","d","D"])?
213
      | (<DIGIT>)+ <EXPONENT> (["f","F","d","D"])?
214
      | (<DIGIT>)+ (<EXPONENT>)? ["f","F","d","D"] >
215
|	< #EXPONENT: ["e","E"] (["+","-"])? (<DIGIT>)+ >
216
}
217
TOKEN: /* STRING */
218
{
219
	< STRING: ( <DOUBLE_QUOTE> ( <CHAR_STRING> )* <DOUBLE_QUOTE> )>
220
|	< CHAR_STRING : ~[ "\"", ";","\n","\r"] >
221
}
222

    
223

    
224
TOKEN : /* LABELING TOKENS */
225
{
226
	< FIELD_IDENTIFIER: <OPEN_SQ_BRACKETS> <CHAR_STRING> <CLOSE_SQ_BRACKETS> >
227
}
228

    
229

    
230
/* LABEL EXPRESSION */
231
//We have to use this function if we want to evaluate an String which contains different Expressions 
232
//inside
233
void LabelExpression() :
234
{
235

    
236
}
237
{
238
	
239
	Expression() (
240
	
241
	LOOKAHEAD(2)<EOFIELD> Expression() {
242
			 Expression leftExpression = (Expression)stack.pop();
243
    		 Expression rightExpression = (Expression)stack.pop();
244
    
245
 			 Expression labelExpr = new LabelExpressionOperator();
246
 			 labelExpr.addArgument(0, rightExpression);
247
 			 labelExpr.addArgument(0, leftExpression);
248
 	
249
    		stack.push(labelExpr);	
250
 	
251
	}
252
 	| Expression(){
253
            Expression leftExpression2 = (Expression)stack.pop();
254
    		Expression rightExpression2 = (Expression)stack.pop();
255
    
256
 			Expression fieldExpr = new FieldExpressionOperator();
257
 			fieldExpr.addArgument(0, rightExpression2);
258
 			fieldExpr.addArgument(0, leftExpression2);
259
 	
260
    		stack.push(fieldExpr); 	
261
   })* 
262
   // <EOEXPR>
263
 	
264
//|	<EOEXPR> 
265

    
266
}
267

    
268
void Expression():{}{
269
  AndExpression()(<OR>AndExpression(){
270
    Expression leftExpression = (Expression)stack.pop();
271
    Expression rightExpression = (Expression)stack.pop();
272
    
273
 	Expression orExpr = new OrOperator();
274
 	orExpr.addArgument(0, rightExpression);
275
 	orExpr.addArgument(0, leftExpression);
276
 	
277
    stack.push(orExpr);
278
   
279
  }
280
  )*
281
}
282
void AndExpression():{
283
  Token x;
284
}
285
{
286
  EqCompExpression()((x = <AND>)EqCompExpression(){
287
    Expression rightExpression = (Expression)stack.pop();
288
    Expression leftExpression = (Expression)stack.pop();
289
    
290
    Expression func = new AndOperator();
291
    
292
    func.addArgument(0, rightExpression);
293
    func.addArgument(0, leftExpression);
294
 	
295
    stack.push(func);
296
  }
297
  )*
298
}
299
void EqCompExpression():{
300
  Token x;
301
}
302
{
303
  ComparisonExpression()((x = <EQ>
304
  | x = <NE>)ComparisonExpression(){
305
    Expression rightExpression = (Expression)stack.pop();
306
    Expression leftExpression = (Expression)stack.pop();
307
    Expression func = null;
308
    
309
    if (x.kind == EQ)func = new EqOperator();
310
    else if (x.kind == NE)func = new NeOperator();
311
    
312
    func.addArgument(0, rightExpression);
313
    func.addArgument(0, leftExpression);
314
 	
315
    stack.push(func);
316
  }
317
  )*
318
}
319
void ComparisonExpression():{
320
  Token x;
321
}
322
{
323
  AdditiveExpression()((x = <LT>
324
  | x = <LE>
325
  | x = <GT>
326
  | x = <GE>)AdditiveExpression(){
327
    Expression rightExpression = (Expression)stack.pop();
328
    Expression leftExpression = (Expression)stack.pop();
329
    Expression func = null;
330
   
331
    
332
    if (x.kind == LT)func = new LessThanOperator();
333
    else if (x.kind == LE)func = new LessThanOrEqualsOperator();
334
    else if (x.kind == GT)func = new GreaterThanOperator();
335
    else if (x.kind == GE)func = new GreaterThanOrEqualsOperator();
336
   
337
    func.addArgument(0, rightExpression);
338
    func.addArgument(0, leftExpression);
339
 	
340
    stack.push(func);
341
  }
342
  )*
343
}
344
void AdditiveExpression():{
345
  Token x;
346
}
347
{
348
  MultiplicativeExpression()((x = <PLUS>
349
  | x = <MINUS>)MultiplicativeExpression(){
350
    Expression rightExpression = (Expression)stack.pop();
351
    Expression leftExpression = (Expression)stack.pop();
352
    Expression func = null;
353
    
354
    if (x.kind == PLUS)func = new AddOperator();
355
    else func = new MinusOperator();
356
    
357
    func.addArgument(0, rightExpression);
358
    func.addArgument(0, leftExpression);
359
 	
360
    stack.push(func);
361
  }
362
  )*
363
}
364
void MultiplicativeExpression():{
365
  Token x;
366
}
367
{
368
  UnaryElement()((x = <MULTIPLY>
369
  | x = <DIVIDE>)UnaryElement(){	
370
  	try{
371
  			Expression A = (Expression) stack.pop();
372
			Expression B = (Expression) stack.pop();
373
			 boolean aInt = (((Expression) A).evaluate(symbols) instanceof Integer);
374
			 boolean bInt = (((Expression) B).evaluate(symbols) instanceof Integer);
375
			if (aInt &&	bInt) {
376
				int a = (Integer) A.evaluate(symbols);
377
				int b = (Integer) B.evaluate(symbols);
378
				if (x.kind == MULTIPLY)
379
					stack.push(new NumericalConstant(new Integer(b * a)));
380
				else
381
					stack.push(new NumericalConstant(new Integer(b / a)));
382
			} else {
383
				
384
				double a = new Double(((Expression)A).evaluate(symbols).toString()); 
385
                double b = new Double(((Expression)B).evaluate(symbols).toString());
386
				if (x.kind == MULTIPLY)
387
					stack.push(new NumericalConstant(new Double(b * a)));
388
				else
389
					stack.push(new NumericalConstant(new Double(b / a)));
390
			}}catch (ClassCastException ex) {
391
                  ex.printStackTrace();
392
            } catch (ExpressionException e) {
393
				  e.printStackTrace();
394
			}
395
			
396
	})*
397
}
398
void UnaryElement():{
399
  Token x = null;
400
}
401
{
402
  (x = <PLUS>
403
  | x = <MINUS>)UnaryElement(){
404
  	      try{
405
                 Object A = stack.pop();
406
                         if ((((Expression) A).evaluate(symbols) instanceof Integer)) {
407
                                int a = (Integer) ((Expression) A).evaluate(symbols);
408
                                if (x.kind == PLUS)
409
                                        stack.push(new NumericalConstant(new Integer(a)));
410
                                else
411
                                        stack.push(new NumericalConstant(new Integer(-a)));
412
                        } else {
413
                                double a = (Double) ((Expression) A).evaluate(symbols);
414
                                if (x.kind == PLUS)
415
                                        stack.push(new NumericalConstant(new Double(a)));
416
                                else
417
                                        stack.push(new NumericalConstant(new Double(-a)));
418
                        }
419
                         } catch (ClassCastException ex) {
420
               ex.printStackTrace();
421
             }catch (ExpressionException ex) {
422
                 ex.printStackTrace();
423
             }
424
  }
425
  
426
  | BooleanUnaryElement()
427
}
428

    
429
void BooleanUnaryElement(): 
430
{
431
	Token t;
432
}
433
{
434
	 t = <NOT> UnaryElement() {
435
	 	Expression rightExpression = (Expression)stack.pop();
436
		Expression func = new NotOperator();
437
		func.addArgument(0, rightExpression);
438
		stack.push(func);
439
	}
440
| Element()
441
}
442

    
443

    
444
void Element():{
445
  Token x;
446
  String y =  "[$,A-Z,_,a-z]([$,A-Z,_,a-z]|[0-9])*";
447
}
448
{
449
	
450
  ("["x = <IDENTIFIER>"]"){
451
     
452
    ReplaceOperator func = new ReplaceOperator();
453
     func.addArgument(x.image); 
454
   	stack.push(func);
455
	addClassName(x.image);
456
   
457
  }
458
  | (x = <INTEGER>){
459
  	NumericalConstant intC = new NumericalConstant(Integer.valueOf(x.image));
460
   	stack.push(intC);
461
  }
462
  | (x = <FLOATING_POINT>){
463
  	NumericalConstant doubleC = new NumericalConstant(Double.valueOf(x.image));
464
   	stack.push(doubleC);
465
  }
466
  |(x = <STRING>) {
467
    StringConstant stringValue = new StringConstant(x.image.substring(1, x.image.length()-1));
468
    stack.push(stringValue);
469
  }
470
  | (x = <BOOLEAN>){
471
    BooleanConstant boolValue = new BooleanConstant(x.image);
472
    stack.push(boolValue);
473
  }
474
  | x = <NULL>{
475
  	NullConstant nullValue = new NullConstant();
476
    stack.push(nullValue);
477
  }
478
  | LOOKAHEAD(2)function()
479
  | "("Expression()")"
480
}
481
void function():{
482
  String functionName;
483
  int argCount = 0;
484
  Expression function;
485
  Token x;
486
}
487
{
488
 LOOKAHEAD(2)
489
  <IDENTIFIER>{
490
    functionName = token.image;
491
  }
492
  argCount = Arguments(){
493
    try {
494
    	function = (Expression) operators.functions.get(functionName).newInstance();
495
    }
496
    catch (Exception e){
497
      throw new ParseException("Problem with function '"+functionName+"': "+e.toString());
498
    }
499
    if (function == null)throw new ParseException("Nonexisting function name '"+functionName+"'");
500
    for (int i = 0;
501
    i<argCount;
502
    i++){
503
      Expression arg = (Expression)stack.pop();
504
      function.addArgument(0, arg);
505
    }
506
    stack.push(function);
507
  }
508
  |(x = <IDENTIFIER>){
509
    StringConstant stringValue = new StringConstant(x.image);
510
    stack.push(stringValue);
511
  }
512
}
513
int Arguments():{
514
  int argCount = 0;
515
}
516
{
517
  <OPEN_PARENTHESIS>[argCount = ArgumentList()]<CLOSE_PARENTHESIS>{
518
    return argCount;
519
  }
520
}
521
int ArgumentList():{
522
  int argCount = 0;
523
}
524
{
525
  Expression(){
526
    argCount++;
527
  }
528
  (<COMMA>Expression(){
529
    argCount++;
530
  }
531
  )*{
532
    return argCount;
533
  }
534
}