KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > freemarker > core > FMParser


1 /* Generated By:JavaCC: Do not edit this line. FMParser.java */
2 package freemarker.core;
3
4 import freemarker.template.*;
5 import freemarker.template.utility.StringUtil;
6 import freemarker.template.utility.DeepUnwrap;
7 import java.io.*;
8 import java.util.*;
9
10 /**
11  * This class is generated by JavaCC from a grammar file.
12  */

13 public class FMParser implements FMParserConstants {
14
15 // Necessary for adding macros and setting location info.
16
Template template;
17   private String JavaDoc templateName;
18
19 // variables that keep track of whether we are in a loop or a switch.
20
private int loopNesting, switchNesting;
21   private boolean inMacro, inFunction, stripWhitespace, stripText;
22   private LinkedList escapes = new LinkedList();
23   private int contentNesting; // for stripText
24

25   /**
26    * Create an FM expression parser using a string.
27    */

28   static public FMParser createExpressionParser(String JavaDoc s) {
29       SimpleCharStream scs = new SimpleCharStream(new StringReader(s), 1, 1, s.length());
30       FMParserTokenManager token_source = new FMParserTokenManager(scs);
31       token_source.SwitchTo(FMParserConstants.FM_EXPRESSION);
32       return new FMParser(token_source);
33   }
34
35   /**
36    * Constructs a new parser object.
37    * @param template The template associated with this parser.
38    * @param reader The character stream to use as input
39    * @param strictEscapeSyntax Whether FreeMarker directives must start with a #
40    */

41   public FMParser(Template template, Reader reader, boolean strictEscapeSyntax, boolean stripWhitespace) {
42       this(reader);
43       this.template = template;
44       token_source.strictEscapeSyntax = strictEscapeSyntax;
45       this.templateName = template != null ? template.getName() : "";
46       token_source.templateName = templateName;
47       this.stripWhitespace = stripWhitespace;
48
49   }
50
51   public FMParser(String JavaDoc template) {
52       this(null, new StringReader(template), true, true);
53   }
54
55   private String JavaDoc getErrorStart(Token t) {
56       return "Error in template: " + template.getName()
57             + "\non line " + t.beginLine + ", column " + t.beginColumn;
58   }
59
60   /**
61    * Throw an exception if the expression passed in is a String
62    * Literal
63    */

64   private void notStringLiteral(Expression exp, String JavaDoc expected) throws ParseException {
65       if (exp instanceof StringLiteral) {
66          String JavaDoc msg = "Error " + exp.getStartLocation()
67                      + "\nFound string literal: " + exp
68                      + "\nExpecting: " + expected;
69          throw new ParseException(msg, exp);
70       }
71   }
72
73   /**
74    * Throw an exception if the expression passed in is a Number
75    * Literal
76    */

77   private void notNumberLiteral(Expression exp, String JavaDoc expected) throws ParseException {
78       if (exp instanceof NumberLiteral) {
79          String JavaDoc msg = "Error " + exp.getStartLocation()
80                      + "\nFound number literal: " + exp.getCanonicalForm()
81                      + "\nExpecting " + expected;
82          throw new ParseException(msg, exp);
83       }
84   }
85
86   /**
87    * Throw an exception if the expression passed in is a boolean
88    * Literal
89    */

90   private void notBooleanLiteral(Expression exp, String JavaDoc expected) throws ParseException {
91       if (exp instanceof BooleanLiteral) {
92          String JavaDoc msg = "Error " + exp.getStartLocation()
93                      + "\nFound: " + exp.getCanonicalForm()
94                      + "\nExpecting " + expected;
95          throw new ParseException(msg, exp);
96       }
97   }
98
99   /**
100    * Throw an exception if the expression passed in is a Hash
101    * Literal
102    */

103   private void notHashLiteral(Expression exp, String JavaDoc expected) throws ParseException {
104         if (exp instanceof HashLiteral) {
105          String JavaDoc msg = "Error " + exp.getStartLocation()
106                      + "\nFound hash literal: " + exp.getCanonicalForm()
107                      + "\nExpecting " + expected;
108          throw new ParseException(msg, exp);
109       }
110   }
111
112   /**
113    * Throw an exception if the expression passed in is a List
114    * Literal
115    */

116
117   private void notListLiteral(Expression exp, String JavaDoc expected)
118       throws ParseException
119   {
120         if (exp instanceof ListLiteral) {
121          String JavaDoc msg = "Error " + exp.getStartLocation()
122                      + "\nFound list literal: " + exp.getCanonicalForm()
123                      + "\nExpecting " + expected;
124          throw new ParseException(msg, exp);
125       }
126   }
127   /**
128    * Throw an exception if the expression passed in is a literal
129    * other than of the numerical type
130    */

131   private void numberLiteralOnly(Expression exp) throws ParseException {
132       notStringLiteral(exp, "number");
133       notListLiteral(exp, "number");
134       notHashLiteral(exp, "number");
135       notBooleanLiteral(exp, "number");
136   }
137
138   /**
139    * Throw an exception if the expression passed in is
140    * not a string.
141    */

142   private void stringLiteralOnly(Expression exp) throws ParseException {
143       notNumberLiteral(exp, "number");
144       notListLiteral(exp, "number");
145       notHashLiteral(exp, "number");
146       notBooleanLiteral(exp, "number");
147   }
148
149   /**
150    * Throw an exception if the expression passed in is a literal
151    * other than of the boolean type
152    */

153   private void booleanLiteralOnly(Expression exp) throws ParseException {
154       notStringLiteral(exp, "boolean (true/false)");
155       notListLiteral(exp, "boolean (true/false)");
156       notHashLiteral(exp, "boolean (true/false)");
157       notNumberLiteral(exp, "boolean (true/false)");
158   }
159
160   private Expression escapedExpression(Expression exp) {
161       if(!escapes.isEmpty()) {
162           return ((EscapeBlock)escapes.getFirst()).doEscape(exp);
163       }
164       return exp;
165   }
166
167   private boolean getBoolean(Expression exp) throws ParseException {
168       TemplateModel tm = null;
169       try {
170           tm = exp.getAsTemplateModel(null);
171       } catch (Exception JavaDoc e) {
172          throw new ParseException(e.getMessage()
173                                   + "\nCould not evaluate expression: "
174                                   + exp.getCanonicalForm()
175                                   + exp.getStartLocation(), exp);
176       }
177       if (tm instanceof TemplateBooleanModel) {
178           try {
179              return ((TemplateBooleanModel) tm).getAsBoolean();
180           } catch (TemplateModelException tme) {
181           }
182       }
183       if (tm instanceof TemplateScalarModel) {
184           try {
185               return StringUtil.getYesNo(((TemplateScalarModel) tm).getAsString());
186           } catch (Exception JavaDoc e) {
187               throw new ParseException(e.getMessage()
188                                        + "\nExpecting yes/no, found: " + exp.getCanonicalForm()
189                                        + exp.getStartLocation(), exp);
190           }
191       }
192       throw new ParseException("Expecting boolean (yes/no) parameter" + exp.getStartLocation(), exp);
193   }
194
195 // Now the actual parsing code, starting
196
// with the productions for FreeMarker's
197
// expression syntax.
198

199 /**
200  * This is the same as OrExpression, since
201  * the OR is the operator with the lowest
202  * precedence.
203  */

204   final public Expression Expression() throws ParseException {
205    Expression exp;
206     exp = OrExpression();
207       {if (true) return exp;}
208     throw new Error JavaDoc("Missing return statement in function");
209   }
210
211 /**
212  * Lowest level expression, a literal, a variable,
213  * or a possibly more complex expression bounded
214  * by parentheses.
215  */

216   final public Expression PrimaryExpression() throws ParseException {
217    Expression exp;
218     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
219     case INTEGER:
220     case DECIMAL:
221       exp = NumberLiteral();
222       break;
223     case OPEN_BRACE:
224       exp = HashLiteral();
225       break;
226     case STRING_LITERAL:
227     case RAW_STRING:
228       exp = StringLiteral(true);
229       break;
230     case FALSE:
231     case TRUE:
232       exp = BooleanLiteral();
233       break;
234     case OPEN_BRACKET:
235       exp = ListLiteral();
236       break;
237     case ID:
238       exp = Identifier();
239       break;
240     case OPEN_PAREN:
241       exp = Parenthesis();
242       break;
243     case DOT:
244       exp = BuiltinVariable();
245       break;
246     default:
247       jj_la1[0] = jj_gen;
248       jj_consume_token(-1);
249       throw new ParseException();
250     }
251     label_1:
252     while (true) {
253       if (jj_2_1(2147483647)) {
254         ;
255       } else {
256         break label_1;
257       }
258       exp = AddSubExpression(exp);
259     }
260      {if (true) return exp;}
261     throw new Error JavaDoc("Missing return statement in function");
262   }
263
264   final public Expression Parenthesis() throws ParseException {
265    Expression exp, result;
266    Token start, end;
267     start = jj_consume_token(OPEN_PAREN);
268     exp = Expression();
269     end = jj_consume_token(CLOSE_PAREN);
270        result = new ParentheticalExpression(exp);
271        result.setLocation(template, start, end);
272        {if (true) return result;}
273     throw new Error JavaDoc("Missing return statement in function");
274   }
275
276 /**
277  * A primary expression preceded by zero or
278  * more unary operators. (The only unary operator we
279  * currently have is the NOT.)
280  */

