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 @ 46050

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