Statistics
| Revision:

svn-gvsig-desktop / 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 @ 46010

History | View | Annotate | Download (26.9 KB)

1 43512 jjdelcerro
package org.gvsig.expressionevaluator.impl;
2
3 44139 jjdelcerro
import java.util.HashMap;
4
import java.util.Map;
5 44750 jjdelcerro
import java.util.Stack;
6 44139 jjdelcerro
import org.apache.commons.lang3.StringUtils;
7 43512 jjdelcerro
import org.gvsig.expressionevaluator.Compiler;
8
import org.gvsig.expressionevaluator.LexicalAnalyzer;
9
import org.gvsig.expressionevaluator.LexicalAnalyzer.Token;
10
import org.gvsig.expressionevaluator.Code;
11 45025 jjdelcerro
import org.gvsig.expressionevaluator.Code.Callable;
12 43512 jjdelcerro
import org.gvsig.expressionevaluator.CodeBuilder;
13 44139 jjdelcerro
import org.gvsig.expressionevaluator.Codes;
14 45025 jjdelcerro
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_DICT;
15 44644 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
16 43983 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionSyntaxException;
17 44139 jjdelcerro
import org.gvsig.expressionevaluator.GrammarSet;
18
import org.gvsig.expressionevaluator.Statement;
19
import org.gvsig.expressionevaluator.Statement.StatementContext;
20
import org.gvsig.expressionevaluator.impl.DefaultCodeBuilder.BaseCodes;
21 44211 jjdelcerro
import org.gvsig.expressionevaluator.impl.DefaultCodeBuilder.BaseConstant;
22
import org.gvsig.expressionevaluator.impl.function.operator.NegOperator;
23 44379 jjdelcerro
import org.gvsig.expressionevaluator.impl.function.programming.CodeBlockFunction;
24 44738 jjdelcerro
import org.gvsig.expressionevaluator.spi.AbstractLexicalAnalyzer;
25
import org.slf4j.Logger;
26
import org.slf4j.LoggerFactory;
27 43512 jjdelcerro
28
public class DefaultCompiler implements Compiler {
29
30 44738 jjdelcerro
    protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultCompiler.class);
