Statistics
| Revision:

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
}