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 @ 44644
History | View | Annotate | Download (21.7 KB)
1 | 43512 | jjdelcerro | package org.gvsig.expressionevaluator.impl; |
---|---|---|---|
2 | |||
3 | 44139 | jjdelcerro | import java.util.HashMap; |
4 | import java.util.Map; |
||
5 | import org.apache.commons.lang3.StringUtils; |
||
6 | 43512 | jjdelcerro | import org.gvsig.expressionevaluator.Compiler; |
7 | import org.gvsig.expressionevaluator.LexicalAnalyzer; |
||
8 | import org.gvsig.expressionevaluator.LexicalAnalyzer.Token; |
||
9 | import org.gvsig.expressionevaluator.Code; |
||
10 | import org.gvsig.expressionevaluator.CodeBuilder; |
||
11 | 44139 | jjdelcerro | import org.gvsig.expressionevaluator.Codes; |
12 | 44644 | jjdelcerro | import org.gvsig.expressionevaluator.ExpressionEvaluatorManager; |
13 | 43983 | jjdelcerro | import org.gvsig.expressionevaluator.ExpressionSyntaxException; |
14 | 44139 | jjdelcerro | import org.gvsig.expressionevaluator.GrammarSet; |
15 | import org.gvsig.expressionevaluator.Statement; |
||
16 | import org.gvsig.expressionevaluator.Statement.StatementContext; |
||
17 | import org.gvsig.expressionevaluator.impl.DefaultCodeBuilder.BaseCodes; |
||
18 | 44211 | jjdelcerro | import org.gvsig.expressionevaluator.impl.DefaultCodeBuilder.BaseConstant; |
19 | import org.gvsig.expressionevaluator.impl.function.operator.NegOperator; |
||
20 | 44379 | jjdelcerro | import org.gvsig.expressionevaluator.impl.function.programming.CodeBlockFunction; |
21 | 43512 | jjdelcerro | |
22 | public class DefaultCompiler implements Compiler { |
||
23 | |||
24 | 44139 | jjdelcerro | class DefaultStatementContext implements StatementContext { |
25 | |||
26 | private String codeClassifier; |
||
27 | private Map<String,Code> codes; |
||
28 | |||
29 | @Override
|
||
30 | public Compiler getCompiler() { |
||
31 | return DefaultCompiler.this;
|
||
32 | } |
||
33 | |||
34 | @Override
|
||
35 | public LexicalAnalyzer getLexicalAnalyzer() {
|
||
36 | return lexer;
|
||
37 | } |
||
38 | |||
39 | @Override
|
||
40 | public void setCode(String id, Code code) { |
||
41 | if( this.codes == null ) { |
||
42 | this.codes = new HashMap<>(); |
||
43 | } |
||
44 | if( !StringUtils.isBlank(this.codeClassifier) ) { |
||
45 | if( id.contains("#") ) { |
||
46 | id = StringUtils.replace(id,"#",this.codeClassifier,1); |
||
47 | } |
||
48 | } |
||
49 | this.codes.put(id, code);
|
||
50 | } |
||
51 | |||
52 | 44379 | jjdelcerro | @Override
|
53 | 44139 | jjdelcerro | public Code getCode(String id) { |
54 | return this.codes.get(id); |
||
55 | } |
||
56 | |||
57 | @Override
|
||
58 | public void setCodeClassifier(String classifier) { |
||
59 | this.codeClassifier = classifier;
|
||
60 | } |
||
61 | |||
62 | @Override
|
||
63 | public String getCodeClassifier() { |
||
64 | return this.codeClassifier; |
||
65 | } |
||
66 | |||
67 | @Override
|
||
68 | public CodeBuilder getCodeBuilder() {
|
||
69 | return codeBuilder;
|
||
70 | } |
||
71 | |||
72 | @Override
|
||
73 | public Token look_token() {
|
||
74 | return lexer.look();
|
||
75 | } |
||
76 | |||
77 | @Override
|
||
78 | public Token next_token() {
|
||
79 | return lexer.next();
|
||
80 | } |
||
81 | |||
82 | @Override
|
||
83 | public Code parse_expression() {
|
||
84 | return DefaultCompiler.this.parse_expression();
|
||
85 | } |
||
86 | |||
87 | @Override
|
||
88 | public Codes parse_expressions(String separator) { |
||
89 | return DefaultCompiler.this.parse_expressions(separator);
|
||
90 | } |
||
91 | |||
92 | 44384 | jjdelcerro | public boolean isReservedWord(String s) { |
93 | return grammars.isReservedWord(s);
|
||
94 | } |
||
95 | 44139 | jjdelcerro | } |
96 | |||
97 | 43939 | jjdelcerro | private boolean objectAccessSupported; |
98 | 43512 | jjdelcerro | private LexicalAnalyzer lexer;
|
99 | private CodeBuilder codeBuilder;
|
||
100 | 44139 | jjdelcerro | private final GrammarSet grammars; |
101 | 44644 | jjdelcerro | protected ExpressionEvaluatorManager manager;
|
102 | 43532 | jjdelcerro | //
|
103 | // https://www.postgresql.org/docs/9.1/static/functions.html
|
||
104 | //
|
||
105 | 43512 | jjdelcerro | |
106 | 44644 | jjdelcerro | public DefaultCompiler(ExpressionEvaluatorManager manager) {
|
107 | this.manager = manager;
|
||
108 | 44139 | jjdelcerro | this.grammars = new DefaultGrammarSet(); |
109 | 43512 | jjdelcerro | this.lexer = new SQLLexicalAnalyzer(); |
110 | 44644 | jjdelcerro | this.codeBuilder = new DefaultCodeBuilder(manager); |
111 | 43939 | jjdelcerro | this.objectAccessSupported = true; |
112 | 43512 | jjdelcerro | } |
113 | |||
114 | @Override
|
||
115 | 43809 | jjdelcerro | public Compiler clone() throws CloneNotSupportedException { |
116 | DefaultCompiler other = (DefaultCompiler) super.clone();
|
||
117 | other.lexer = lexer.clone(); |
||
118 | other.codeBuilder = codeBuilder.clone(); |
||
119 | |||
120 | return other;
|
||
121 | } |
||
122 | |||
123 | @Override
|
||
124 | 43512 | jjdelcerro | public void setLexicalAnalyzer(LexicalAnalyzer lexer) { |
125 | this.lexer = lexer;
|
||
126 | } |
||
127 | 43983 | jjdelcerro | |
128 | @Override
|
||
129 | public LexicalAnalyzer getLexicalAnalyzer() {
|
||
130 | return this.lexer; |
||
131 | } |
||
132 | 43512 | jjdelcerro | |
133 | @Override
|
||
134 | public void setCodeBuilder(CodeBuilder codeBuilder) { |
||
135 | this.codeBuilder = codeBuilder;
|
||
136 | } |
||
137 | 43809 | jjdelcerro | |
138 | 43512 | jjdelcerro | @Override
|
139 | 43809 | jjdelcerro | public CodeBuilder getCodeBuilder() {
|
140 | return this.codeBuilder; |
||
141 | } |
||
142 | |||
143 | @Override
|
||
144 | 43939 | jjdelcerro | public boolean isObjectAccessSupported() { |
145 | return this.objectAccessSupported; |
||
146 | } |
||
147 | |||
148 | @Override
|
||
149 | public void setObjectAccessSupported(boolean objectAccessSupported) { |
||
150 | this.objectAccessSupported = objectAccessSupported;
|
||
151 | } |
||
152 | 44139 | jjdelcerro | |
153 | 43939 | jjdelcerro | @Override
|
154 | 44139 | jjdelcerro | public GrammarSet getGrammars() {
|
155 | return this.grammars; |
||
156 | } |
||
157 | |||
158 | @Override
|
||
159 | 43512 | jjdelcerro | public Code compileExpression(String expression) { |
160 | 43983 | jjdelcerro | this.lexer.setSource(expression.trim());
|
161 | 44139 | jjdelcerro | Code code = parse_expression(); |
162 | 43983 | jjdelcerro | if( !this.lexer.isEOF() ) { |
163 | throw new ExpressionSyntaxException(lexer); |
||
164 | } |
||
165 | return code;
|
||
166 | 43512 | jjdelcerro | } |
167 | |||
168 | 44139 | jjdelcerro | public Code parse_expression() {
|
169 | 43983 | jjdelcerro | Code code = parse_relational(); |
170 | return code;
|
||
171 | 43512 | jjdelcerro | } |
172 | |||
173 | 44139 | jjdelcerro | public Code parse_relational() {
|
174 | 43512 | jjdelcerro | Code op1 = parse_not(); |
175 | Code op2; |
||
176 | while( true ) { |
||
177 | Token token = lexer.look(); |
||
178 | switch( token.getType() ) {
|
||
179 | case Token.OP_OR:
|
||
180 | lexer.next(); |
||
181 | op2 = parse_not(); |
||
182 | 43983 | jjdelcerro | if( op2==null ) { |
183 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_OR_operator(),lexer); |
184 | 43983 | jjdelcerro | } |
185 | 43512 | jjdelcerro | op1 = codeBuilder.or(op1, op2); |
186 | break;
|
||
187 | case Token.OP_AND:
|
||
188 | lexer.next(); |
||
189 | op2 = parse_not(); |
||
190 | 43983 | jjdelcerro | if( op2==null ) { |
191 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_AND_operator(),lexer); |
192 | 43983 | jjdelcerro | } |
193 | 43512 | jjdelcerro | op1 = codeBuilder.and(op1, op2); |
194 | break;
|
||
195 | default:
|
||
196 | return op1;
|
||
197 | } |
||
198 | } |
||
199 | } |
||
200 | |||
201 | 44139 | jjdelcerro | public Code parse_not() {
|
202 | 43512 | jjdelcerro | Code op1; |
203 | Token token = lexer.look(); |
||
204 | if( token.getType() == Token.OP_NOT ) {
|
||
205 | lexer.next(); |
||
206 | op1 = parse_conditional(); |
||
207 | op1 = codeBuilder.not(op1); |
||
208 | } else {
|
||
209 | op1 = parse_conditional(); |
||
210 | } |
||
211 | return op1;
|
||
212 | } |
||
213 | |||
214 | 44139 | jjdelcerro | public Code parse_conditional() {
|
215 | 43512 | jjdelcerro | Code op1 = parse_sum(); |
216 | Code op2; |
||
217 | while( true ) { |
||
218 | Token token = lexer.look(); |
||
219 | switch( token.getType() ) {
|
||
220 | case Token.OP_LT:
|
||
221 | lexer.next(); |
||
222 | op2 = parse_sum(); |
||
223 | 43983 | jjdelcerro | if( op2==null ) { |
224 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_LT_operator(),lexer); |
225 | 43983 | jjdelcerro | } |
226 | 43512 | jjdelcerro | op1 = codeBuilder.lt(op1, op2); |
227 | break;
|
||
228 | case Token.OP_GT:
|
||
229 | lexer.next(); |
||
230 | op2 = parse_sum(); |
||
231 | 43983 | jjdelcerro | if( op2==null ) { |
232 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_GT_operator(),lexer); |
233 | 43983 | jjdelcerro | } |
234 | 43512 | jjdelcerro | op1 = codeBuilder.gt(op1, op2); |
235 | break;
|
||
236 | case Token.OP_LE:
|
||
237 | lexer.next(); |
||
238 | op2 = parse_sum(); |
||
239 | 43983 | jjdelcerro | if( op2==null ) { |
240 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_LE_operator(),lexer); |
241 | 43983 | jjdelcerro | } |
242 | 43512 | jjdelcerro | op1 = codeBuilder.le(op1, op2); |
243 | break;
|
||
244 | case Token.OP_GE:
|
||
245 | lexer.next(); |
||
246 | op2 = parse_sum(); |
||
247 | 43983 | jjdelcerro | if( op2==null ) { |
248 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_GE_operator(),lexer); |
249 | 43983 | jjdelcerro | } |
250 | 43512 | jjdelcerro | op1 = codeBuilder.ge(op1, op2); |
251 | break;
|
||
252 | case Token.OP_EQ:
|
||
253 | lexer.next(); |
||
254 | op2 = parse_sum(); |
||
255 | 43983 | jjdelcerro | if( op2==null ) { |
256 | 44139 | jjdelcerro | token = lexer.look(); |
257 | String tip = null; |
||
258 | switch(token.getType()) {
|
||
259 | case Token.OP_GT:
|
||
260 | tip = I18N.The_operator_greater_than_or_equal_is_ge(); |
||
261 | break;
|
||
262 | case Token.OP_LT:
|
||
263 | tip = I18N.The_operator_less_than_or_equal_is_ge(); |
||
264 | break;
|
||
265 | } |
||
266 | throw new ExpressionSyntaxException( |
||
267 | I18N.Cant_recognize_the_second_operand_of_EQ_operator(), |
||
268 | lexer, |
||
269 | tip |
||
270 | ); |
||
271 | 43983 | jjdelcerro | } |
272 | 43512 | jjdelcerro | op1 = codeBuilder.eq(op1, op2); |
273 | break;
|
||
274 | 43521 | jjdelcerro | case Token.OP_NE:
|
275 | 43512 | jjdelcerro | lexer.next(); |
276 | 43521 | jjdelcerro | op2 = parse_sum(); |
277 | 43983 | jjdelcerro | if( op2==null ) { |
278 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_NEQ_operator(),lexer); |
279 | 43983 | jjdelcerro | } |
280 | 43521 | jjdelcerro | op1 = codeBuilder.ne(op1, op2); |
281 | break;
|
||
282 | case Token.PRED_IS: {
|
||
283 | lexer.next(); |
||
284 | Token next = lexer.look(); |
||
285 | 44361 | jjdelcerro | switch(next.getType()) {
|
286 | case Token.NOTNULL:
|
||
287 | lexer.next(); |
||
288 | op1 = codeBuilder.is(op1, codeBuilder.constant(null));
|
||
289 | op1 = codeBuilder.not(op1); |
||
290 | break;
|
||
291 | case Token.OP_NOT:
|
||
292 | lexer.next(); |
||
293 | next = lexer.look(); |
||
294 | if( next.getType() == Token.NULL ) {
|
||
295 | lexer.next(); |
||
296 | op1 = codeBuilder.is(op1, codeBuilder.constant(null));
|
||
297 | } else {
|
||
298 | op2 = parse_sum(); |
||
299 | if( op2==null ) { |
||
300 | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_IS_operator(),lexer); |
||
301 | } |
||
302 | op1 = codeBuilder.is(op1, op2); |
||
303 | } |
||
304 | op1 = codeBuilder.not(op1); |
||
305 | break;
|
||
306 | case Token.NULL:
|
||
307 | lexer.next(); |
||
308 | op1 = codeBuilder.is(op1, codeBuilder.constant(null));
|
||
309 | break;
|
||
310 | default:
|
||
311 | op2 = parse_sum(); |
||
312 | if( op2==null ) { |
||
313 | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_IS_operator(),lexer); |
||
314 | } |
||
315 | op1 = codeBuilder.is(op1, op2); |
||
316 | 43521 | jjdelcerro | } |
317 | 43512 | jjdelcerro | } |
318 | 43521 | jjdelcerro | break;
|
319 | 43512 | jjdelcerro | case Token.ISNULL:
|
320 | lexer.next(); |
||
321 | op1 = codeBuilder.is(op1, codeBuilder.constant(null));
|
||
322 | break;
|
||
323 | 43532 | jjdelcerro | case Token.OP_REGEXP:
|
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_REGEXP_operator(),lexer); |
328 | 43983 | jjdelcerro | } |
329 | 43532 | jjdelcerro | op1 = codeBuilder.regexp(op1, op2); |
330 | break;
|
||
331 | 43512 | jjdelcerro | case Token.PRED_LIKE:
|
332 | lexer.next(); |
||
333 | op2 = parse_sum(); |
||
334 | 43983 | jjdelcerro | if( op2==null ) { |
335 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_LIKE_operator(),lexer); |
336 | 43983 | jjdelcerro | } |
337 | 43512 | jjdelcerro | op1 = codeBuilder.like(op1, op2); |
338 | break;
|
||
339 | case Token.PRED_ILIKE:
|
||
340 | lexer.next(); |
||
341 | op2 = parse_sum(); |
||
342 | 43983 | jjdelcerro | if( op2==null ) { |
343 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_ILIKE_operator(),lexer); |
344 | 43983 | jjdelcerro | } |
345 | 43512 | jjdelcerro | op1 = codeBuilder.ilike(op1, op2); |
346 | break;
|
||
347 | default:
|
||
348 | return op1;
|
||
349 | } |
||
350 | } |
||
351 | } |
||
352 | |||
353 | 44139 | jjdelcerro | public Code parse_sum() {
|
354 | 43512 | jjdelcerro | Code op1 = parse_factor(); |
355 | Code op2; |
||
356 | while( true ) { |
||
357 | Token token = lexer.look(); |
||
358 | switch( token.getType() ) {
|
||
359 | 44139 | jjdelcerro | case Token.OP_CONCAT:
|
360 | lexer.next(); |
||
361 | op2 = parse_factor(); |
||
362 | op1 = codeBuilder.concat(op1, op2); |
||
363 | break;
|
||
364 | 43512 | jjdelcerro | case Token.OP_ADD:
|
365 | lexer.next(); |
||
366 | op2 = parse_factor(); |
||
367 | op1 = codeBuilder.add(op1, op2); |
||
368 | break;
|
||
369 | case Token.OP_SUBST:
|
||
370 | lexer.next(); |
||
371 | op2 = parse_factor(); |
||
372 | op1 = codeBuilder.subst(op1, op2); |
||
373 | break;
|
||
374 | default:
|
||
375 | return op1;
|
||
376 | } |
||
377 | } |
||
378 | } |
||
379 | |||
380 | 44139 | jjdelcerro | public Code parse_factor() {
|
381 | 43939 | jjdelcerro | Code op1 = parse_getattr(); |
382 | 43512 | jjdelcerro | Code op2; |
383 | while( true ) { |
||
384 | Token token = lexer.look(); |
||
385 | switch( token.getType() ) {
|
||
386 | case Token.OP_MULT:
|
||
387 | lexer.next(); |
||
388 | 43939 | jjdelcerro | op2 = parse_getattr(); |
389 | 43983 | jjdelcerro | if( op2==null ) { |
390 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_MULT_operator(),lexer); |
391 | 43983 | jjdelcerro | } |
392 | 43512 | jjdelcerro | op1 = codeBuilder.mult(op1, op2); |
393 | break;
|
||
394 | case Token.OP_DIV:
|
||
395 | lexer.next(); |
||
396 | 43939 | jjdelcerro | op2 = parse_getattr(); |
397 | 43983 | jjdelcerro | if( op2==null ) { |
398 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_DIV_operator(),lexer); |
399 | 43983 | jjdelcerro | } |
400 | 43512 | jjdelcerro | op1 = codeBuilder.div(op1, op2); |
401 | break;
|
||
402 | case Token.OP_MOD:
|
||
403 | lexer.next(); |
||
404 | 43939 | jjdelcerro | op2 = parse_getattr(); |
405 | 43983 | jjdelcerro | if( op2==null ) { |
406 | 44098 | jjdelcerro | throw new ExpressionSyntaxException(I18N.Cant_recognize_the_second_operand_of_MOD_operator(),lexer); |
407 | 43983 | jjdelcerro | } |
408 | 43512 | jjdelcerro | op1 = codeBuilder.mod(op1, op2); |
409 | break;
|
||
410 | 44139 | jjdelcerro | case Token.OPEN_BRACKET:
|
411 | lexer.next(); |
||
412 | Code codeIndex = parse_expression(); |
||
413 | if( codeIndex == null ) { |
||
414 | throw new ExpressionSyntaxException(I18N.unexpected_end_of_source(),lexer); |
||
415 | } |
||
416 | token = lexer.look(); |
||
417 | if( token.getType()!=Token.CLOSED_BRACKET) {
|
||
418 | throw new ExpressionSyntaxException(I18N.A_XTokenX_was_expected_and_XliteralX_was_found("]", token.getLiteral()),lexer); |
||
419 | } |
||
420 | lexer.next(); |
||
421 | Code code = codeBuilder.getitem(op1, codeIndex); |
||
422 | return code;
|
||
423 | 43512 | jjdelcerro | default:
|
424 | return op1;
|
||
425 | } |
||
426 | } |
||
427 | } |
||
428 | |||
429 | 44139 | jjdelcerro | public Code parse_getattr() {
|
430 | 43939 | jjdelcerro | Code op1 = parse_termino(); |
431 | if( !isObjectAccessSupported() ) {
|
||
432 | return op1;
|
||
433 | } |
||
434 | while( true ) { |
||
435 | Token next = lexer.look(); |
||
436 | switch( next.getType() ) {
|
||
437 | case Token.OP_GETATTR:
|
||
438 | lexer.next(); |
||
439 | next = lexer.look(); |
||
440 | if( next.getType()!=Token.IDENTIFIER ) {
|
||
441 | 43983 | jjdelcerro | throw new ExpressionSyntaxException( |
442 | 44098 | jjdelcerro | I18N.An_attribute_identifier_was_expected_and_XliteralX_was_found(next.getLiteral()), |
443 | lexer |
||
444 | 43983 | jjdelcerro | ); |
445 | 43939 | jjdelcerro | } |
446 | String id = (String) next.getLiteral(); |
||
447 | lexer.next(); |
||
448 | next = lexer.look(); |
||
449 | if( next.getType() == Token.PARENTHESIS_OPEN ) {
|
||
450 | lexer.next(); |
||
451 | 44139 | jjdelcerro | Codes args = parse_expressions(",");
|
452 | 43939 | jjdelcerro | next = lexer.next(); |
453 | if( next.getType() != Token.PARENTHESIS_CLOSE ) {
|
||
454 | 43983 | jjdelcerro | throw new ExpressionSyntaxException( |
455 | 44098 | jjdelcerro | I18N.Closing_parenthesis_was_expected_and_XliteralX_was_found(next.getLiteral()), |
456 | lexer |
||
457 | 43983 | jjdelcerro | ); |
458 | 43939 | jjdelcerro | } |
459 | 44379 | jjdelcerro | op1 = codeBuilder.method(op1, id, args); |
460 | 43939 | jjdelcerro | } else {
|
461 | 44379 | jjdelcerro | op1 = codeBuilder.getattr(op1, id); |
462 | 43939 | jjdelcerro | } |
463 | 44379 | jjdelcerro | break;
|
464 | 43939 | jjdelcerro | default:
|
465 | return op1;
|
||
466 | } |
||
467 | } |
||
468 | } |
||
469 | |||
470 | 44139 | jjdelcerro | public Code parse_termino() {
|
471 | 43512 | jjdelcerro | |
472 | Token token = lexer.look(); |
||
473 | switch( token.getType() ) {
|
||
474 | case Token.PARENTHESIS_OPEN: {
|
||
475 | 43521 | jjdelcerro | lexer.next(); |
476 | 44139 | jjdelcerro | Code value = parse_expression(); |
477 | 43521 | jjdelcerro | Token next = lexer.next(); |
478 | 44098 | jjdelcerro | switch(next.getType()) {
|
479 | case Token.PARENTHESIS_CLOSE:
|
||
480 | break;
|
||
481 | case Token.EOF:
|
||
482 | throw new ExpressionSyntaxException( |
||
483 | I18N.Closing_parenthesis_was_expected_and_end_of_source_was_found(), |
||
484 | lexer |
||
485 | ); |
||
486 | default:
|
||
487 | throw new ExpressionSyntaxException( |
||
488 | I18N.Closing_parenthesis_was_expected_and_XliteralX_was_found(next.getLiteral()), |
||
489 | lexer |
||
490 | ); |
||
491 | 43521 | jjdelcerro | } |
492 | return value;
|
||
493 | 43512 | jjdelcerro | } |
494 | case Token.IDENTIFIER: {
|
||
495 | 44139 | jjdelcerro | Code code = parse_grammars(); |
496 | if( code!=null ) { |
||
497 | return code;
|
||
498 | } |
||
499 | if( this.grammars.isReservedWord(token.getLiteral()) ) { |
||
500 | return null; |
||
501 | } |
||
502 | 43512 | jjdelcerro | lexer.next(); |
503 | 43521 | jjdelcerro | String id = (String) token.getLiteral(); |
504 | Token next = lexer.look(); |
||
505 | if( next.getType() == Token.PARENTHESIS_OPEN ) {
|
||
506 | lexer.next(); |
||
507 | 44139 | jjdelcerro | Codes args = parse_expressions(",");
|
508 | 43521 | jjdelcerro | next = lexer.next(); |
509 | 44098 | jjdelcerro | switch(next.getType()) {
|
510 | case Token.PARENTHESIS_CLOSE:
|
||
511 | break;
|
||
512 | case Token.EOF:
|
||
513 | throw new ExpressionSyntaxException( |
||
514 | I18N.Closing_parenthesis_was_expected_and_end_of_source_was_found(), |
||
515 | lexer |
||
516 | ); |
||
517 | default:
|
||
518 | throw new ExpressionSyntaxException( |
||
519 | I18N.Closing_parenthesis_was_expected_and_XliteralX_was_found(next.getLiteral()), |
||
520 | lexer |
||
521 | ); |
||
522 | 43521 | jjdelcerro | } |
523 | return codeBuilder.function(id, args);
|
||
524 | } else {
|
||
525 | 44379 | jjdelcerro | if( StringUtils.equalsIgnoreCase(id, "TRUE") ) { |
526 | return codeBuilder.constant(true); |
||
527 | } |
||
528 | if( StringUtils.equalsIgnoreCase(id, "FALSE") ) { |
||
529 | return codeBuilder.constant(false); |
||
530 | } |
||
531 | 43521 | jjdelcerro | return codeBuilder.identifier(id);
|
532 | 43512 | jjdelcerro | } |
533 | } |
||
534 | case Token.STRING_LITERAL:
|
||
535 | lexer.next(); |
||
536 | return codeBuilder.constant(token.getValue());
|
||
537 | case Token.INTEGER_LITERAL:
|
||
538 | lexer.next(); |
||
539 | return codeBuilder.constant(token.getValue());
|
||
540 | case Token.FLOATING_POINT_LITERAL:
|
||
541 | lexer.next(); |
||
542 | return codeBuilder.constant(token.getValue());
|
||
543 | case Token.NULL:
|
||
544 | lexer.next(); |
||
545 | return codeBuilder.constant(null); |
||
546 | case Token.TRUE:
|
||
547 | lexer.next(); |
||
548 | return codeBuilder.constant(true); |
||
549 | case Token.FALSE:
|
||
550 | lexer.next(); |
||
551 | return codeBuilder.constant(false); |
||
552 | 44098 | jjdelcerro | case Token.OP_SUBST:
|
553 | lexer.next(); |
||
554 | Code code = parse_termino(); |
||
555 | 44211 | jjdelcerro | if( code.code()==Code.CONSTANT ) {
|
556 | BaseConstant c = (BaseConstant)code; |
||
557 | if( c.value() instanceof Number ) { |
||
558 | c.value(NegOperator.negate((Number) c.value()));
|
||
559 | return code;
|
||
560 | } |
||
561 | 44212 | jjdelcerro | throw new ExpressionSyntaxException(I18N.A_numeric_constant_was_expected_after_the_unary_operator_minus(),lexer); |
562 | 44211 | jjdelcerro | } |
563 | 44098 | jjdelcerro | return codeBuilder.negate(code);
|
564 | case Token.EOF:
|
||
565 | throw new ExpressionSyntaxException(I18N.unexpected_end_of_source(),lexer); |
||
566 | 44139 | jjdelcerro | default:
|
567 | return parse_grammars();
|
||
568 | 43512 | jjdelcerro | } |
569 | } |
||
570 | |||
571 | 44139 | jjdelcerro | public Codes parse_expressions(String sep) { |
572 | BaseCodes codes = null;
|
||
573 | 43512 | jjdelcerro | while( true ) { |
574 | 44139 | jjdelcerro | Code code = parse_expression(); |
575 | if( code!=null ) { |
||
576 | if( codes == null ) { |
||
577 | codes = (BaseCodes) codeBuilder.args(); |
||
578 | 43519 | jjdelcerro | } |
579 | 44139 | jjdelcerro | codes.add(code); |
580 | 43519 | jjdelcerro | } |
581 | 43512 | jjdelcerro | Token next = lexer.look(); |
582 | 44139 | jjdelcerro | String literal = next.getLiteral();
|
583 | if( literal == null ) { |
||
584 | return codes;
|
||
585 | } |
||
586 | literal = literal.trim(); |
||
587 | if( sep.equals(literal) ) {
|
||
588 | 43512 | jjdelcerro | lexer.next(); // Consume el ",".
|
589 | 44139 | jjdelcerro | } else {
|
590 | return codes;
|
||
591 | 43512 | jjdelcerro | } |
592 | } |
||
593 | } |
||
594 | 44139 | jjdelcerro | |
595 | private Code parse_grammars() {
|
||
596 | StatementContext context = new DefaultStatementContext();
|
||
597 | 44379 | jjdelcerro | Code code; |
598 | BaseCodes args = (BaseCodes) this.codeBuilder.args();
|
||
599 | 44139 | jjdelcerro | Statement stmt = this.grammars.getApplicableStatement(context); |
600 | 44379 | jjdelcerro | while( stmt!=null ) { |
601 | code = stmt.parse(context); |
||
602 | args.add(code); |
||
603 | stmt = this.grammars.getApplicableStatement(context);
|
||
604 | 44139 | jjdelcerro | } |
605 | 44379 | jjdelcerro | switch(args.size()) {
|
606 | case 0 : |
||
607 | code = null;
|
||
608 | break;
|
||
609 | case 1 : |
||
610 | code = args.get(0);
|
||
611 | break;
|
||
612 | default:
|
||
613 | code = this.codeBuilder.function(CodeBlockFunction.NAME, args);
|
||
614 | break;
|
||
615 | } |
||
616 | return code;
|
||
617 | 44139 | jjdelcerro | } |
618 | 43512 | jjdelcerro | } |