31
32 44139 jjdelcerro
    class DefaultStatementContext implements StatementContext {
33 44750 jjdelcerro
34
        private class State {
35
          public String codeClassifier;
36
          public Map<String,Code> codes;
37
        }
38
39
        private State state;
40
        private final Stack<State> states;
41 44139 jjdelcerro
42 44750 jjdelcerro
        public DefaultStatementContext() {
43
          this.state = new State();
44
          this.states = new Stack<>();
45
        }
46
47
        @Override
48
        public void save_state() {
49 45153 jjdelcerro
          this.trace("save_state");
50 44750 jjdelcerro
          ((AbstractLexicalAnalyzer)lexer).save_state();
51
          this.states.push(state);
52
        }
53 44139 jjdelcerro
54
        @Override
55 44750 jjdelcerro
        public void restore_state() {
56
          ((AbstractLexicalAnalyzer)lexer).restore_state();
57
          state = this.states.pop();
58 45153 jjdelcerro
          this.trace("restore_state");
59 44750 jjdelcerro
        }
60
61
        @Override
62
        public void drop_state() {
63
          ((AbstractLexicalAnalyzer)lexer).drop_state();
64
          this.states.pop();
65 45153 jjdelcerro
          this.trace("drop_state");
66 44750 jjdelcerro
        }
67
68
        @Override
69 44139 jjdelcerro
        public Compiler getCompiler() {
70
            return DefaultCompiler.this;
71
        }
72
73
        @Override
74
        public LexicalAnalyzer getLexicalAnalyzer() {
75
            return lexer;
76
        }
77
78
        @Override
79
        public void setCode(String id, Code code) {
80 44750 jjdelcerro
            if( this.state.codes == null ) {
81
                this.state.codes = new HashMap<>();
82 44139 jjdelcerro
            }
83 44750 jjdelcerro
            if( !StringUtils.isBlank(this.state.codeClassifier) ) {
84 44139 jjdelcerro
                if( id.contains("#") ) {
85 44750 jjdelcerro
                    id = StringUtils.replace(id,"#",this.state.codeClassifier,1);
86 44139 jjdelcerro
                }
87
            }
88 44750 jjdelcerro
            this.state.codes.put(id.toUpperCase(), code);
89 44139 jjdelcerro
        }
90
91 44379 jjdelcerro
        @Override
92 44139 jjdelcerro
        public Code getCode(String id) {
93 45934 jjdelcerro
            if( this.state==null || this.state.codes==null ) {
94
                return null;
95
            }
96
            if( StringUtils.isBlank(id) ) {
97
                return null;
98
            }
99 44750 jjdelcerro
            return this.state.codes.get(id.toUpperCase());
100 44139 jjdelcerro
        }
101
102
        @Override
103
        public void setCodeClassifier(String classifier) {
104 44750 jjdelcerro
            this.state.codeClassifier = classifier;
105 44139 jjdelcerro
        }
106
107
        @Override
108
        public String getCodeClassifier() {
109 44750 jjdelcerro
            return this.state.codeClassifier;
110 44139 jjdelcerro
        }
111
112
        @Override
113
        public CodeBuilder getCodeBuilder() {
114
            return codeBuilder;
115
        }
116
117
        @Override
118
        public Token look_token() {
119
            return lexer.look();
120
        }
121
122
        @Override
123
        public Token next_token() {
124
            return lexer.next();
125
        }
126
127
        @Override
128 45153 jjdelcerro
        public Code parse_expression(boolean allow_assignement) {
129
            return DefaultCompiler.this.parse_expression(allow_assignement);
130 44139 jjdelcerro
        }
131
132
        @Override
133
        public Codes parse_expressions(String separator) {
134
            return DefaultCompiler.this.parse_expressions(separator);
135
        }
136
137 44738 jjdelcerro
        @Override
138 44384 jjdelcerro
        public boolean isReservedWord(String s) {
139
            return grammars.isReservedWord(s);
140
        }
141 44738 jjdelcerro
142
        @Override
143
        public void trace(String msg) {
144 45153 jjdelcerro
//            LexicalAnalyzer lex = this.getLexicalAnalyzer();
145
//            String s = StringUtils.left(lex.getSource(), lex.getPosition()) + "[*]" + StringUtils.mid(lex.getSource(), lex.getPosition(), 200);
146
//            if( s.length()>200 ) {
147
//                s = "..."+StringUtils.mid(s, lex.getPosition()-100, 200)+"...";
148
//            }
149
//            System.out.println(msg+". "+s);
150 44738 jjdelcerro
        }
151 44139 jjdelcerro
    }
152
153 43939 jjdelcerro
    private boolean objectAccessSupported;
154 43512 jjdelcerro
    private LexicalAnalyzer lexer;
155
    private CodeBuilder codeBuilder;
156 44139 jjdelcerro
    private final GrammarSet grammars;
157 44644 jjdelcerro
    protected ExpressionEvaluatorManager manager;
158 43532 jjdelcerro
    //
159
    // https://www.postgresql.org/docs/9.1/static/functions.html
160
    //
161 43512 jjdelcerro
162 44644 jjdelcerro
    public DefaultCompiler(ExpressionEvaluatorManager manager) {
163
        this.manager = manager;
164 44139 jjdelcerro
        this.grammars = new DefaultGrammarSet();
165 43512 jjdelcerro
        this.lexer = new SQLLexicalAnalyzer();
166 44644 jjdelcerro
        this.codeBuilder = new DefaultCodeBuilder(manager);
167 43939 jjdelcerro
        this.objectAccessSupported = true;
168 43512 jjdelcerro
    }
169
170
    @Override
171 43809 jjdelcerro
    public Compiler clone() throws CloneNotSupportedException {
172
        DefaultCompiler other = (DefaultCompiler) super.clone();
173
        other.lexer = lexer.clone();
174
        other.codeBuilder = codeBuilder.clone();
175
176
        return other;
177
    }
178
179
    @Override
180 43512 jjdelcerro
    public void setLexicalAnalyzer(LexicalAnalyzer lexer) {
181
        this.lexer = lexer;
182
    }