281   final public Expression UnaryExpression() throws ParseException {
282    Expression exp, result;
283    boolean haveNot = false;
284    Token t = null, start=null;
285     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
286     case PLUS:
287     case MINUS:
288       result = UnaryPlusMinusExpression();
289       break;
290     case NOT:
291       result = NotExpression();
292       break;
293     case STRING_LITERAL:
294     case RAW_STRING:
295     case FALSE:
296     case TRUE:
297     case INTEGER:
298     case DECIMAL:
299     case DOT:
300     case OPEN_BRACKET:
301     case OPEN_PAREN:
302     case OPEN_BRACE:
303     case ID:
304       result = PrimaryExpression();
305       break;
306     default:
307       jj_la1[1] = jj_gen;
308       jj_consume_token(-1);
309       throw new ParseException();
310     }
311      {if (true) return result;}
312     throw new Error JavaDoc("Missing return statement in function");
313   }
314
315   final public Expression NotExpression() throws ParseException {
316    Token t;
317    Expression exp, result=null;
318    ArrayList nots = new ArrayList();
319     label_2:
320     while (true) {
321       t = jj_consume_token(NOT);
322                nots.add(t);
323       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
324       case NOT:
325         ;
326         break;
327       default:
328         jj_la1[2] = jj_gen;
329         break label_2;
330       }
331     }
332     exp = PrimaryExpression();
333       for (int i=0; i<nots.size(); i++) {
334          result = new NotExpression(exp);
335          Token tok = (Token) nots.get(nots.size() -i -1);
336          result.setLocation(template, tok, exp);
337          exp = result;
338       }
339       {if (true) return result;}
340     throw new Error JavaDoc("Missing return statement in function");
341   }
342
343   final public Expression UnaryPlusMinusExpression() throws ParseException {
344    Expression exp, result;
345    boolean isMinus = false;
346    Token t;
347     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
348     case PLUS:
349       t = jj_consume_token(PLUS);
350       break;
351     case MINUS:
352       t = jj_consume_token(MINUS);
353                  isMinus = true;
354       break;
355     default:
356       jj_la1[3] = jj_gen;
357       jj_consume_token(-1);
358       throw new ParseException();
359     }
360     exp = PrimaryExpression();
361       result = new UnaryPlusMinusExpression(exp, isMinus);
362       result.setLocation(template, t, exp);
363       {if (true) return result;}
364     throw new Error JavaDoc("Missing return statement in function");
365   }
366
367   final public Expression AdditiveExpression() throws ParseException {
368    Expression lhs, rhs, result;
369    boolean plus;
370     lhs = MultiplicativeExpression();
371                                    result = lhs;
372     label_3:
373     while (true) {
374       if (jj_2_2(2147483647)) {
375         ;
376       } else {
377         break label_3;
378       }
379       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
380       case PLUS:
381         jj_consume_token(PLUS);
382                  plus = true;
383         break;
384       case MINUS:
385         jj_consume_token(MINUS);
386                   plus = false;
387         break;
388       default:
389         jj_la1[4] = jj_gen;
390         jj_consume_token(-1);
391         throw new ParseException();
392       }
393       rhs = MultiplicativeExpression();
394          if (plus) {
395            // plus is treated separately, since it is also
396
// used for concatenation.
397
result = new AddConcatExpression(lhs, rhs);
398          }
399          else {
400              numberLiteralOnly(lhs);
401              numberLiteralOnly(rhs);
402              result = new ArithmeticExpression(lhs,
403                                             rhs,
404                                             ArithmeticExpression.SUBSTRACTION);
405          }
406          result.setLocation(template, lhs, rhs);
407          lhs = result;
408     }
409       {if (true) return result;}
410     throw new Error JavaDoc("Missing return statement in function");
411   }
412
413 /**
414  * A unary expression followed by zero or more
415  * unary expressions with operators in between.
416  */

