Statistics
| Revision:

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
}