183 43983 jjdelcerro
184
    @Override
185
    public LexicalAnalyzer getLexicalAnalyzer() {
186
        return this.lexer;
187
    }
188 43512 jjdelcerro
189
    @Override
190
    public void setCodeBuilder(CodeBuilder codeBuilder) {
191
        this.codeBuilder = codeBuilder;
192
    }
193 43809 jjdelcerro
194 43512 jjdelcerro
    @Override
195 43809 jjdelcerro
    public CodeBuilder getCodeBuilder() {
196
        return this.codeBuilder;
197
    }
198
199
    @Override
200 43939 jjdelcerro
    public boolean isObjectAccessSupported() {
201
        return this.objectAccessSupported;
202
    }
203
204
    @Override
205
    public void setObjectAccessSupported(boolean objectAccessSupported) {
206
        this.objectAccessSupported = objectAccessSupported;
207
    }
208 44139 jjdelcerro
209 43939 jjdelcerro
    @Override
210 44139 jjdelcerro
    public GrammarSet getGrammars() {
211
        return this.grammars;
212
    }
213
214
    @Override
215 43512 jjdelcerro
    public Code compileExpression(String expression) {
216 45950 jjdelcerro
        if( StringUtils.isBlank(expression) ) {
217
            return this.getCodeBuilder().constant(null);
218
        }
219
220 43983 jjdelcerro
        this.lexer.setSource(expression.trim());
221 44139 jjdelcerro
        Code code = parse_expression();
222 43983 jjdelcerro
        if( !this.lexer.isEOF() ) {
223
            throw new ExpressionSyntaxException(lexer);
224
        }
225
        return code;
226 43512 jjdelcerro
    }
227 45153 jjdelcerro
228
    public Code parse_expression() {
229
        return this.parse_expression(true);
230
    }
231 43512 jjdelcerro
232 45153 jjdelcerro
    public Code parse_expression(boolean allow_assignement) {
233 43983 jjdelcerro
        Code code = parse_relational();
234 45153 jjdelcerro
        if( code != null && allow_assignement) {
235
            Token token = lexer.look();
236
            if( token.is("AS") ) {
237
                lexer.next();
238
                token = lexer.look();
239
                if( token.getType() != Token.IDENTIFIER ) {
240
                    throw new ExpressionSyntaxException(
241
                        I18N.An_identifier_was_expected_and_XliteralX_was_found(token.getLiteral()),
242
                        lexer
243
                    );
244
                }
245
                token = lexer.next();
246
                code = codeBuilder.let(token.getLiteral(),code);
247
            }
248
        }
249 43983 jjdelcerro
        return code;
250 43512 jjdelcerro
    }
251
252 44139 jjdelcerro
    public Code parse_relational() {
253 43512 jjdelcerro
        Code op1 = parse_not();
254
        Code op2;
255
        while( true ) {
256
            Token token = lexer.look();
257
            switch( token.getType() ) {
258
            case Token.OP_OR:
259
                lexer.next();
260
                op2 = parse_not();
261 43983 jjdelcerro
                if( op2==null ) {
262 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_OR_operator(),lexer);
263 43983 jjdelcerro
                }
264 43512 jjdelcerro
                op1 = codeBuilder.or(op1, op2);
265
                break;
266
            case Token.OP_AND:
267
                lexer.next();
268
                op2 = parse_not();
269 43983 jjdelcerro
                if( op2==null ) {
270 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_AND_operator(),lexer);
271 43983 jjdelcerro
                }
272 43512 jjdelcerro
                op1 = codeBuilder.and(op1, op2);
273
                break;
274
            default:
275
                return op1;
276
            }
277
        }
278
    }
279
280 44139 jjdelcerro
    public Code parse_not() {
281 43512 jjdelcerro
        Code op1;
282
        Token token = lexer.look();
283
        if( token.getType() == Token.OP_NOT ) {
284
            lexer.next();
285
            op1 = parse_conditional();
286
            op1 = codeBuilder.not(op1);
287
        } else {
288
            op1 = parse_conditional();
289
        }
290
        return op1;
291
    }
