Revision 44738 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/DefaultStatement.java
DefaultStatement.java | ||
---|---|---|
5 | 5 |
import java.util.Objects; |
6 | 6 |
import org.apache.commons.lang3.ArrayUtils; |
7 | 7 |
import org.apache.commons.lang3.StringUtils; |
8 |
import org.apache.commons.lang3.tuple.ImmutablePair; |
|
9 |
import org.apache.commons.lang3.tuple.Pair; |
|
8 | 10 |
import org.gvsig.expressionevaluator.Code; |
9 | 11 |
import org.gvsig.expressionevaluator.Code.Caller; |
10 | 12 |
import org.gvsig.expressionevaluator.Codes; |
... | ... | |
18 | 20 |
import org.gvsig.expressionevaluator.Statement.StatementContext; |
19 | 21 |
import org.gvsig.expressionevaluator.impl.function.programming.CodeBlockFunction; |
20 | 22 |
import org.gvsig.expressionevaluator.impl.DefaultCodeBuilder.BaseCodes; |
23 |
import org.gvsig.expressionevaluator.spi.AbstractLexicalAnalyzer; |
|
21 | 24 |
|
22 | 25 |
/** |
23 | 26 |
* |
... | ... | |
31 | 34 |
// private String codeId; |
32 | 35 |
// private ArgsBuilder argsBuilder; |
33 | 36 |
|
37 |
public interface IsApplicableRule extends Rule { |
|
38 |
public boolean isApplicable(StatementContext context); |
|
39 |
} |
|
40 |
|
|
34 | 41 |
public interface RepeatRule extends CompoundRule { |
35 | 42 |
|
36 | 43 |
public String getClassifier(); |
37 | 44 |
} |
38 | 45 |
|
39 |
public class RuleRequireAnyToken implements Rule { |
|
46 |
public class RuleRequireAnyToken implements IsApplicableRule {
|
|
40 | 47 |
|
41 | 48 |
private final String[] required_token; |
42 | 49 |
|
... | ... | |
46 | 53 |
|
47 | 54 |
@Override |
48 | 55 |
public void parse(StatementContext context) { |
56 |
context.trace(this.toString()+".parse"); |
|
49 | 57 |
Token token = context.look_token(); |
50 | 58 |
if (!token.is(this.required_token)) { |
51 | 59 |
throw new ExpressionSyntaxException( |
... | ... | |
59 | 67 |
context.next_token(); |
60 | 68 |
} |
61 | 69 |
|
62 |
private boolean isApplicable(StatementContext context) { |
|
63 |
Token token = context.look_token(); |
|
64 |
return token.is(this.required_token); |
|
70 |
@Override |
|
71 |
public boolean isApplicable(StatementContext context) { |
|
72 |
Token token = context.next_token(); |
|
73 |
boolean r = token.is(this.required_token); |
|
74 |
context.trace(this.toString()+".isApplicable return "+r); |
|
75 |
return r; |
|
65 | 76 |
} |
66 | 77 |
|
67 | 78 |
@Override |
... | ... | |
71 | 82 |
|
72 | 83 |
} |
73 | 84 |
|
74 |
public class RuleRequireIdentifier implements Rule { |
|
85 |
public class RuleRequireIdentifier implements IsApplicableRule {
|
|
75 | 86 |
|
76 | 87 |
private final String id; |
77 | 88 |
|
... | ... | |
81 | 92 |
|
82 | 93 |
@Override |
83 | 94 |
public void parse(StatementContext context) { |
95 |
context.trace(this.toString()+".parse"); |
|
84 | 96 |
Token token = context.look_token(); |
85 | 97 |
if (token.getType() != Token.IDENTIFIER) { |
86 | 98 |
throw new ExpressionSyntaxException( |
... | ... | |
95 | 107 |
} |
96 | 108 |
|
97 | 109 |
@Override |
110 |
public boolean isApplicable(StatementContext context) { |
|
111 |
Token token = context.next_token(); |
|
112 |
boolean r = token.getType() == Token.IDENTIFIER; |
|
113 |
context.trace(this.toString()+".isApplicable return "+r); |
|
114 |
return r; |
|
115 |
} |
|
116 |
|
|
117 |
@Override |
|
98 | 118 |
public String toString() { |
99 | 119 |
return "require_identifier('" + this.id + "')"; |
100 | 120 |
} |
... | ... | |
110 | 130 |
|
111 | 131 |
@Override |
112 | 132 |
public void parse(StatementContext context) { |
133 |
context.trace(this.toString()+".parse"); |
|
113 | 134 |
Token token = context.look_token(); |
114 | 135 |
if (token.getType() != Token.STRING_LITERAL) { |
115 | 136 |
throw new ExpressionSyntaxException( |
... | ... | |
139 | 160 |
|
140 | 161 |
@Override |
141 | 162 |
public void parse(StatementContext context) { |
163 |
context.trace(this.toString()+".parse"); |
|
142 | 164 |
Code code = context.parse_expression(); |
143 | 165 |
if (code == null) { |
144 | 166 |
throw new ExpressionSyntaxException(context.getLexicalAnalyzer()); |
... | ... | |
165 | 187 |
|
166 | 188 |
@Override |
167 | 189 |
public void parse(StatementContext context) { |
190 |
context.trace(this.toString()+".parse"); |
|
168 | 191 |
if( this.value instanceof Code ) { |
169 | 192 |
context.setCode(id, (Code) this.value); |
170 | 193 |
} else { |
... | ... | |
190 | 213 |
|
191 | 214 |
@Override |
192 | 215 |
public void parse(StatementContext context) { |
216 |
context.trace(this.toString()+".parse"); |
|
193 | 217 |
Codes codes = context.parse_expressions(this.separator); |
194 | 218 |
if (codes == null) { |
195 | 219 |
throw new ExpressionSyntaxException(context.getLexicalAnalyzer()); |
... | ... | |
259 | 283 |
|
260 | 284 |
@Override |
261 | 285 |
public void parse(StatementContext context) { |
286 |
context.trace(this.toString()+".parse"); |
|
262 | 287 |
Token token = context.look_token(); |
263 | 288 |
if (token.is(this.optional_token)) { |
264 | 289 |
context.next_token(); |
... | ... | |
286 | 311 |
|
287 | 312 |
@Override |
288 | 313 |
public String toString() { |
289 |
return "optional_token(" + StringUtils.join(this.optional_token) + ") rules:" + StringUtils.join(onTrueRules, ",");
|
|
314 |
return "optional_token(" + StringUtils.join(this.optional_token) + ") onTrue:" + StringUtils.join(onTrueRules, ",")+", onFalse:" + StringUtils.join(onFalseRules, ",");
|
|
290 | 315 |
} |
291 | 316 |
} |
292 | 317 |
|
318 |
public class RuleSwitchToken implements SwichTokenRule { |
|
319 |
|
|
320 |
private final List<Pair<String,Rule[]>> caseRules; |
|
321 |
private Rule[] defaultRule; |
|
322 |
|
|
323 |
public RuleSwitchToken() { |
|
324 |
this.caseRules = new ArrayList<>(); |
|
325 |
} |
|
326 |
|
|
327 |
@Override |
|
328 |
public void parse(StatementContext context) { |
|
329 |
context.trace(this.toString()+".parse"); |
|
330 |
Token token = context.look_token(); |
|
331 |
for (Pair<String, Rule[]> caseRule : caseRules) { |
|
332 |
if( token.is(caseRule.getKey()) ) { |
|
333 |
context.next_token(); |
|
334 |
for (Rule rule : caseRule.getValue()) { |
|
335 |
rule.parse(context); |
|
336 |
} |
|
337 |
return; |
|
338 |
} |
|
339 |
} |
|
340 |
if( defaultRule!=null ) { |
|
341 |
for (Rule rule : defaultRule) { |
|
342 |
rule.parse(context); |
|
343 |
} |
|
344 |
} |
|
345 |
} |
|
346 |
|
|
347 |
@Override |
|
348 |
public SwichTokenRule addCase(String token, Rule... rules) { |
|
349 |
this.caseRules.add(new ImmutablePair(token,rules)); |
|
350 |
return this; |
|
351 |
} |
|
352 |
|
|
353 |
@Override |
|
354 |
public SwichTokenRule addDefault(Rule... rules) { |
|
355 |
this.defaultRule = rules; |
|
356 |
return this; |
|
357 |
} |
|
358 |
|
|
359 |
@Override |
|
360 |
public String toString() { |
|
361 |
return "switch_token() rules:" + StringUtils.join(this.caseRules,",") + " default: " + defaultRule; |
|
362 |
} |
|
363 |
} |
|
364 |
|
|
293 | 365 |
public class RuleRepeatUntilAnyTokens implements RepeatRule { |
294 | 366 |
|
295 | 367 |
private final String[] exit_tokens; |
... | ... | |
303 | 375 |
|
304 | 376 |
@Override |
305 | 377 |
public void parse(StatementContext context) { |
378 |
context.trace(this.toString()+".parse"); |
|
306 | 379 |
String save = context.getCodeClassifier(); |
307 | 380 |
try { |
308 | 381 |
this.counter = 1; |
... | ... | |
340 | 413 |
} |
341 | 414 |
} |
342 | 415 |
|
416 |
public class RuleRepeat implements RepeatRule { |
|
417 |
|
|
418 |
private final List<Rule> rules; |
|
419 |
private int counter; |
|
420 |
|
|
421 |
public RuleRepeat() { |
|
422 |
this.rules = new ArrayList<>(); |
|
423 |
} |
|
424 |
|
|
425 |
@Override |
|
426 |
public void parse(StatementContext context) { |
|
427 |
context.trace(this.toString()+".parse"); |
|
428 |
String save = context.getCodeClassifier(); |
|
429 |
try { |
|
430 |
this.counter = 1; |
|
431 |
boolean breakloop = false; |
|
432 |
while (!breakloop) { |
|
433 |
context.setCodeClassifier(String.valueOf(counter).trim()); |
|
434 |
for (Rule rule : rules) { |
|
435 |
try { |
|
436 |
rule.parse(context); |
|
437 |
} catch(BreakLoopException ex) { |
|
438 |
breakloop = true; |
|
439 |
break; |
|
440 |
} |
|
441 |
} |
|
442 |
this.counter = this.counter + 1; |
|
443 |
} |
|
444 |
} finally { |
|
445 |
context.setCodeClassifier(save); |
|
446 |
} |
|
447 |
} |
|
448 |
|
|
449 |
@Override |
|
450 |
public RuleRepeat addRule(Rule rule) { |
|
451 |
this.rules.add(rule); |
|
452 |
return this; |
|
453 |
} |
|
454 |
|
|
455 |
@Override |
|
456 |
public String getClassifier() { |
|
457 |
String s = String.valueOf(counter).trim(); |
|
458 |
return s; |
|
459 |
} |
|
460 |
|
|
461 |
@Override |
|
462 |
public String toString() { |
|
463 |
return "repeat() rules:" + StringUtils.join(rules, ","); |
|
464 |
} |
|
465 |
} |
|
466 |
|
|
467 |
public static class BreakLoopException extends RuntimeException { |
|
468 |
|
|
469 |
} |
|
470 |
|
|
471 |
public static class RuleBreakLoop implements Rule { |
|
472 |
|
|
473 |
public RuleBreakLoop() { |
|
474 |
} |
|
475 |
|
|
476 |
@Override |
|
477 |
public void parse(StatementContext context) { |
|
478 |
context.trace(this.toString()+".parse"); |
|
479 |
throw new BreakLoopException(); |
|
480 |
} |
|
481 |
|
|
482 |
@Override |
|
483 |
public String toString() { |
|
484 |
return "break_loop()"; |
|
485 |
} |
|
486 |
} |
|
487 |
|
|
343 | 488 |
public class RuleOptionalIdentifiers extends AbstractConditionalRule implements ConditionalRule { |
344 | 489 |
|
345 | 490 |
private final String id; |
... | ... | |
353 | 498 |
|
354 | 499 |
@Override |
355 | 500 |
public void parse(StatementContext context) { |
501 |
context.trace(this.toString()+".parse"); |
|
356 | 502 |
BaseCodes args = (BaseCodes) context.getCodeBuilder().args(); |
357 | 503 |
Token token = context.look_token(); |
358 | 504 |
while (token.getType() == Token.IDENTIFIER) { |
... | ... | |
396 | 542 |
|
397 | 543 |
@Override |
398 | 544 |
public void parse(StatementContext context) { |
545 |
context.trace(this.toString()+".parse"); |
|
399 | 546 |
Token token = context.look_token(); |
400 | 547 |
if (token.getType() == Token.STRING_LITERAL) { |
401 | 548 |
String s = (String) token.getValue(); |
... | ... | |
416 | 563 |
|
417 | 564 |
public static class ArgsBuilderFromNames implements ArgsBuilder { |
418 | 565 |
|
419 |
private final String[] argNames;
|
|
566 |
protected final String[] argNames;
|
|
420 | 567 |
|
421 | 568 |
public ArgsBuilderFromNames(String... argNames) { |
422 | 569 |
this.argNames = argNames; |
423 | 570 |
} |
424 | 571 |
|
425 | 572 |
@Override |
573 |
public String toString() { |
|
574 |
return "args_names("+StringUtils.join(argNames,",")+")"; |
|
575 |
} |
|
576 |
|
|
577 |
@Override |
|
426 | 578 |
public Codes build(StatementContext context) { |
579 |
context.trace(this.toString()+".build"); |
|
427 | 580 |
BaseCodes args = (BaseCodes) context.getCodeBuilder().args(); |
428 | 581 |
for (String argName : argNames) { |
429 | 582 |
if (argName.contains("#")) { |
... | ... | |
434 | 587 |
if (code == null) { |
435 | 588 |
break; |
436 | 589 |
} |
437 |
args.add(code); |
|
590 |
args.add(argNameX, code);
|
|
438 | 591 |
n++; |
439 | 592 |
} |
440 | 593 |
} else { |
... | ... | |
442 | 595 |
// if( code == null) { |
443 | 596 |
// code = context.getCodeBuilder().constant(null); |
444 | 597 |
// } |
445 |
args.add(code); |
|
598 |
args.add(argName,code);
|
|
446 | 599 |
} |
447 | 600 |
} |
448 | 601 |
return args; |
... | ... | |
456 | 609 |
} |
457 | 610 |
|
458 | 611 |
@Override |
612 |
public String toString() { |
|
613 |
return "args_expand("+StringUtils.join(argNames,",")+")"; |
|
614 |
} |
|
615 |
|
|
616 |
@Override |
|
459 | 617 |
public Codes build(StatementContext context) { |
460 | 618 |
BaseCodes args = (BaseCodes) context.getCodeBuilder().args(); |
461 | 619 |
|
... | ... | |
595 | 753 |
if (this.rules.isEmpty()) { |
596 | 754 |
return false; |
597 | 755 |
} |
598 |
Rule rule = this.rules.get(0); |
|
599 |
if (!(rule instanceof RuleRequireAnyToken)) { |
|
600 |
return false; |
|
756 |
context.trace(this.getName()+".isApplicable"); |
|
757 |
AbstractLexicalAnalyzer lexer = (AbstractLexicalAnalyzer) context.getLexicalAnalyzer(); |
|
758 |
lexer.push_state(); |
|
759 |
try { |
|
760 |
boolean applicable = false; |
|
761 |
for (Rule rule : rules) { |
|
762 |
if (!(rule instanceof IsApplicableRule)) { |
|
763 |
break; |
|
764 |
} |
|
765 |
if( !((IsApplicableRule) rule).isApplicable(context) ) { |
|
766 |
return false; |
|
767 |
} |
|
768 |
applicable = true; |
|
769 |
} |
|
770 |
context.trace(this.getName()+".isApplicable return "+applicable); |
|
771 |
return applicable; |
|
772 |
} finally { |
|
773 |
lexer.pop_state(); |
|
601 | 774 |
} |
602 |
return ((RuleRequireAnyToken) rule).isApplicable(context); |
|
603 | 775 |
} |
604 | 776 |
|
605 | 777 |
@Override |
... | ... | |
619 | 791 |
this.builder(new StatementBuilderBase(id, argsBuilder)); |
620 | 792 |
} |
621 | 793 |
|
794 |
@Override |
|
622 | 795 |
public void builder(StatementBuilder builder) { |
623 | 796 |
this.stmtBuilder = builder; |
624 | 797 |
} |
625 | 798 |
|
626 | 799 |
@Override |
627 | 800 |
public Code parse(StatementContext context) { |
628 |
// System.err.println("start parse "+this.getName());
|
|
801 |
context.trace(this.getName()+".parse");
|
|
629 | 802 |
for (Rule rule : rules) { |
630 | 803 |
rule.parse(context); |
631 | 804 |
} |
632 | 805 |
Code code = this.stmtBuilder.build(context); |
806 |
context.trace(this.getName()+".return "+code); |
|
633 | 807 |
return code; |
634 | 808 |
} |
635 | 809 |
|
... | ... | |
638 | 812 |
return this.getName() + " " + StringUtils.join(this.rules, ";"); |
639 | 813 |
|
640 | 814 |
} |
815 |
|
|
816 |
@Override |
|
817 |
public CompoundRule repeat() { |
|
818 |
return new RuleRepeat(); |
|
819 |
} |
|
820 |
|
|
821 |
@Override |
|
822 |
public Rule break_loop() { |
|
823 |
return new RuleBreakLoop(); |
|
824 |
} |
|
825 |
|
|
826 |
@Override |
|
827 |
public SwichTokenRule switch_token() { |
|
828 |
return new RuleSwitchToken(); |
|
829 |
} |
|
830 |
|
|
641 | 831 |
} |
Also available in: Unified diff