417   final public Expression MultiplicativeExpression() throws ParseException {
418    Expression lhs, rhs, result;
419    int operation = ArithmeticExpression.MULTIPLICATION;
420     lhs = UnaryExpression();
421                           result = lhs;
422     label_4:
423     while (true) {
424       if (jj_2_3(2147483647)) {
425         ;
426       } else {
427         break label_4;
428       }
429       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
430       case TIMES:
431         jj_consume_token(TIMES);
432                   operation = ArithmeticExpression.MULTIPLICATION;
433         break;
434       case DIVIDE:
435         jj_consume_token(DIVIDE);
436                    operation = ArithmeticExpression.DIVISION;
437         break;
438       case PERCENT:
439         jj_consume_token(PERCENT);
440                    operation = ArithmeticExpression.MODULUS;
441         break;
442       default:
443         jj_la1[5] = jj_gen;
444         jj_consume_token(-1);
445         throw new ParseException();
446       }
447       rhs = UnaryExpression();
448          numberLiteralOnly(lhs);
449          numberLiteralOnly(rhs);
450          result = new ArithmeticExpression(lhs, rhs, operation);
451          result.setLocation(template, lhs, rhs);
452          lhs = result;
453     }
454       {if (true) return result;}
455     throw new Error JavaDoc("Missing return statement in function");
456   }
457
458   final public Expression EqualityExpression() throws ParseException {
459    Expression lhs, rhs, result;
460    Token t;
461     lhs = RelationalExpression();
462                                result = lhs;
463     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
464     case EQUALS:
465     case DOUBLE_EQUALS:
466     case NOT_EQUALS:
467       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
468       case NOT_EQUALS:
469         t = jj_consume_token(NOT_EQUALS);
470         break;
471       case EQUALS:
472         t = jj_consume_token(EQUALS);
473         break;
474       case DOUBLE_EQUALS:
475         t = jj_consume_token(DOUBLE_EQUALS);
476         break;
477       default:
478         jj_la1[6] = jj_gen;
479         jj_consume_token(-1);
480         throw new ParseException();
481       }
482       rhs = RelationalExpression();
483         notHashLiteral(lhs, "scalar");
484         notHashLiteral(rhs, "scalar");
485         notListLiteral(lhs, "scalar");
486         notListLiteral(rhs, "scalar");
487         result = new ComparisonExpression(lhs, rhs, t.image);
488         result.setLocation(template, lhs, rhs);
489       break;
490     default:
491       jj_la1[7] = jj_gen;
492       ;
493     }
494       {if (true) return result;}
495     throw new Error JavaDoc("Missing return statement in function");
496   }
497
498   final public Expression RelationalExpression() throws ParseException {
499    Expression lhs, rhs, result;
500    Token t;
501     lhs = RangeExpression();
502                           result = lhs;
503     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
504     case LESS_THAN:
505     case LESS_THAN_EQUALS:
506     case ESCAPED_GT:
507     case ESCAPED_GTE:
508     case NATURAL_GT:
509     case NATURAL_GTE:
510       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
511       case NATURAL_GTE:
512         t = jj_consume_token(NATURAL_GTE);
513         break;
514       case ESCAPED_GTE:
515         t = jj_consume_token(ESCAPED_GTE);
516         break;
517       case NATURAL_GT:
518         t = jj_consume_token(NATURAL_GT);
519         break;
520       case ESCAPED_GT:
521         t = jj_consume_token(ESCAPED_GT);
522         break;
523       case LESS_THAN_EQUALS:
524         t = jj_consume_token(LESS_THAN_EQUALS);
525         break;
526       case LESS_THAN:
527         t = jj_consume_token(LESS_THAN);
528         break;
529       default:
530         jj_la1[8] = jj_gen;
531         jj_consume_token(-1);
532         throw new ParseException();
533       }
534       rhs = RangeExpression();
535         notHashLiteral(lhs, "scalar");
536         notHashLiteral(rhs, "scalar");
537         notListLiteral(lhs, "scalar");
538         notListLiteral(rhs, "scalar");
539         notStringLiteral(lhs, "number");
540         notStringLiteral(rhs, "number");
541         result = new ComparisonExpression(lhs, rhs, t.image);
542         result.setLocation(template, lhs, rhs);
543       break;
544     default:
545       jj_la1[9] = jj_gen;
546       ;
547     }
548       {if (true) return result;}
549     throw new Error JavaDoc("Missing return statement in function");
550   }
551
552   final public Expression RangeExpression() throws ParseException {
553    Expression lhs, rhs=null, result;
554     lhs = AdditiveExpression();
555                               result = lhs;
556     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
557     case DOT_DOT:
558       jj_consume_token(DOT_DOT);
559       if (jj_2_4(2147483647)) {
560         rhs = AdditiveExpression();
561       } else {
562         ;
563       }
564            numberLiteralOnly(lhs);
565            if (rhs != null) {
566                numberLiteralOnly(rhs);
567            }
568            Range range = new Range(lhs, rhs);
569            if (rhs != null) {
570                range.setLocation(template, lhs, rhs);
571            } else {
572               range.setLocation(template, lhs, lhs);
573            }
574            result = range;
575       break;
576     default:
577       jj_la1[10] = jj_gen;
578       ;
579     }
580         {if (true) return result;}
581     throw new Error JavaDoc("Missing return statement in function");
582   }
583
584   final public Expression AndExpression() throws ParseException {
585    Expression lhs, rhs, result;
586     lhs = EqualityExpression();
587                              result = lhs;
588     label_5:
589     while (true) {
590       if (jj_2_5(2147483647)) {
591         ;
592       } else {
593         break label_5;
594       }
595       jj_consume_token(AND);
596       rhs = EqualityExpression();
597          booleanLiteralOnly(lhs);
598          booleanLiteralOnly(rhs);
599          result = new AndExpression(lhs, rhs);
600          result.setLocation(template, lhs, rhs);
601          lhs = result;
602     }
603       {if (true) return result;}
604     throw new Error JavaDoc("Missing return statement in function");
605   }
606
607   final public Expression OrExpression() throws ParseException {
608    Expression lhs, rhs, result;
609     lhs = AndExpression();
610                         result = lhs;
611     label_6:
612     while (true) {
613       if (jj_2_6(2147483647)) {
614         ;
615       } else {
616         break label_6;
617       }
618       jj_consume_token(OR);
619       rhs = AndExpression();
620          booleanLiteralOnly(lhs);
621          booleanLiteralOnly(rhs);
622          result = new OrExpression(lhs, rhs);
623          result.setLocation(template, lhs, rhs);
624          lhs = result;
625     }
626       {if (true) return result;}
627     throw new Error JavaDoc("Missing return statement in function");
628   }
629
630   final public ListLiteral ListLiteral() throws ParseException {
631    ArrayList values = new ArrayList();
632    Token begin, end;
633     begin = jj_consume_token(OPEN_BRACKET);
634     values = PositionalArgs();
635     end = jj_consume_token(CLOSE_BRACKET);
636         ListLiteral result = new ListLiteral(values);
637         result.setLocation(template, begin, end);
638         {if (true) return result;}
639     throw new Error JavaDoc("Missing return statement in function");
640   }
641
642   final public Expression NumberLiteral() throws ParseException {
643    Token op = null, t;
644     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
645     case INTEGER:
646       t = jj_consume_token(INTEGER);
647       break;
648     case DECIMAL:
649       t = jj_consume_token(DECIMAL);
650       break;
651     default:
652       jj_la1[11] = jj_gen;
653       jj_consume_token(-1);
654       throw new ParseException();
655     }
656        String JavaDoc s = t.image;
657        Expression result = new NumberLiteral(template.getArithmeticEngine().toNumber(s));
658        Token startToken = (op != null) ? op : t;
659        result.setLocation(template, startToken, t);
660        {if (true) return result;}
661     throw new Error JavaDoc("Missing return statement in function");
662   }
663
664   final public Identifier Identifier() throws ParseException {
665     Token t;
666     t = jj_consume_token(ID);
667         Identifier id = new Identifier(t.image);
668         id.setLocation(template, t, t);
669         {if (true) return id;}
670     throw new Error JavaDoc("Missing return statement in function");
671   }
672
673   final public Expression IdentifierOrStringLiteral() throws ParseException {
674    Expression exp;
675     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
676     case ID:
677       exp = Identifier();
678       break;
679     case STRING_LITERAL:
680     case RAW_STRING:
681       exp = StringLiteral(false);
682       break;
683     default:
684       jj_la1[12] = jj_gen;
685       jj_consume_token(-1);
686       throw new ParseException();
687     }
688       {if (true) return exp;}
689     throw new Error JavaDoc("Missing return statement in function");
690   }
691
692   final public BuiltinVariable BuiltinVariable() throws ParseException {
693    Token dot, name;
694     dot = jj_consume_token(DOT);
695     name = jj_consume_token(ID);
696       BuiltinVariable result = null;
697       try {
698           result = new BuiltinVariable(name.image);
699       } catch (ParseException pe) {
700           pe.lineNumber = dot.beginLine;
701           pe.columnNumber = dot.beginColumn;
702           {if (true) throw pe;}
703       }
704       result.setLocation(template, dot, name);
705       {if (true) return result;}
706     throw new Error JavaDoc("Missing return statement in function");
707   }
708
709 /**
710  * Production that builds up an expression
711  * using the dot or dynamic key name
712  * or the args list if this is a method invocation.
713  */