292
293 44139 jjdelcerro
    public Code parse_conditional() {
294 43512 jjdelcerro
        Code op1 = parse_sum();
295
        Code op2;
296
        while( true ) {
297
            Token token = lexer.look();
298
            switch( token.getType() ) {
299
            case Token.OP_LT:
300
                lexer.next();
301
                op2 = parse_sum();
302 43983 jjdelcerro
                if( op2==null ) {
303 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_LT_operator(),lexer);
304 43983 jjdelcerro
                }
305 43512 jjdelcerro
                op1 = codeBuilder.lt(op1, op2);
306
                break;
307
            case Token.OP_GT:
308
                lexer.next();
309
                op2 = parse_sum();
310 43983 jjdelcerro
                if( op2==null ) {
311 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_GT_operator(),lexer);
312 43983 jjdelcerro
                }
313 43512 jjdelcerro
                op1 = codeBuilder.gt(op1, op2);
314
                break;
315
            case Token.OP_LE:
316
                lexer.next();
317
                op2 = parse_sum();
318 43983 jjdelcerro
                if( op2==null ) {
319 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_LE_operator(),lexer);
320 43983 jjdelcerro
                }
321 43512 jjdelcerro
                op1 = codeBuilder.le(op1, op2);
322
                break;
323
            case Token.OP_GE:
324
                lexer.next();
325
                op2 = parse_sum();
326 43983 jjdelcerro
                if( op2==null ) {
327 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_GE_operator(),lexer);
328 43983 jjdelcerro
                }
329 43512 jjdelcerro
                op1 = codeBuilder.ge(op1, op2);
330
                break;
331
            case Token.OP_EQ:
332
                lexer.next();
333
                op2 = parse_sum();
334 43983 jjdelcerro
                if( op2==null ) {
335 44139 jjdelcerro
                    token = lexer.look();
336
                    String tip = null;
337
                    switch(token.getType()) {
338
                        case Token.OP_GT:
339
                            tip = I18N.The_operator_greater_than_or_equal_is_ge();
340
                            break;
341
                        case Token.OP_LT:
342
                            tip = I18N.The_operator_less_than_or_equal_is_ge();
343
                            break;
344
                    }
345
                    throw new ExpressionSyntaxException(
346
                            I18N.Cant_recognize_the_second_operand_of_EQ_operator(),
347
                            lexer,
348
                            tip
349
                    );
350 43983 jjdelcerro
                }
351 43512 jjdelcerro
                op1 = codeBuilder.eq(op1, op2);
352
                break;
353 43521 jjdelcerro
            case Token.OP_NE:
354 43512 jjdelcerro
                lexer.next();
355 43521 jjdelcerro
                op2 = parse_sum();
356 43983 jjdelcerro
                if( op2==null ) {
357 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_NEQ_operator(),lexer);
358 43983 jjdelcerro
                }
359 43521 jjdelcerro
                op1 = codeBuilder.ne(op1, op2);
360
                break;
361
            case Token.PRED_IS: {
362
                    lexer.next();
363
                    Token next = lexer.look();
364 44361 jjdelcerro
                    switch(next.getType()) {
365
                        case Token.NOTNULL:
366
                            lexer.next();
367
                            op1 = codeBuilder.is(op1, codeBuilder.constant(null));
368
                            op1 = codeBuilder.not(op1);
369
                            break;
370
                        case Token.OP_NOT:
371
                            lexer.next();
372
                            next = lexer.look();
373
                            if( next.getType() == Token.NULL ) {
374
                                lexer.next();
375
                                op1 = codeBuilder.is(op1, codeBuilder.constant(null));
376
                            } else {
377
                                op2 = parse_sum();
378
                                if( op2==null ) {
379
                                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_IS_operator(),lexer);
380
                                }
381
                                op1 = codeBuilder.is(op1, op2);
382
                            }
383
                            op1 = codeBuilder.not(op1);
384
                            break;
385
                        case Token.NULL:
386
                            lexer.next();
387
                            op1 = codeBuilder.is(op1, codeBuilder.constant(null));
388
                            break;
389
                        default:
390
                            op2 = parse_sum();
391
                            if( op2==null ) {
392
                                throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_IS_operator(),lexer);
393
                            }
