Revision 44139 trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/main/java/org/gvsig/expressionevaluator/impl/DefaultCompiler.java

View differences:

DefaultCompiler.java
1 1
package org.gvsig.expressionevaluator.impl;
2 2

  
3
import java.util.HashMap;
4
import java.util.Map;
5
import org.apache.commons.lang3.StringUtils;
3 6
import org.gvsig.expressionevaluator.Compiler;
4
import org.gvsig.expressionevaluator.Code.Caller.Arguments;
5 7
import org.gvsig.expressionevaluator.LexicalAnalyzer;
6 8
import org.gvsig.expressionevaluator.LexicalAnalyzer.Token;
7 9
import org.gvsig.expressionevaluator.Code;
8 10
import org.gvsig.expressionevaluator.CodeBuilder;
11
import org.gvsig.expressionevaluator.Codes;
9 12
import org.gvsig.expressionevaluator.ExpressionSyntaxException;
13
import org.gvsig.expressionevaluator.GrammarSet;
14
import org.gvsig.expressionevaluator.Statement;
15
import org.gvsig.expressionevaluator.Statement.StatementContext;
16
import org.gvsig.expressionevaluator.impl.DefaultCodeBuilder.BaseCodes;
10 17

  
11 18
public class DefaultCompiler implements Compiler {
12 19

  
20
    class DefaultStatementContext implements StatementContext {
21

  
22
        private String codeClassifier;
23
        private Map<String,Code> codes;
24

  
25
        @Override
26
        public Compiler getCompiler() {
27
            return DefaultCompiler.this;
28
        }
29

  
30
        @Override
31
        public LexicalAnalyzer getLexicalAnalyzer() {
32
            return lexer;
33
        }
34

  
35
        @Override
36
        public void setCode(String id, Code code) {
37
            if( this.codes == null ) {
38
                this.codes = new HashMap<>();
39
            }
40
            if( !StringUtils.isBlank(this.codeClassifier) ) {
41
                if( id.contains("#") ) {
42
                    id = StringUtils.replace(id,"#",this.codeClassifier,1);
43
                }
44
            }
45
            this.codes.put(id, code);
46
        }
47

  
48
        public Code getCode(String id) {
49
            return this.codes.get(id);
50
        }
51
        
52
        @Override
53
        public void setCodeClassifier(String classifier) {
54
            this.codeClassifier = classifier;
55
        }
56

  
57
        @Override
58
        public String getCodeClassifier() {
59
            return this.codeClassifier;
60
        }
61

  
62
        @Override
63
        public CodeBuilder getCodeBuilder() {
64
            return codeBuilder;
65
        }
66

  
67
        @Override
68
        public Token look_token() {
69
            return lexer.look();
70
        }
71

  
72
        @Override
73
        public Token next_token() {
74
            return lexer.next();
75
        }
76

  
77
        @Override
78
        public Code parse_expression() {
79
            return DefaultCompiler.this.parse_expression();
80
        }
81

  
82
        @Override
83
        public Codes parse_expressions(String separator) {
84
            return DefaultCompiler.this.parse_expressions(separator);
85
        }
86
        
87
    }
88

  
13 89
    private boolean objectAccessSupported;
14 90
    private LexicalAnalyzer lexer;
15 91
    private CodeBuilder codeBuilder;
92
    private final GrammarSet grammars;
16 93
    //
17 94
    // https://www.postgresql.org/docs/9.1/static/functions.html
18 95
    //
19 96

  
20 97
    public DefaultCompiler() {
98
        this.grammars = new DefaultGrammarSet();
21 99
        this.lexer = new SQLLexicalAnalyzer();
22 100
        this.codeBuilder = new DefaultCodeBuilder();
23 101
        this.objectAccessSupported = true;
......
61 139
    public void setObjectAccessSupported(boolean objectAccessSupported) {
62 140
        this.objectAccessSupported = objectAccessSupported;
63 141
    }
64
    
142

  
65 143
    @Override
144
    public GrammarSet getGrammars() {
145
        return this.grammars;
146
    }
147

  
148
    @Override
66 149
    public Code compileExpression(String expression) {
67 150
        this.lexer.setSource(expression.trim());
68
        Code code = parseExpression();
151
        Code code = parse_expression();
69 152
        if( !this.lexer.isEOF() ) {
70 153
            throw new ExpressionSyntaxException(lexer);
71 154
        }
72 155
        return code;
73 156
    }
74 157

  
75
    private Code parseExpression() {
158
    public Code parse_expression() {
76 159
        Code code = parse_relational();
77 160
        return code;
78 161
    }
79 162

  
80
    private Code parse_relational() {
163
    public Code parse_relational() {
81 164
        Code op1 = parse_not();
82 165
        Code op2;
83 166
        while( true ) {
......
105 188
        }
106 189
    }
107 190

  
108
    private Code parse_not() {
191
    public Code parse_not() {
109 192
        Code op1;
110 193
        Token token = lexer.look();
111 194
        if( token.getType() == Token.OP_NOT ) {
......
118 201
        return op1;
119 202
    }
120 203

  
121
    private Code parse_conditional() {
204
    public Code parse_conditional() {
122 205
        Code op1 = parse_sum();
123 206
        Code op2;
124 207
        while( true ) {
......
160 243
                lexer.next();
161 244
                op2 = parse_sum();
162 245
                if( op2==null ) {
163
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_EQ_operator(),lexer);
246
                    token = lexer.look();
247
                    String tip = null;
248
                    switch(token.getType()) {
249
                        case Token.OP_GT:
250
                            tip = I18N.The_operator_greater_than_or_equal_is_ge();
251
                            break;
252
                        case Token.OP_LT:
253
                            tip = I18N.The_operator_less_than_or_equal_is_ge();
254
                            break;
255
                    }
256
                    throw new ExpressionSyntaxException(
257
                            I18N.Cant_recognize_the_second_operand_of_EQ_operator(),
258
                            lexer,
259
                            tip
260
                    );
164 261
                }
165 262
                op1 = codeBuilder.eq(op1, op2);
166 263
                break;
......
221 318
        }
222 319
    }
223 320

  
224
    private Code parse_sum() {
321
    public Code parse_sum() {
225 322
        Code op1 = parse_factor();
226 323
        Code op2;
227 324
        while( true ) {
228 325
            Token token = lexer.look();
229 326
            switch( token.getType() ) {
327
            case Token.OP_CONCAT:
328
                lexer.next();
329
                op2 = parse_factor();
330
                op1 = codeBuilder.concat(op1, op2);
331
                break;
230 332
            case Token.OP_ADD:
231 333
                lexer.next();
232 334
                op2 = parse_factor();
......
243 345
        }
244 346
    }
245 347

  
246
    private Code parse_factor() {
348
    public Code parse_factor() {
247 349
        Code op1 = parse_getattr();
248 350
        Code op2;
249 351
        while( true ) {
......
273 375
                }
274 376
                op1 = codeBuilder.mod(op1, op2);
275 377
                break;
378
            case Token.OPEN_BRACKET:
379
                lexer.next();
380
                Code codeIndex = parse_expression();
381
                if( codeIndex == null ) {
382
                    throw new ExpressionSyntaxException(I18N.unexpected_end_of_source(),lexer);
383
                }
384
                token = lexer.look();
385
                if( token.getType()!=Token.CLOSED_BRACKET) {
386
                    throw new ExpressionSyntaxException(I18N.A_XTokenX_was_expected_and_XliteralX_was_found("]", token.getLiteral()),lexer);
387
                }
388
                lexer.next();
389
                Code code = codeBuilder.getitem(op1, codeIndex);
390
                return code;
276 391
            default:
277 392
                return op1;
278 393
            }
279 394
        }
280 395
    }
281 396

  
282
    private Code parse_getattr() {
397
    public Code parse_getattr() {
283 398
        Code op1 = parse_termino();
284 399
        if( !isObjectAccessSupported() ) {
285 400
            return op1;
......
301 416
                next = lexer.look();
302 417
                if( next.getType() == Token.PARENTHESIS_OPEN ) {
303 418
                    lexer.next();
304
                    Arguments args = parseArgs();
419
                    Codes args = parse_expressions(",");
305 420
                    next = lexer.next();
306 421
                    if( next.getType() != Token.PARENTHESIS_CLOSE ) {
307 422
                        throw new ExpressionSyntaxException(
......
319 434
        }
320 435
    }    
321 436

  
322
    private Code parse_termino() {
437
    public Code parse_termino() {
323 438

  
324 439
        Token token = lexer.look();
325 440
        switch( token.getType() ) {
326 441
        case Token.PARENTHESIS_OPEN: {
327 442
                lexer.next();
328
                Code value = parseExpression();
443
                Code value = parse_expression();
329 444
                Token next = lexer.next();
330 445
                switch(next.getType()) {
331 446
                    case Token.PARENTHESIS_CLOSE:
......
344 459
                return value;
345 460
            }
346 461
        case Token.IDENTIFIER: {
462
                Code code = parse_grammars();
463
                if( code!=null ) {
464
                    return code;
465
                }
466
                if( this.grammars.isReservedWord(token.getLiteral()) ) {
467
                    return null;
468
                }
347 469
                lexer.next();
348 470
                String id = (String) token.getLiteral();
349 471
                Token next = lexer.look();
350 472
                if( next.getType() == Token.PARENTHESIS_OPEN ) {
351 473
                    lexer.next();
352
                    Arguments args = parseArgs();
474
                    Codes args = parse_expressions(",");
353 475
                    next = lexer.next();
354 476
                    switch(next.getType()) {
355 477
                        case Token.PARENTHESIS_CLOSE:
......
394 516
            return codeBuilder.negate(code);
395 517
        case Token.EOF:
396 518
            throw new ExpressionSyntaxException(I18N.unexpected_end_of_source(),lexer);
519
        default:
520
            return parse_grammars();
397 521
        }
398
        return null;
399 522
    }
400 523

  
401
    private Arguments parseArgs() {
402
        Arguments args = null;
524
    public Codes parse_expressions(String sep) {
525
        BaseCodes codes = null;
403 526
        while( true ) {
404
            Code arg = parseExpression();
405
            if( arg!=null ) {
406
                if( args == null ) {
407
                    args = codeBuilder.args();
527
            Code code = parse_expression();
528
            if( code!=null ) {
529
                if( codes == null ) {
530
                    codes = (BaseCodes) codeBuilder.args();
408 531
                }
409
                ((DefaultCodeBuilder.BaseArguments)args).add(arg);
532
                codes.add(code);
410 533
            }
411 534
            Token next = lexer.look();
412
            switch( next.getType() ) {
413
            case Token.COMA:
535
            String literal = next.getLiteral();
536
            if( literal == null ) {
537
                return codes;
538
            }
539
            literal = literal.trim();
540
            if( sep.equals(literal) ) {
414 541
                lexer.next(); // Consume el ",".
415
                break;
416
            default:
417
                return args;
542
            } else {
543
                return codes;
418 544
            }
419 545
        }
420 546
    }
547

  
548
    private Code parse_grammars() {
549
        StatementContext context = new DefaultStatementContext();
550
        Statement stmt = this.grammars.getApplicableStatement(context);
551
        if( stmt!=null ) {
552
            Code code1 = stmt.parse(context);
553
            return code1;
554
        }
555
        return null;
556
    }
421 557
}

Also available in: Unified diff