714   final public Expression AddSubExpression(Expression exp) throws ParseException {
715    Expression result = null;
716     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
717     case DOT:
718       result = DotVariable(exp);
719       break;
720     case OPEN_BRACKET:
721       result = DynamicKey(exp);
722       break;
723     case OPEN_PAREN:
724       result = MethodArgs(exp);
725       break;
726     case BUILT_IN:
727       result = BuiltIn(exp);
728       break;
729     default:
730       jj_la1[13] = jj_gen;
731       jj_consume_token(-1);
732       throw new ParseException();
733     }
734         {if (true) return result;}
735     throw new Error JavaDoc("Missing return statement in function");
736   }
737
738   final public Expression BuiltIn(Expression exp) throws ParseException {
739    Token t=null;
740     jj_consume_token(BUILT_IN);
741     t = jj_consume_token(ID);
742        BuiltIn result = null;
743        try {
744            result = BuiltIn.newBuiltIn(exp, t.image, t, templateName);
745        } catch (ParseException pe) {
746            pe.lineNumber = t.beginLine;
747            pe.columnNumber = t.beginColumn;
748            {if (true) throw pe;}
749        }
750        result.setLocation(template, exp, t);
751        {if (true) return result;}
752     throw new Error JavaDoc("Missing return statement in function");
753   }
754
755 /**
756  * production for when a key is specified by <DOT> + keyname
757  */