394
                            op1 = codeBuilder.is(op1, op2);
395 43521 jjdelcerro
                    }
396 43512 jjdelcerro
                }
397 43521 jjdelcerro
                break;
398 43512 jjdelcerro
            case Token.ISNULL:
399
                lexer.next();
400
                op1 = codeBuilder.is(op1, codeBuilder.constant(null));
401
                break;
402 43532 jjdelcerro
            case Token.OP_REGEXP:
403
                lexer.next();
404
                op2 = parse_sum();
405 43983 jjdelcerro
                if( op2==null ) {
406 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_REGEXP_operator(),lexer);
407 43983 jjdelcerro
                }
408 43532 jjdelcerro
                op1 = codeBuilder.regexp(op1, op2);
409
                break;
410 43512 jjdelcerro
            case Token.PRED_LIKE:
411
                lexer.next();
412
                op2 = parse_sum();
413 43983 jjdelcerro
                if( op2==null ) {
414 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_LIKE_operator(),lexer);
415 43983 jjdelcerro
                }
416 43512 jjdelcerro
                op1 = codeBuilder.like(op1, op2);
417
                break;
418
            case Token.PRED_ILIKE:
419
                lexer.next();
420
                op2 = parse_sum();
421 43983 jjdelcerro
                if( op2==null ) {
422 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_ILIKE_operator(),lexer);
423 43983 jjdelcerro
                }
424 43512 jjdelcerro
                op1 = codeBuilder.ilike(op1, op2);
425
                break;
426
            default:
427
                return op1;
428
            }
429
        }
430
    }
431
432 44139 jjdelcerro
    public Code parse_sum() {
433 43512 jjdelcerro
        Code op1 = parse_factor();
434
        Code op2;
435
        while( true ) {
436
            Token token = lexer.look();
437
            switch( token.getType() ) {
438 44139 jjdelcerro
            case Token.OP_CONCAT:
439
                lexer.next();
440
                op2 = parse_factor();
441
                op1 = codeBuilder.concat(op1, op2);
442
                break;
443 43512 jjdelcerro
            case Token.OP_ADD:
444
                lexer.next();
445
                op2 = parse_factor();
446
                op1 = codeBuilder.add(op1, op2);
447
                break;
448
            case Token.OP_SUBST:
449
                lexer.next();
450
                op2 = parse_factor();
451
                op1 = codeBuilder.subst(op1, op2);
452
                break;
453
            default:
454
                return op1;
455
            }
456
        }
457
    }
458
459 44139 jjdelcerro
    public Code parse_factor() {
460 43939 jjdelcerro
        Code op1 = parse_getattr();
461 43512 jjdelcerro
        Code op2;
462
        while( true ) {
463
            Token token = lexer.look();
464
            switch( token.getType() ) {
465
            case Token.OP_MULT:
466
                lexer.next();
467 43939 jjdelcerro
                op2 = parse_getattr();
468 43983 jjdelcerro
                if( op2==null ) {
469 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_MULT_operator(),lexer);
470 43983 jjdelcerro
                }
471 43512 jjdelcerro
                op1 = codeBuilder.mult(op1, op2);
472
                break;
473
            case Token.OP_DIV:
474
                lexer.next();
475 43939 jjdelcerro
                op2 = parse_getattr();
476 43983 jjdelcerro
                if( op2==null ) {
477 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_DIV_operator(),lexer);
478 43983 jjdelcerro
                }
479 43512 jjdelcerro
                op1 = codeBuilder.div(op1, op2);
480
                break;
481
            case Token.OP_MOD:
482
                lexer.next();
483 43939 jjdelcerro
                op2 = parse_getattr();
484 43983 jjdelcerro
                if( op2==null ) {
485 44098 jjdelcerro
                    throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_MOD_operator(),lexer);
486 43983 jjdelcerro
                }
487 43512 jjdelcerro
                op1 = codeBuilder.mod(op1, op2);
488
                break;
489 44139 jjdelcerro
            case Token.OPEN_BRACKET:
490
                lexer.next();
491
                Code codeIndex = parse_expression();
492
                if( codeIndex == null ) {
493
                    throw new ExpressionSyntaxException(I18N.unexpected_end_of_source(),lexer);
494
                }
495
                token = lexer.look();
496
                if( token.getType()!=Token.CLOSED_BRACKET) {
497
                    throw new ExpressionSyntaxException(I18N.A_XTokenX_was_expected_and_XliteralX_was_found("]", token.getLiteral()),lexer);
498
                }
499
                lexer.next();
500
                Code code = codeBuilder.getitem(op1, codeIndex);
501
                return code;
502 43512 jjdelcerro
            default:
503
                return op1;
504
            }
505
        }
506
    }
507
508 44139 jjdelcerro
    public Code parse_getattr() {
509 43939 jjdelcerro
        Code op1 = parse_termino();
510
        if( !isObjectAccessSupported() ) {
511
            return op1;
512
        }
513
        while( true ) {
514
            Token next = lexer.look();
515
            switch( next.getType() ) {
516
            case Token.OP_GETATTR:
517
                lexer.next();
518
                next = lexer.look();
519
                if( next.getType()!=Token.IDENTIFIER ) {
520 43983 jjdelcerro
                    throw new ExpressionSyntaxException(
521 44098 jjdelcerro
                        I18N.An_attribute_identifier_was_expected_and_XliteralX_was_found(next.getLiteral()),
522
                        lexer
523 43983 jjdelcerro
                    );
524 43939 jjdelcerro
                }
525
                String id = (String) next.getLiteral();
526
                lexer.next();
527
                next = lexer.look();
528
                if( next.getType() == Token.PARENTHESIS_OPEN ) {
529
                    lexer.next();
530 44139 jjdelcerro
                    Codes args = parse_expressions(",");
531 43939 jjdelcerro
                    next = lexer.next();
532
                    if( next.getType() != Token.PARENTHESIS_CLOSE ) {
533 43983 jjdelcerro
                        throw new ExpressionSyntaxException(
534 44098 jjdelcerro
                            I18N.Closing_parenthesis_was_expected_and_XliteralX_was_found(next.getLiteral()),
535
                            lexer
536 43983 jjdelcerro
                        );
537 43939 jjdelcerro
                    }
538 44379 jjdelcerro
                    op1 = codeBuilder.method(op1, id, args);
539 43939 jjdelcerro
                } else {
540 44379 jjdelcerro
                    op1 = codeBuilder.getattr(op1, id);
541 43939 jjdelcerro
                }
542 44379 jjdelcerro
                break;
543 43939 jjdelcerro
            default:
544
                return op1;
545
            }
546
        }
547
    }
548
549 45132 jjdelcerro
    @SuppressWarnings("UnusedAssignment")
