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