758   final public Expression DotVariable(Expression exp) throws ParseException {
759   Token t;
760     jj_consume_token(DOT);
761     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
762     case ID:
763       t = jj_consume_token(ID);
764       break;
765     case TIMES:
766       t = jj_consume_token(TIMES);
767       break;
768     case DOUBLE_STAR:
769       t = jj_consume_token(DOUBLE_STAR);
770       break;
771     case FALSE:
772     case TRUE:
773     case LESS_THAN:
774     case LESS_THAN_EQUALS:
775     case ESCAPED_GT:
776     case ESCAPED_GTE:
777     case IN:
778     case AS:
779     case USING:
780       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
781       case LESS_THAN:
782         t = jj_consume_token(LESS_THAN);
783         break;
784       case LESS_THAN_EQUALS:
785         t = jj_consume_token(LESS_THAN_EQUALS);
786         break;
787       case ESCAPED_GT:
788         t = jj_consume_token(ESCAPED_GT);
789         break;
790       case ESCAPED_GTE:
791         t = jj_consume_token(ESCAPED_GTE);
792         break;
793       case FALSE:
794         t = jj_consume_token(FALSE);
795         break;
796       case TRUE:
797         t = jj_consume_token(TRUE);
798         break;
799       case IN:
800         t = jj_consume_token(IN);
801         break;
802       case AS:
803         t = jj_consume_token(AS);
804         break;
805       case USING:
806         t = jj_consume_token(USING);
807         break;
808       default:
809         jj_la1[14] = jj_gen;
810         jj_consume_token(-1);
811         throw new ParseException();
812       }
813             if (!Character.isLetter(t.image.charAt(0))) {
814                 String JavaDoc msg = getErrorStart(t)
815                             + "\n" + t.image + " is not a valid identifier.";
816                 {if (true) throw new ParseException(msg, t.beginLine, t.beginColumn);}
817             }
818       break;
819     default:
820       jj_la1[15] = jj_gen;
821       jj_consume_token(-1);
822       throw new ParseException();
823     }
824          notListLiteral(exp, "hash");
825          notStringLiteral(exp, "hash");
826          notBooleanLiteral(exp, "hash");
827          Dot dot = new Dot(exp, t.image);
828          dot.setLocation(template, exp, t);
829          {if (true) return dot;}
830     throw new Error JavaDoc("Missing return statement in function");
831   }
832
833 /**
834  * production for when the key is specified
835  * in brackets.
836  */