550 44139 jjdelcerro
    public Code parse_termino() {
551 43512 jjdelcerro
552
        Token token = lexer.look();
553
        switch( token.getType() ) {
554
        case Token.PARENTHESIS_OPEN: {
555 43521 jjdelcerro
                lexer.next();
556 44139 jjdelcerro
                Code value = parse_expression();
557 43521 jjdelcerro
                Token next = lexer.next();
558 44098 jjdelcerro
                switch(next.getType()) {
559
                    case Token.PARENTHESIS_CLOSE:
560
                        break;
561
                    case Token.EOF:
562
                        throw new ExpressionSyntaxException(
563
                            I18N.Closing_parenthesis_was_expected_and_end_of_source_was_found(),
564
                            lexer
565
                        );
566
                    default:
567
                        throw new ExpressionSyntaxException(
568
                            I18N.Closing_parenthesis_was_expected_and_XliteralX_was_found(next.getLiteral()),
569
                            lexer
570
                        );
571 43521 jjdelcerro
                }
572
                return value;
573 43512 jjdelcerro
            }
574
        case Token.IDENTIFIER: {
575 44139 jjdelcerro
                Code code = parse_grammars();
576
                if( code!=null ) {
577
                    return code;
578
                }
579
                if( this.grammars.isReservedWord(token.getLiteral()) ) {
580
                    return null;
581
                }
582 43512 jjdelcerro
                lexer.next();
583 43521 jjdelcerro
                String id = (String) token.getLiteral();
584
                Token next = lexer.look();
585
                if( next.getType() == Token.PARENTHESIS_OPEN ) {
586 44750 jjdelcerro
                    next = lexer.next();
587 44738 jjdelcerro
                    Codes args = parse_arguments();
588 43521 jjdelcerro
                    next = lexer.next();
589 44098 jjdelcerro
                    switch(next.getType()) {
590
                        case Token.PARENTHESIS_CLOSE:
591
                            break;
592
                        case Token.EOF:
593
                            throw new ExpressionSyntaxException(
594
                                I18N.Closing_parenthesis_was_expected_and_end_of_source_was_found(),
595
                                lexer
596
                            );
597
                        default:
598
                            throw new ExpressionSyntaxException(
599
                                I18N.Closing_parenthesis_was_expected_and_XliteralX_was_found(next.getLiteral()),
600
                                lexer
601
                            );
602 43521 jjdelcerro
                    }
603 45025 jjdelcerro
                    // Optimizacion para cuando se esta invocando a la funcion dict
604
                    if( StringUtils.equalsIgnoreCase(id, FUNCTION_DICT) && args!=null && args.size()==1 ) {
605
                        code = args.get(0);
606
                        if( code.code()==Code.CALLABLE &&
607
                            StringUtils.equalsIgnoreCase(((Callable)code).name(),FUNCTION_DICT) ) {
608
                            return code;
609
                        }
610
                    }
611 43521 jjdelcerro
                    return codeBuilder.function(id, args);
612
                } else {
613 44379 jjdelcerro
                    if( StringUtils.equalsIgnoreCase(id, "TRUE") ) {
614
                        return codeBuilder.constant(true);
615
                    }
616
                    if( StringUtils.equalsIgnoreCase(id, "FALSE") ) {
617
                        return codeBuilder.constant(false);
618
                    }
619 43521 jjdelcerro
                    return codeBuilder.identifier(id);
620 43512 jjdelcerro
                }
621
            }
622
        case Token.STRING_LITERAL:
623
            lexer.next();
624
            return codeBuilder.constant(token.getValue());
625
        case Token.INTEGER_LITERAL:
626
            lexer.next();
627
            return codeBuilder.constant(token.getValue());
628
        case Token.FLOATING_POINT_LITERAL:
629
            lexer.next();
630
            return codeBuilder.constant(token.getValue());
631
        case Token.NULL:
632
            lexer.next();
633
            return codeBuilder.constant(null);
634
        case Token.TRUE:
635
            lexer.next();
636
            return codeBuilder.constant(true);
637
        case Token.FALSE:
638
            lexer.next();
639
            return codeBuilder.constant(false);
640 44098 jjdelcerro
        case Token.OP_SUBST:
641
            lexer.next();
642
            Code code = parse_termino();
643 44211 jjdelcerro
            if( code.code()==Code.CONSTANT ) {
644
                BaseConstant c = (BaseConstant)code;
645
                if( c.value() instanceof Number ) {
646
                    c.value(NegOperator.negate((Number) c.value()));
647
                    return code;
648
                }
649 44212 jjdelcerro
                throw new ExpressionSyntaxException(I18N.A_numeric_constant_was_expected_after_the_unary_operator_minus(),lexer);
650 44211 jjdelcerro
            }
651 44098 jjdelcerro
            return codeBuilder.negate(code);
652
        case Token.EOF:
653
            throw new ExpressionSyntaxException(I18N.unexpected_end_of_source(),lexer);
654 44139 jjdelcerro
        default:
655
            return parse_grammars();
656 43512 jjdelcerro
        }
657
    }
