Revision 44750 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

View differences:

DefaultStatement.java
9 9
import org.apache.commons.lang3.tuple.Pair;
10 10
import org.gvsig.expressionevaluator.Code;
11 11
import org.gvsig.expressionevaluator.Code.Caller;
12
import org.gvsig.expressionevaluator.CodeBuilder;
12 13
import org.gvsig.expressionevaluator.Codes;
13 14
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_LIST;
14 15
import org.gvsig.expressionevaluator.ExpressionSyntaxException;
......
20 21
import org.gvsig.expressionevaluator.Statement.StatementContext;
21 22
import org.gvsig.expressionevaluator.impl.function.programming.CodeBlockFunction;
22 23
import org.gvsig.expressionevaluator.impl.DefaultCodeBuilder.BaseCodes;
23
import org.gvsig.expressionevaluator.spi.AbstractLexicalAnalyzer;
24 24

  
25 25
/**
26 26
 *
......
46 46
    public class RuleRequireAnyToken implements IsApplicableRule {
47 47

  
48 48
        private final String[] required_token;
49
        private String id;
49 50

  
50 51
        public RuleRequireAnyToken(String... required_token) {
51 52
            this.required_token = required_token;
52 53
        }
54
        
55
        @Override
56
        public RuleRequireAnyToken capture_as(String... ids) {
57
          this.id = ids[0];
58
          return this;
59
        }
53 60

  
54 61
        @Override
55 62
        public void parse(StatementContext context) {
......
64 71
                        context.getLexicalAnalyzer()
65 72
                );
66 73
            }
74
            if( this.id != null ) {
75
              Code code = context.getCodeBuilder().constant(token.getValue());
76
              context.setCode(id, code);
77
            }
67 78
            context.next_token();
68 79
        }
69 80

  
......
84 95

  
85 96
    public class RuleRequireIdentifier implements IsApplicableRule {
86 97

  
87
        private final String id;
98
        private String id;
88 99

  
89
        public RuleRequireIdentifier(String id) {
90
            this.id = id;
100
        public RuleRequireIdentifier() {
91 101
        }
92 102

  
93 103
        @Override
104
        public Rule capture_as(String... ids) {
105
          this.id = ids[0];
106
          return this;
107
        }
108

  
109
        @Override
94 110
        public void parse(StatementContext context) {
95 111
            context.trace(this.toString()+".parse");
96 112
            Token token = context.look_token();
......
100 116
                        context.getLexicalAnalyzer()
101 117
                );
102 118
            }
103
            String identifier = (String) token.getLiteral();
104
            Code code = context.getCodeBuilder().constant(identifier);
105
            context.setCode(id, code);
119
            if( this.id!=null ) {
120
              String identifier = (String) token.getLiteral();
121
              Code code = context.getCodeBuilder().constant(identifier);
122
              context.setCode(id, code);
123
            }
106 124
            context.next_token();
107 125
        }
108 126

  
......
122 140

  
123 141
    public class RuleRequireLiteralString implements Rule {
124 142

  
125
        private final String id;
143
        private String id;
126 144

  
127
        public RuleRequireLiteralString(String id) {
128
            this.id = id;
145
        public RuleRequireLiteralString() {
129 146
        }
130 147

  
131 148
        @Override
149
        public Rule capture_as(String... ids) {
150
          this.id = ids[0];
151
          return this;
152
        }
153

  
154
        @Override
132 155
        public void parse(StatementContext context) {
133 156
            context.trace(this.toString()+".parse");
134 157
            Token token = context.look_token();
......
138 161
                        context.getLexicalAnalyzer()
139 162
                );
140 163
            }
141
            String identifier = (String) token.getValue();
142
            Code code = context.getCodeBuilder().constant(identifier);
143
            context.setCode(id, code);
144
            context.next_token();
164
            if( this.id!=null ) {
165
              String identifier = (String) token.getValue();
166
              Code code = context.getCodeBuilder().constant(identifier);
167
              context.setCode(id, code);
168
              context.next_token();
169
            }
145 170
        }
146 171

  
147 172
        @Override
......
152 177

  
153 178
    public class RuleRequireExpression implements Rule {
154 179

  
155
        private final String id;
180
        private String id;
156 181

  
157
        public RuleRequireExpression(String id) {
158
            this.id = id;
182
        public RuleRequireExpression() {
159 183
        }
160 184

  
161 185
        @Override
186
        public Rule capture_as(String... ids) {
187
          this.id = ids[0];
188
          return this;
189
        }
190

  
191
        @Override
162 192
        public void parse(StatementContext context) {
163 193
            context.trace(this.toString()+".parse");
164 194
            Code code = context.parse_expression();
165 195
            if (code == null) {
166 196
                throw new ExpressionSyntaxException(context.getLexicalAnalyzer());
167 197
            }
168
            context.setCode(id, code);
198
            if( this.id!=null ) {
199
              context.setCode(id, code);
200
            }
169 201
        }
170 202

  
171 203
        @Override
......
186 218
        }
187 219

  
188 220
        @Override
221
        public Rule capture_as(String... ids) {
222
          throw new UnsupportedOperationException("Unsupported operation.");
223
        }
224

  
225
        @Override
189 226
        public void parse(StatementContext context) {
190 227
            context.trace(this.toString()+".parse");
191 228
            if( this.value instanceof Code ) {
......
203 240

  
204 241
    public class RuleRequiereExpressions implements Rule {
205 242

  
206
        private final String id;
243
        private String id;
207 244
        private final String separator;
208 245

  
209
        public RuleRequiereExpressions(String id, String separator) {
210
            this.id = id;
246
        public RuleRequiereExpressions(String separator) {
211 247
            this.separator = separator;
212 248
        }
213 249

  
214 250
        @Override
251
        public Rule capture_as(String... ids) {
252
          this.id = ids[0];
253
          return this;
254
        }
255
        
256
        @Override
215 257
        public void parse(StatementContext context) {
216 258
            context.trace(this.toString()+".parse");
217 259
            Codes codes = context.parse_expressions(this.separator);
218 260
            if (codes == null) {
219 261
                throw new ExpressionSyntaxException(context.getLexicalAnalyzer());
220 262
            }
221
            Code code;
222
            if( codes.size()==1 ) {
223
                code = codes.get(0);
224
            } else {
225
                code = context.getCodeBuilder().function(CodeBlockFunction.NAME, codes);
263
            if( this.id!=null ) {
264
              Code code;
265
              if( codes.size()==1 ) {
266
                  code = codes.get(0);
267
              } else {
268
                  code = context.getCodeBuilder().function(CodeBlockFunction.NAME, codes);
269
              }
270
              context.setCode(id, code);
226 271
            }
227
            context.setCode(id, code);
228 272
        }
229 273

  
230 274
        @Override
......
243 287
            this.onFalseRules = new ArrayList<>();
244 288
        }
245 289

  
290
        @Override
291
        public ConditionalRule capture_as(String... ids) {
292
          throw new UnsupportedOperationException("Operation not suppted.");
293
        }
294

  
246 295
        protected void parseOnTrueRules(StatementContext context) {
247 296
            for (Rule rule : this.onTrueRules) {
248 297
                rule.parse(context);
......
274 323
        private final String[] optional_token;
275 324
        private final List<Rule> onTrueRules;
276 325
        private final List<Rule> onFalseRules;
326
        private String id;
277 327

  
278 328
        public RuleOptionalAnyToken(String... optional_token) {
279 329
            this.optional_token = optional_token;
......
282 332
        }
283 333

  
284 334
        @Override
335
        public ConditionalRule capture_as(String... ids) {
336
          this.id = ids[0];
337
          return this;
338
        }
339
        
340
        @Override
285 341
        public void parse(StatementContext context) {
286 342
            context.trace(this.toString()+".parse");
287 343
            Token token = context.look_token();
288 344
            if (token.is(this.optional_token)) {
345
                if( this.id!=null ) {
346
                  Code code = context.getCodeBuilder().constant(token.getValue());
347
                  context.setCode(id, code);
348
                }
289 349
                context.next_token();
290 350
                for (Rule rule : this.onTrueRules) {
291 351
                    rule.parse(context);
......
325 385
        }
326 386

  
327 387
        @Override
388
        public Rule capture_as(String... ids) {
389
          throw new UnsupportedOperationException("Unsupported operation.");
390
        }
391

  
392
        @Override
328 393
        public void parse(StatementContext context) {
329 394
            context.trace(this.toString()+".parse");
330 395
            Token token = context.look_token();
......
374 439
        }
375 440

  
376 441
        @Override
442
        public Rule capture_as(String... ids) {
443
          throw new UnsupportedOperationException("Operation not suppted.");
444
        }
445
        
446
        @Override
377 447
        public void parse(StatementContext context) {
378 448
            context.trace(this.toString()+".parse");
379 449
            String save = context.getCodeClassifier();
......
421 491
        public RuleRepeat() {
422 492
            this.rules = new ArrayList<>();
423 493
        }
424

  
494
        
425 495
        @Override
496
        public Rule capture_as(String... ids) {
497
          throw new UnsupportedOperationException("Operation not suppted.");
498
        }
499
        
500
        @Override
426 501
        public void parse(StatementContext context) {
427 502
            context.trace(this.toString()+".parse");
428 503
            String save = context.getCodeClassifier();
......
474 549
        }
475 550

  
476 551
        @Override
552
        public Rule capture_as(String... ids) {
553
          throw new UnsupportedOperationException("Operation not suppted.");
554
        }
555

  
556
        @Override
477 557
        public void parse(StatementContext context) {
478 558
          context.trace(this.toString()+".parse");
479 559
          throw new BreakLoopException();
......
485 565
        }
486 566
    }
487 567

  
568
        public static class RuleFail implements Rule {
569

  
570
        public RuleFail() {
571
        }
572

  
573
        @Override
574
        public Rule capture_as(String... ids) {
575
          throw new UnsupportedOperationException("Operation not suppted.");
576
        }
577

  
578
        @Override
579
        public void parse(StatementContext context) {
580
          context.trace(this.toString()+".parse");
581
          throw new ExpressionSyntaxException();
582
        }
583

  
584
        @Override
585
        public String toString() {
586
            return "fail()";
587
        }
588
    }
589

  
488 590
    public class RuleOptionalIdentifiers extends AbstractConditionalRule implements ConditionalRule {
489 591

  
490
        private final String id;
592
        private String id;
491 593
        private final String separator;
492 594

  
493
        public RuleOptionalIdentifiers(String id, String separator) {
595
        public RuleOptionalIdentifiers(String separator) {
494 596
            super();
495
            this.id = id;
496 597
            this.separator = separator;
497 598
        }
498 599

  
499 600
        @Override
601
        public ConditionalRule capture_as(String... ids) {
602
          this.id = ids[0];
603
          return this;
604
        }
605

  
606
        @Override
500 607
        public void parse(StatementContext context) {
501 608
            context.trace(this.toString()+".parse");
502 609
            BaseCodes args = (BaseCodes) context.getCodeBuilder().args();
......
517 624
                token = context.look_token();
518 625
            }
519 626
            if (args.size() != 0) {
627
              if( this.id!=null ) {
520 628
                Code code = context.getCodeBuilder().function(FUNCTION_LIST, args);
521 629
                context.setCode(id, code);
522
                this.parseOnTrueRules(context);
630
              }
631
              this.parseOnTrueRules(context);
523 632
            } else {
524 633
                this.parseOnFalseRules(context);
525 634
            }
......
533 642

  
534 643
    public class RuleRequireIdentifiers implements Rule {
535 644

  
536
        private final String id;
645
        private String id;
537 646
        private final String separator;
538 647

  
539
        public RuleRequireIdentifiers(String id, String separator) {
648
        public RuleRequireIdentifiers(String separator) {
540 649
            super();
541
            this.id = id;
542 650
            this.separator = separator;
543 651
        }
544 652

  
545 653
        @Override
654
        public Rule capture_as(String... ids) {
655
          this.id = ids[0];
656
          return this;
657
        }
658

  
659
        @Override
546 660
        public void parse(StatementContext context) {
547 661
            context.trace(this.toString()+".parse");
548 662
            BaseCodes args = (BaseCodes) context.getCodeBuilder().args();
......
568 682
                        context.getLexicalAnalyzer()
569 683
                );
570 684
            }
571
            Code code = context.getCodeBuilder().function(FUNCTION_LIST, args);
572
            context.setCode(id, code);
685
            if( this.id!=null ) {
686
              Code code = context.getCodeBuilder().function(FUNCTION_LIST, args);
687
              context.setCode(id, code);
688
            }
573 689
        }
574 690

  
575 691
        @Override
......
580 696

  
581 697
    public class RuleOptionalLiteralString extends AbstractConditionalRule implements ConditionalRule {
582 698

  
583
        private final String id;
699
        private String id;
584 700

  
585
        public RuleOptionalLiteralString(String id) {
701
        public RuleOptionalLiteralString() {
586 702
            super();
587
            this.id = id;
588 703
        }
589 704

  
590 705
        @Override
706
        public ConditionalRule capture_as(String... ids) {
707
          this.id = ids[0];
708
          return this;
709
        }
710
        
711
        @Override
591 712
        public void parse(StatementContext context) {
592 713
            context.trace(this.toString()+".parse");
593 714
            Token token = context.look_token();
594 715
            if (token.getType() == Token.STRING_LITERAL) {
595
                String s = (String) token.getValue();
596
                Code code = context.getCodeBuilder().constant(s);
597
                context.setCode(id, code);
598
                context.next_token();
716
                if( this.id!=null ) {
717
                  String s = (String) token.getValue();
718
                  Code code = context.getCodeBuilder().constant(s);
719
                  context.setCode(id, code);
720
                  context.next_token();
721
                }
599 722
                this.parseOnTrueRules(context);
600 723
            } else {
601 724
                this.parseOnFalseRules(context);
......
634 757
                        if (code == null) {
635 758
                            break;
636 759
                        }
637
                        args.add(argNameX, code);
760
                        args.add(code);
638 761
                        n++;
639 762
                    }
640 763
                } else {
......
642 765
//                    if( code == null) {
643 766
//                        code = context.getCodeBuilder().constant(null);
644 767
//                    }
645
                    args.add(argName,code);
768
                    args.add(code);
646 769
                }
647 770
            }
648 771
            return args;
649 772
        }
650 773
    }
651 774

  
775
    public static class FixedArgsBuilderFromNames implements ArgsBuilder {
776

  
777
        protected final String[] argNames;
778

  
779
        public FixedArgsBuilderFromNames(String... argNames) {
780
            this.argNames = argNames;
781
        }
782

  
783
        @Override
784
        public String toString() {
785
          return "fixed_args_names("+StringUtils.join(argNames,",")+")";
786
        }
787
        
788
        @Override
789
        public Codes build(StatementContext context) {
790
            context.trace(this.toString()+".build");
791
            CodeBuilder codeBuilder = context.getCodeBuilder();
792
            BaseCodes args = (BaseCodes) codeBuilder.args();
793
            for (String argName : argNames) {
794
                if (argName.contains("#")) {
795
                    int n = 1;
796
                    BaseCodes argsX = (BaseCodes) codeBuilder.args();
797
                    while (true) {
798
                        String argNameX = StringUtils.replace(argName, "#", String.valueOf(n).trim(), 1);
799
                        Code code = context.getCode(argNameX);
800
                        if (code == null) {
801
                            break;
802
                        }
803
                        argsX.add(code);
804
                        n++;
805
                    }
806
                    
807
                    args.add(codeBuilder.tuple(argsX));
808
                } else {
809
                    Code code = context.getCode(argName);
810
                    if( code == null) {
811
                        code = context.getCodeBuilder().constant(null);
812
                    }
813
                    args.add(code);
814
                }
815
            }
816
            return args;
817
        }
818
    }
819

  
652 820
    public static class ArgsBuilderExpand extends ArgsBuilderFromNames {
653 821

  
654 822
        public ArgsBuilderExpand(String... argNames) {
......
745 913
    }
746 914

  
747 915
    @Override
748
    public Rule require_identifier(String id) {
749
        return new RuleRequireIdentifier(id);
916
    public Rule require_identifier() {
917
        return new RuleRequireIdentifier();
750 918
    }
751 919

  
752 920
    @Override
753
    public Rule require_identifiers(String id, String sep) {
754
        return new RuleRequireIdentifiers(id, sep);
921
    public Rule require_identifiers(String sep) {
922
        return new RuleRequireIdentifiers(sep);
755 923
    }
756 924

  
757 925
    @Override
758
    public Rule require_literal_string(String id) {
759
        return new RuleRequireLiteralString(id);
926
    public Rule require_literal_string() {
927
        return new RuleRequireLiteralString();
760 928
    }
761 929

  
762 930
    @Override
......
765 933
    }
766 934

  
767 935
    @Override
768
    public Rule require_expression(String id) {
769
        return new RuleRequireExpression(id);
936
    public Rule require_expression() {
937
        return new RuleRequireExpression();
770 938
    }
771 939

  
772 940
    @Override
773
    public Rule require_expressions(String id, String separator) {
774
        return new RuleRequiereExpressions(id, separator);
941
    public Rule require_expressions(String separator) {
942
        return new RuleRequiereExpressions(separator);
775 943
    }
776 944

  
777 945
    @Override
......
780 948
    }
781 949

  
782 950
    @Override
783
    public ConditionalRule optional_identifiers(String id, String separator) {
784
        return new RuleOptionalIdentifiers(id, separator);
951
    public ConditionalRule optional_identifiers(String separator) {
952
        return new RuleOptionalIdentifiers(separator);
785 953
    }
786 954

  
787 955
    @Override
788
    public ConditionalRule optional_literal_string(String id) {
789
        return new RuleOptionalLiteralString(id);
956
    public ConditionalRule optional_literal_string() {
957
        return new RuleOptionalLiteralString();
790 958
    }
791 959

  
792 960
    @Override
......
806 974
            return false;
807 975
        }
808 976
        context.trace(this.getName()+".isApplicable");
809
        AbstractLexicalAnalyzer lexer = (AbstractLexicalAnalyzer) context.getLexicalAnalyzer();
810
        lexer.push_state();
977
        context.save_state();
811 978
        try {
812
          boolean applicable = false;
813 979
          for (Rule rule : rules) {
814
            if (!(rule instanceof IsApplicableRule)) {
815
                break;
980
            if( rule == null ) {
981
              continue;
816 982
            }
817
            if( !((IsApplicableRule) rule).isApplicable(context) ) {
818
              return false;
983
            if (rule instanceof IsApplicableRule) {
984
              if( !((IsApplicableRule) rule).isApplicable(context) ) {
985
                context.trace(this.getName()+".isApplicable return false");
986
                return false;
987
              }
988
            } else {
989
              rule.parse(context);
819 990
            }
820
            applicable = true;
821 991
          }
822
          context.trace(this.getName()+".isApplicable return "+applicable);
823
          return applicable;
992
          context.trace(this.getName()+".isApplicable return true");
993
          return true;
994
        } catch(Exception ex) {
995
          context.trace(this.getName()+".isApplicable return false (error)");
996
          return false;
824 997
        } finally {
825
          lexer.pop_state();
998
          context.restore_state();
826 999
        }
827 1000
    }
828 1001

  
......
833 1006
    }
834 1007
    
835 1008
    @Override
1009
    public ArgsBuilder fixed_args_names(String... args) {
1010
        ArgsBuilder x = new FixedArgsBuilderFromNames(args);
1011
        return x;
1012
    }
1013
    
1014
    @Override
836 1015
    public ArgsBuilder args_expand(String... args) {
837 1016
        ArgsBuilder x = new ArgsBuilderExpand(args);
838 1017
        return x;
......
871 1050
    }
872 1051

  
873 1052
    @Override
1053
    public Rule fail() {
1054
      return new RuleFail();
1055
    }
1056

  
1057
    @Override
874 1058
    public Rule break_loop() {
875 1059
      return new RuleBreakLoop();
876 1060
    }

Also available in: Unified diff