837   final public Expression DynamicKey(Expression exp) throws ParseException {
838    Expression arg;
839    Token t;
840     jj_consume_token(OPEN_BRACKET);
841     arg = Expression();
842     t = jj_consume_token(CLOSE_BRACKET);
843        notBooleanLiteral(exp, "list or hash");
844        notNumberLiteral(exp, "list or hash");
845        DynamicKeyName dkn = new DynamicKeyName(exp, arg);
846        dkn.setLocation(template, exp, t);
847        {if (true) return dkn;}
848     throw new Error JavaDoc("Missing return statement in function");
849   }
850
851 /**
852  * production for an arglist part of a method invocation.
853  */

854   final public MethodCall MethodArgs(Expression exp) throws ParseException {
855      ArrayList args = new ArrayList();
856      Token end;
857     jj_consume_token(OPEN_PAREN);
858     args = PositionalArgs();
859     end = jj_consume_token(CLOSE_PAREN);
860         args.trimToSize();
861         MethodCall result = new MethodCall(exp, args);
862         result.setLocation(template, exp, end);
863         {if (true) return result;}
864     throw new Error JavaDoc("Missing return statement in function");
865   }
866
867   final public StringLiteral StringLiteral(boolean interpolate) throws ParseException {
868   Token t;
869   boolean raw = false;
870     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
871     case STRING_LITERAL:
872       t = jj_consume_token(STRING_LITERAL);
873       break;
874     case RAW_STRING:
875       t = jj_consume_token(RAW_STRING);
876                      raw = true;
877       break;
878     default:
879       jj_la1[16] = jj_gen;
880 <