658
659 44139 jjdelcerro
    public Codes parse_expressions(String sep) {
660
        BaseCodes codes = null;
661 43512 jjdelcerro
        while( true ) {
662 44139 jjdelcerro
            Code code = parse_expression();
663
            if( code!=null ) {
664
                if( codes == null ) {
665
                    codes = (BaseCodes) codeBuilder.args();
666 43519 jjdelcerro
                }
667 44139 jjdelcerro
                codes.add(code);
668 43519 jjdelcerro
            }
669 43512 jjdelcerro
            Token next = lexer.look();
670 44139 jjdelcerro
            String literal = next.getLiteral();
671
            if( literal == null ) {
672
                return codes;
673
            }
674
            literal = literal.trim();
675
            if( sep.equals(literal) ) {
676 43512 jjdelcerro
                lexer.next(); // Consume el ",".
677 44139 jjdelcerro
            } else {
678
                return codes;
679 43512 jjdelcerro
            }
680
        }
681
    }
682 44139 jjdelcerro
683 45025 jjdelcerro
    private String getKeyArgument() {
684
        ((AbstractLexicalAnalyzer)lexer).save_state();
685
        Token next = lexer.look();
686
        if( next.getType()==Token.IDENTIFIER ) {
687
            String key = next.getLiteral();
688
            lexer.next();
689
            next = lexer.next();
690 45132 jjdelcerro
            if( next.is(":","=","=>") ) {
691 45025 jjdelcerro
                ((AbstractLexicalAnalyzer)lexer).drop_state();
692
                return key;
693
            }
694
        }
695
        ((AbstractLexicalAnalyzer)lexer).restore_state();
696
        return null;
697
    }
698
699 44738 jjdelcerro
    public Codes parse_arguments() {
700
        String sep = ",";
701
        BaseCodes codes = null;
702 45025 jjdelcerro
        Map<String,Code> kwargs = null;
703 44738 jjdelcerro
        while( true ) {
704 45025 jjdelcerro
            String key = getKeyArgument();
705
            if( key == null ) {
706
                if( kwargs != null ) {
707
                    throw new ExpressionSyntaxException(I18N.nonkeyword_arg_after_keyword_arg(),lexer);
708 44738 jjdelcerro
                }
709 45025 jjdelcerro
                Code code = parse_expression();
710
                if( code!=null ) {
711
                    if( codes == null ) {
712
                        codes = (BaseCodes) codeBuilder.args();
713
                    }
714
                    codes.add(code);
715
                }
716
            } else {
717
                if( kwargs == null ) {
718
                    kwargs = new HashMap<>();
719
                }
720
                Code code = parse_expression();
721
                kwargs.put(key, code);
722 44738 jjdelcerro
            }
723
            Token next = lexer.look();
724 45025 jjdelcerro
            if( !next.is(sep) ) {
725
                break;
726 44738 jjdelcerro
            }
727 45025 jjdelcerro
            lexer.next(); // Consume el ",".
728
        }
729
        if( kwargs!=null ) {
730
            if( codes == null ) {
731
                codes = (BaseCodes) codeBuilder.args();
732 44738 jjdelcerro
            }
733 45025 jjdelcerro
            Code code = codeBuilder.dict(kwargs);
734
            codes.add(code);
735 44738 jjdelcerro
        }
736 45025 jjdelcerro
        return codes;
737 44738 jjdelcerro
    }
738
739 44139 jjdelcerro
    private Code parse_grammars() {
740
        StatementContext context = new DefaultStatementContext();
741 44379 jjdelcerro
        Code code;
742
        BaseCodes args = (BaseCodes) this.codeBuilder.args();
743 45153 jjdelcerro
        context.trace("compiler.parse_gramars");
744 44139 jjdelcerro
        Statement stmt = this.grammars.getApplicableStatement(context);
745 44379 jjdelcerro
        while( stmt!=null ) {
746
            code = stmt.parse(context);
747
            args.add(code);
748
            stmt = this.grammars.getApplicableStatement(context);
749 44139 jjdelcerro
        }
750 44379 jjdelcerro
        switch(args.size()) {
751
            case 0 :
752
                code = null;
753
                break;
754
            case 1 :
755
                code = args.get(0);
756
                break;
757
            default:
758
                code = this.codeBuilder.function(CodeBlockFunction.NAME, args);
759
                break;
760
        }
761
        return code;
762 44139 jjdelcerro
    }
763 43512 jjdelcerro
}