1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.peaseplate.internal.lang;
21
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import org.peaseplate.TemplateEngine;
26 import org.peaseplate.TemplateException;
27 import org.peaseplate.TemplateRuntimeException;
28 import org.peaseplate.internal.lang.command.AdditionCommand;
29 import org.peaseplate.internal.lang.command.AndCommand;
30 import org.peaseplate.internal.lang.command.BitwiseAndCommand;
31 import org.peaseplate.internal.lang.command.BitwiseExclusiveOrCommand;
32 import org.peaseplate.internal.lang.command.BitwiseInclusiveOrCommand;
33 import org.peaseplate.internal.lang.command.ComplementCommand;
34 import org.peaseplate.internal.lang.command.DivideCommand;
35 import org.peaseplate.internal.lang.command.EqualsCommand;
36 import org.peaseplate.internal.lang.command.GreaterEqualCommand;
37 import org.peaseplate.internal.lang.command.GreaterThanCommand;
38 import org.peaseplate.internal.lang.command.ICommand;
39 import org.peaseplate.internal.lang.command.InlineConditionCommand;
40 import org.peaseplate.internal.lang.command.InvocationCommand;
41 import org.peaseplate.internal.lang.command.LessEqualCommand;
42 import org.peaseplate.internal.lang.command.LessThanCommand;
43 import org.peaseplate.internal.lang.command.ModuloCommand;
44 import org.peaseplate.internal.lang.command.MultiplyCommand;
45 import org.peaseplate.internal.lang.command.NegativeCommand;
46 import org.peaseplate.internal.lang.command.NotCommand;
47 import org.peaseplate.internal.lang.command.NotEqualsCommand;
48 import org.peaseplate.internal.lang.command.OrCommand;
49 import org.peaseplate.internal.lang.command.PopCommand;
50 import org.peaseplate.internal.lang.command.PositiveCommand;
51 import org.peaseplate.internal.lang.command.QueryCommand;
52 import org.peaseplate.internal.lang.command.ShiftLeftCommand;
53 import org.peaseplate.internal.lang.command.ShiftRightCommand;
54 import org.peaseplate.internal.lang.command.SubstractCommand;
55 import org.peaseplate.internal.lang.command.ThisCommand;
56 import org.peaseplate.internal.lang.command.TransformerCommand;
57 import org.peaseplate.internal.lang.command.UnsignedShiftRightCommand;
58 import org.peaseplate.internal.lang.command.ValueCommand;
59 import org.peaseplate.internal.lang.command.VariableCommand;
60 import org.peaseplate.internal.model.CompileContext;
61 import org.peaseplate.lang.TemplateParserException;
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 public class Parser {
110
111 private final TemplateEngine engine;
112 private final CompileContext context;
113 private final Tokenizer tokenizer;
114
115 public Parser(TemplateEngine engine, CompileContext context, int line, int column, char code[], int offset, int length) {
116 super();
117
118 this.engine = engine;
119 this.context = context;
120
121 tokenizer = new Tokenizer(context.getLocator(), line, column, code, offset, length);
122 }
123
124 public TemplateEngine getEngine() {
125 return engine;
126 }
127
128 public CompileContext getContext() {
129 return context;
130 }
131
132 public Tokenizer getTokenizer() {
133 return tokenizer;
134 }
135
136
137
138
139
140
141
142
143
144
145 public ICommand readDefaultReference() throws TemplateException {
146 ICommand result = null;
147
148 try {
149 tokenizer.readToken();
150 result = parseCommand(null, 0);
151
152 if (Tokenizer.Type.NONE != tokenizer.getTokenType()) {
153 throw new TemplateParserException(
154 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
155 "Exected end of code but found \"" + tokenizer.getTokenValue() + "\""
156 );
157 }
158 }
159 catch (TokenizerException e) {
160 throw new TemplateParserException(context.getLocator(), e);
161 }
162
163 return result;
164 }
165
166
167
168
169
170
171
172
173 public String readKey() throws TemplateException {
174 String key = null;
175
176 try {
177 tokenizer.readKeyToken();
178
179 int line = tokenizer.getTokenLine();
180 int column = tokenizer.getTokenColumn();
181 Tokenizer.Type type = tokenizer.getTokenType();
182
183 if ((Tokenizer.Type.KEY != type) && (Tokenizer.Type.STRING != type))
184 throw new TemplateParserException(
185 context.getLocator(), line, column,
186 "Key identifier expected, but \"" + tokenizer.getTokenValue() + "\" found"
187 );
188
189 key = String.valueOf(tokenizer.getTokenValue());
190
191 tokenizer.readToken();
192 }
193 catch (TokenizerException e) {
194 throw new TemplateParserException(context.getLocator(), e);
195 }
196
197 return key;
198 }
199
200
201
202
203
204
205
206
207 public String readIdentifier() throws TemplateException {
208 String identifier = null;
209
210 try {
211 tokenizer.readToken();
212
213 int line = tokenizer.getTokenLine();
214 int column = tokenizer.getTokenColumn();
215 Tokenizer.Type type = tokenizer.getTokenType();
216
217 if (Tokenizer.Type.IDENTIFIER != type)
218 throw new TemplateParserException(
219 context.getLocator(), line, column,
220 "Identifier expected, but \"" + tokenizer.getTokenValue() + "\" found"
221 );
222
223 identifier = String.valueOf(tokenizer.getTokenValue());
224
225 tokenizer.readToken();
226 }
227 catch (TokenizerException e) {
228 throw new TemplateParserException(context.getLocator(), e);
229 }
230
231 return identifier;
232 }
233
234
235
236
237
238
239
240
241
242
243
244 protected ICommand parseCommand(Tokenizer.Type operator, int parenthesisCount) throws TemplateException {
245 ICommand result = null;
246 int line = tokenizer.getTokenLine();
247 int column = tokenizer.getTokenColumn();
248 Tokenizer.Type type = tokenizer.getTokenType();
249
250 try {
251 if (Tokenizer.Type.PARENTHESIS_OPEN == type) {
252 tokenizer.readToken();
253
254 result = parseCommand(null, parenthesisCount+1);
255 }
256 else if (isExpression())
257 result = parseExpression();
258 else
259 throw new TemplateParserException(
260 context.getLocator(), line, column,
261 "Expected (Invocation | Number | String | \"true\" | \"false\" | \"null\" | \"$this\" | \"$pop\" | \"(\")"
262 );
263
264 if (Tokenizer.Type.PARENTHESIS_CLOSE != tokenizer.getTokenType()) {
265 while (isAnyOperator()) {
266
267
268
269
270
271 if ((operator == null) || (tokenizer.getTokenType().ordinal() < operator.ordinal())) {
272
273
274 Tokenizer.Type currentOperator = tokenizer.getTokenType();
275 Object currentValue = tokenizer.getTokenValue();
276 int currentLine = tokenizer.getTokenLine();
277 int currentColumn = tokenizer.getTokenColumn();
278
279 tokenizer.readToken();
280
281 ICommand right = parseCommand(currentOperator, parenthesisCount);
282
283 result = createDoubleParameterCommand(
284 currentOperator, currentValue, currentLine, currentColumn,
285 result, right
286 );
287 }
288 else
289 break;
290 }
291 }
292 else if (parenthesisCount > 0)
293 tokenizer.readToken();
294
295 if (parenthesisCount == 0) {
296 if (Tokenizer.Type.INLINE_CONDIDION == tokenizer.getTokenType()) {
297 tokenizer.readToken();
298
299 ICommand trueCommand = parseCommand(null, 0);
300
301 if (Tokenizer.Type.INLINE_SEPARATOR != tokenizer.getTokenType())
302 throw new TemplateParserException(
303 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
304 "Expected \":\", but found \"" + tokenizer.getTokenValue() + "\""
305 );
306
307 tokenizer.readToken();
308
309 ICommand falseCommand = parseCommand(null, 0);
310
311 result = new InlineConditionCommand(
312 context.getLocator(), line, column,
313 result, trueCommand, falseCommand
314 );
315 }
316
317 result = parseTransformerChain(result);
318 }
319 }
320 catch (TokenizerException e) {
321 throw new TemplateParserException(context.getLocator(), e);
322 }
323
324 return result;
325 }
326
327 protected boolean isAnyOperator() throws TemplateException {
328 Tokenizer.Type type = tokenizer.getTokenType();
329
330 return
331 (Tokenizer.Type.MULTIPLICATIVE_OPERATOR == type) ||
332 (Tokenizer.Type.ADDITIVE_OPERATOR == type) ||
333 (Tokenizer.Type.SHIFT_OPERATOR == type) ||
334 (Tokenizer.Type.RELATIONAL_OPERATOR == type) ||
335 (Tokenizer.Type.EQUALITY_OPERATOR == type) ||
336 (Tokenizer.Type.BITWISE_OPERATOR == type) ||
337 (Tokenizer.Type.CONDITIONAL_AND_OPERATOR == type) ||
338 (Tokenizer.Type.CONDITIONAL_OR_OPERATOR == type)
339 ;
340 }
341
342 protected boolean isExpression() {
343 Tokenizer.Type type = tokenizer.getTokenType();
344
345 return
346 (Tokenizer.Type.UNARY_OPERATOR == type) ||
347 (Tokenizer.Type.IDENTIFIER == type) ||
348 (Tokenizer.Type.QUERY_OPEN == type) ||
349 (Tokenizer.Type.VARIABLE == type) ||
350 (Tokenizer.Type.NUMERIC == type) ||
351 (Tokenizer.Type.STRING == type) ||
352 (Tokenizer.Type.KEYWORD_TRUE == type) ||
353 (Tokenizer.Type.KEYWORD_FALSE == type) ||
354 (Tokenizer.Type.KEYWORD_NULL == type) ||
355 (Tokenizer.Type.KEYWORD_THIS == type) ||
356 (Tokenizer.Type.KEYWORD_POP == type)
357 ;
358 }
359
360
361
362
363
364
365
366
367
368
369 protected ICommand parseExpression() throws TemplateException {
370 ICommand result = null;
371
372 Tokenizer.Type type = tokenizer.getTokenType();
373
374 try {
375 if (Tokenizer.Type.UNARY_OPERATOR == type) {
376 Tokenizer.Type unaryType = type;
377 Object unaryValue = tokenizer.getTokenValue();
378 int unaryLine = tokenizer.getTokenLine();
379 int unaryColumn = tokenizer.getTokenColumn();
380
381 tokenizer.readToken();
382
383 result = createSingleParameterCommand(
384 unaryType, unaryValue,
385 unaryLine, unaryColumn, parseSubExpression()
386 );
387
388 }
389 else
390 result = parseSubExpression();
391 }
392 catch (TokenizerException e) {
393 throw new TemplateParserException(context.getLocator(), e);
394 }
395
396 return result;
397 }
398
399
400 protected ICommand parseSubExpression() throws TemplateException {
401 ICommand result = null;
402 Tokenizer.Type type = tokenizer.getTokenType();
403 Object value = tokenizer.getTokenValue();
404 int line = tokenizer.getTokenLine();
405 int column = tokenizer.getTokenColumn();
406
407 try {
408 switch (type) {
409 case IDENTIFIER:
410 result = parseInvocation(null);
411 break;
412
413 case QUERY_OPEN:
414 result = parseQuery(null);
415 break;
416
417 case VARIABLE:
418 if (!context.containsVariable(String.valueOf(value)))
419 throw new TemplateParserException(
420 context.getLocator(), line, column,
421 "The variable " + value + " is not defined"
422 );
423
424 result = new VariableCommand(context.getLocator(), line, column, String.valueOf(value));
425 tokenizer.readToken();
426 break;
427
428 case NUMERIC:
429 case STRING:
430 result = new ValueCommand(context.getLocator(), line, column, value);
431 tokenizer.readToken();
432 break;
433
434 case KEYWORD_TRUE:
435 result = new ValueCommand(context.getLocator(), line, column, Boolean.TRUE);
436 tokenizer.readToken();
437 break;
438
439 case KEYWORD_FALSE:
440 result = new ValueCommand(context.getLocator(), line, column, Boolean.FALSE);
441 tokenizer.readToken();
442 break;
443
444 case KEYWORD_NULL:
445 result = new ValueCommand(context.getLocator(), line, column, null);
446 tokenizer.readToken();
447 break;
448
449 case KEYWORD_THIS:
450 result = new ThisCommand(context.getLocator(), line, column);
451 tokenizer.readToken();
452 break;
453
454 case KEYWORD_POP:
455 tokenizer.readToken();
456
457 if (isExpressionChain()) {
458 ICommand command = parseExpressionChain(null);
459
460 result = new PopCommand(context.getLocator(), line, column, command);
461 }
462 else
463 result = new PopCommand(context.getLocator(), line, column, null);
464 break;
465
466 default:
467 throw new TemplateParserException(
468 context.getLocator(), line, column,
469 "Unexpected token"
470 );
471 }
472
473 if (isExpressionChain())
474 result = parseExpressionChain(result);
475 }
476 catch (TokenizerException e) {
477 throw new TemplateParserException(context.getLocator(), e);
478 }
479
480 return result;
481 }
482
483 protected boolean isExpressionChain() {
484 return
485 (Tokenizer.Type.DELEGATOR == tokenizer.getTokenType()) ||
486 (Tokenizer.Type.QUERY_OPEN == tokenizer.getTokenType())
487 ;
488 }
489
490 protected ICommand parseExpressionChain(ICommand command) throws TemplateException {
491 ICommand result = null;
492 Tokenizer.Type type = tokenizer.getTokenType();
493
494 try {
495 if (Tokenizer.Type.DELEGATOR == type) {
496 type = tokenizer.readToken();
497
498 switch (type) {
499 case IDENTIFIER:
500 result = parseInvocation(command);
501 break;
502
503 case KEYWORD_POP:
504 result = new PopCommand(context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(), command);
505 tokenizer.readToken();
506 break;
507
508 default:
509 throw new TemplateParserException(
510 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
511 "Expected identifier or \"pop\""
512 );
513 }
514 }
515 else if (Tokenizer.Type.QUERY_OPEN == type) {
516 result = parseQuery(command);
517 }
518 else
519 throw new TemplateParserException(
520 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
521 "Expected \".\" or \"[\""
522 );
523
524 if (isExpressionChain())
525 result = parseExpressionChain(result);
526 }
527 catch (TokenizerException e) {
528 throw new TemplateParserException(context.getLocator(), e);
529 }
530
531 return result;
532 }
533
534 protected boolean isInvocation() {
535 return (Tokenizer.Type.IDENTIFIER == tokenizer.getTokenType());
536 }
537
538 protected ICommand parseInvocation(ICommand command) throws TemplateException {
539 int line = tokenizer.getTokenLine();
540 int column = tokenizer.getTokenColumn();
541 Object value = tokenizer.getTokenValue();
542
543 try {
544 tokenizer.readToken();
545
546 return new InvocationCommand(
547 context.getLocator(), line, column, command,
548 String.valueOf(value), parseParameterList()
549 );
550 }
551 catch (TokenizerException e) {
552 throw new TemplateParserException(context.getLocator(), e);
553 }
554 }
555
556 protected ICommand parseQuery(ICommand command) throws TemplateException {
557 ICommand identifierCommand = null;
558 int line = tokenizer.getTokenLine();
559 int column = tokenizer.getTokenColumn();
560
561 try {
562 tokenizer.readToken();
563
564 identifierCommand = parseCommand(null, 0);
565
566 if (tokenizer.getTokenType() != Tokenizer.Type.QUERY_CLOSE)
567 throw new TemplateRuntimeException(
568 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
569 "Exprected \"]\""
570 );
571
572 tokenizer.readToken();
573
574 return new QueryCommand(
575 context.getLocator(), line, column, command,
576 identifierCommand, parseParameterList()
577 );
578 }
579 catch (TokenizerException e) {
580 throw new TemplateParserException(context.getLocator(), e);
581 }
582 }
583
584
585
586
587
588
589
590
591
592
593
594
595 public ICommand[] parseParameterList() throws TemplateException {
596 List<ICommand> results = null;
597
598 try {
599 if (Tokenizer.Type.PARENTHESIS_OPEN == tokenizer.getTokenType()) {
600
601 tokenizer.readToken();
602
603 results = new ArrayList<ICommand>();
604
605 if (Tokenizer.Type.PARENTHESIS_CLOSE == tokenizer.getTokenType()) {
606
607
608 tokenizer.readToken();
609 }
610 else while (true) {
611
612 results.add(parseCommand(null, 0));
613
614 Tokenizer.Type type = tokenizer.getTokenType();
615
616 if (Tokenizer.Type.PARENTHESIS_CLOSE == type) {
617
618 tokenizer.readToken();
619 break;
620 }
621 else if (Tokenizer.Type.SEPARATOR == type) {
622
623 tokenizer.readToken();
624 }
625 else
626 throw new TemplateParserException(
627 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
628 "Expected \")\" or \",\" but \"" + tokenizer.getTokenValue() + "\" found"
629 );
630 }
631 }
632 }
633 catch (TokenizerException e) {
634 throw new TemplateParserException(context.getLocator(), e);
635 }
636
637 return (results != null) ? (ICommand[])results.toArray(new ICommand[results.size()]) : null;
638 }
639
640
641
642
643
644
645
646
647
648
649
650
651 public String[] parseVariableList() throws TemplateException {
652 List<String> results = null;
653
654 try {
655 if (Tokenizer.Type.PARENTHESIS_OPEN == tokenizer.getTokenType()) {
656
657 tokenizer.readToken();
658
659 results = new ArrayList<String>();
660
661 if (Tokenizer.Type.PARENTHESIS_CLOSE == tokenizer.getTokenType()) {
662
663
664 tokenizer.readToken();
665 }
666 else while (true) {
667
668 Tokenizer.Type type = tokenizer.getTokenType();
669
670 if (Tokenizer.Type.VARIABLE != type)
671 throw new TemplateParserException(
672 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
673 "Expected a variable but \"" + tokenizer.getTokenValue() + "\" found"
674 );
675
676 results.add(String.valueOf(tokenizer.getTokenValue()));
677
678 type = tokenizer.readToken();
679
680 if (Tokenizer.Type.PARENTHESIS_CLOSE == type) {
681
682 tokenizer.readToken();
683 break;
684 }
685 else if (Tokenizer.Type.SEPARATOR == type) {
686
687 tokenizer.readToken();
688 }
689 else
690 throw new TemplateParserException(
691 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
692 "Expected \")\" or \",\" but \"" + tokenizer.getTokenValue() + "\" found"
693 );
694 }
695 }
696 }
697 catch (TokenizerException e) {
698 throw new TemplateParserException(context.getLocator(), e);
699 }
700
701 return (results != null) ? (String[])results.toArray(new String[results.size()]) : null;
702 }
703
704
705
706
707
708
709
710
711
712
713
714
715 public String[] parseIdentifierList() throws TemplateException {
716 List<String> results = null;
717
718 try {
719 if (Tokenizer.Type.PARENTHESIS_OPEN == tokenizer.getTokenType()) {
720
721 tokenizer.readToken();
722
723 results = new ArrayList<String>();
724
725 if (Tokenizer.Type.PARENTHESIS_CLOSE == tokenizer.getTokenType()) {
726
727
728 tokenizer.readToken();
729 }
730 else while (true) {
731
732 if (Tokenizer.Type.IDENTIFIER != tokenizer.getTokenType())
733 throw new TemplateParserException(
734 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
735 "Expected identifier, but found \"" + tokenizer.getTokenValue() + "\""
736 );
737
738 results.add(String.valueOf(tokenizer.getTokenValue()));
739
740 tokenizer.readToken();
741
742 Tokenizer.Type type = tokenizer.getTokenType();
743
744 if (Tokenizer.Type.PARENTHESIS_CLOSE == type) {
745
746 tokenizer.readToken();
747 break;
748 }
749 else if (Tokenizer.Type.SEPARATOR == type) {
750
751 tokenizer.readToken();
752 }
753 else
754 throw new TemplateParserException(
755 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
756 "Expected \")\" or \",\", but \"" + tokenizer.getTokenValue() + "\" found"
757 );
758 }
759 }
760 }
761 catch (TokenizerException e) {
762 throw new TemplateParserException(context.getLocator(), e);
763 }
764
765 return (results != null) ? (String[])results.toArray(new String[results.size()]) : null;
766 }
767
768
769
770
771
772
773
774
775
776
777 public String parseIdentifierExtension() throws TemplateException {
778 String result = null;
779
780 try {
781 if (Tokenizer.Type.DELEGATOR == tokenizer.getTokenType()) {
782 tokenizer.readToken();
783
784 Tokenizer.Type type = tokenizer.getTokenType();
785
786 if (Tokenizer.Type.IDENTIFIER != type)
787 throw new TemplateParserException(
788 context.getLocator(), tokenizer.getTokenColumn(), tokenizer.getTokenLine(),
789 "Expected identifier but \"" + tokenizer.getTokenValue() + "\" found"
790 );
791
792 result = String.valueOf(tokenizer.getTokenValue());
793 }
794 }
795 catch (TokenizerException e) {
796 throw new TemplateParserException(context.getLocator(), e);
797 }
798
799 return result;
800 }
801
802 protected ICommand createSingleParameterCommand(Tokenizer.Type operator, Object value, int line, int column, ICommand command) throws TemplateException {
803 if (Tokenizer.Type.UNARY_OPERATOR == operator) {
804 if ("+".equals(value))
805 return new PositiveCommand(context.getLocator(), line, column, command);
806 else if ("-".equals(value))
807 return new NegativeCommand(context.getLocator(), line, column, command);
808 else if ("!".equals(value))
809 return new NotCommand(context.getLocator(), line, column, command);
810 else if ("~".equals(value))
811 return new ComplementCommand(context.getLocator(), line, column, command);
812 }
813
814 throw new TemplateParserException(
815 context.getLocator(), line, column,
816 "Unexpected symbol \"" + value + "\" in operation \"" + operator
817 );
818 }
819
820 protected ICommand createDoubleParameterCommand(Tokenizer.Type operator, Object value, int line, int column, ICommand left, ICommand right) throws TemplateException {
821 switch (operator) {
822 case MULTIPLICATIVE_OPERATOR:
823 if ("*".equals(value))
824 return new MultiplyCommand(context.getLocator(), line, column, left, right);
825 else if ("/".equals(value))
826 return new DivideCommand(context.getLocator(), line, column, left, right);
827 else if ("%".equals(value))
828 return new ModuloCommand(context.getLocator(), line, column, left, right);
829 break;
830
831 case ADDITIVE_OPERATOR:
832 if ("+".equals(value))
833 return new AdditionCommand(context.getLocator(), line, column, left, right);
834 else if ("-".equals(value))
835 return new SubstractCommand(context.getLocator(), line, column, left, right);
836 break;
837
838 case SHIFT_OPERATOR:
839 if ("<<".equals(value))
840 return new ShiftLeftCommand(context.getLocator(), line, column, left, right);
841 else if (">>".equals(value))
842 return new ShiftRightCommand(context.getLocator(), line, column, left, right);
843 else if (">>>".equals(value))
844 return new UnsignedShiftRightCommand(context.getLocator(), line, column, left, right);
845 break;
846
847 case RELATIONAL_OPERATOR:
848 if ("<".equals(value))
849 return new LessThanCommand(context.getLocator(), line, column, left, right);
850 else if ("<=".equals(value))
851 return new LessEqualCommand(context.getLocator(), line, column, left, right);
852 else if (">".equals(value))
853 return new GreaterThanCommand(context.getLocator(), line, column, left, right);
854 else if (">=".equals(value))
855 return new GreaterEqualCommand(context.getLocator(), line, column, left, right);
856 break;
857
858 case EQUALITY_OPERATOR:
859 if ("==".equals(value))
860 return new EqualsCommand(context.getLocator(), line, column, left, right);
861 else if ("!=".equals(value))
862 return new NotEqualsCommand(context.getLocator(), line, column, left, right);
863 break;
864
865 case BITWISE_OPERATOR:
866 if ("&".equals(value))
867 return new BitwiseAndCommand(context.getLocator(), line, column, left, right);
868 else if ("^".equals(value))
869 return new BitwiseExclusiveOrCommand(context.getLocator(), line, column, left, right);
870 else if ("|".equals(value))
871 return new BitwiseInclusiveOrCommand(context.getLocator(), line, column, left, right);
872 break;
873
874 case CONDITIONAL_AND_OPERATOR:
875 if ("&&".equals(value))
876 return new AndCommand(context.getLocator(), line, column, left, right);
877 break;
878
879 case CONDITIONAL_OR_OPERATOR:
880 if ("||".equals(value))
881 return new OrCommand(context.getLocator(), line, column, left, right);
882 break;
883
884 default:
885 throw new TemplateParserException(
886 context.getLocator(), line, column, "Unexpected token"
887 );
888 }
889
890 throw new TemplateParserException(
891 context.getLocator(), line, column,
892 "Unexpected symbol \"" + value + "\" in operation \"" + operator
893 );
894 }
895
896
897
898
899
900
901
902
903
904
905
906
907
908 public ICommand parseTransformerChain(ICommand command) throws TemplateException {
909 ICommand result = command;
910
911 try {
912 while (Tokenizer.Type.TRANSFORMER_CALL == tokenizer.getTokenType()) {
913
914 tokenizer.readToken();
915
916 Tokenizer.Type type = tokenizer.getTokenType();
917 int transformerLine = tokenizer.getTokenLine();
918 int transformerColumn = tokenizer.getTokenColumn();
919
920
921 if (Tokenizer.Type.IDENTIFIER != type)
922 throw new TemplateParserException(
923 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
924 "Identifier expected"
925 );
926
927 String transformerName = String.valueOf(tokenizer.getTokenValue());
928 Object transformerExtension = null;
929
930 type = tokenizer.readToken();
931
932
933 if (Tokenizer.Type.DELEGATOR == type) {
934 type = tokenizer.readToken();
935
936
937 if (Tokenizer.Type.IDENTIFIER != type)
938 throw new TemplateParserException(
939 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
940 "Identifier expected"
941 );
942
943 transformerExtension = tokenizer.getTokenValue();
944
945 type = tokenizer.readToken();
946 }
947
948 result = new TransformerCommand(
949 context.getLocator(), transformerLine, transformerColumn,
950 engine.getTransformerService(), String.valueOf(transformerName),
951 (transformerExtension != null) ? String.valueOf(transformerExtension) : null,
952 result, parseParameterList()
953 );
954 }
955 }
956 catch (TokenizerException e) {
957 throw new TemplateParserException(context.getLocator(), e);
958 }
959
960 return result;
961 }
962
963 public String parseAssignedKey() throws TemplateException {
964 String key = null;
965
966 try {
967 if (Tokenizer.Type.ASSIGNMENT != tokenizer.getTokenType())
968 throw new TemplateParserException(
969 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
970 "Expected \"=\", but found \"" + tokenizer.getTokenValue() + "\""
971 );
972
973 tokenizer.readKeyToken();
974
975 if ((Tokenizer.Type.KEY != tokenizer.getTokenType()) && (Tokenizer.Type.STRING != tokenizer.getTokenType()))
976 throw new TemplateParserException(
977 context.getLocator(), tokenizer.getTokenLine(), tokenizer.getTokenColumn(),
978 "Key identifier expected, but \"" + tokenizer.getTokenValue() + "\" found"
979 );
980
981 key = String.valueOf(tokenizer.getTokenValue());
982
983 tokenizer.readToken();
984 }
985 catch (TokenizerException e) {
986 throw new TemplateParserException(context.getLocator(), e);
987 }
988
989 return key;
990
991 }
992
993 protected boolean isAnyOperator(Tokenizer.Type type) {
994 return
995 (type == Tokenizer.Type.MULTIPLICATIVE_OPERATOR) ||
996 (type == Tokenizer.Type.ADDITIVE_OPERATOR) ||
997 (type == Tokenizer.Type.SHIFT_OPERATOR) ||
998 (type == Tokenizer.Type.RELATIONAL_OPERATOR) ||
999 (type == Tokenizer.Type.EQUALITY_OPERATOR) ||
1000 (type == Tokenizer.Type.BITWISE_OPERATOR) ||
1001 (type == Tokenizer.Type.CONDITIONAL_AND_OPERATOR) ||
1002 (type == Tokenizer.Type.CONDITIONAL_OR_OPERATOR)
1003 ;
1004 }
1005
1006 }