You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by jv...@locus.apache.org on 2000/08/29 08:48:32 UTC

cvs commit: jakarta-velocity/src/java/org/apache/velocity/parser ASTPropertyMethod.java Parser.java Parser.jj Parser.jjt ParserConstants.java ParserTokenManager.java ParserTreeConstants.java ParserVisitor.java

jvanzyl     00/08/28 23:48:31

  Modified:    src/java/org/apache/velocity/parser Parser.java Parser.jj
                        Parser.jjt ParserConstants.java
                        ParserTokenManager.java ParserTreeConstants.java
                        ParserVisitor.java
  Added:       src/java/org/apache/velocity/parser ASTPropertyMethod.java
  Log:
  - added new PropertyMethod node. Making Velocity compatible with
    WM. This will take a couple more hours.
  
  Revision  Changes    Path
  1.3       +266 -86   jakarta-velocity/src/java/org/apache/velocity/parser/Parser.java
  
  Index: Parser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/parser/Parser.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Parser.java	2000/08/27 22:18:08	1.2
  +++ Parser.java	2000/08/29 06:48:23	1.3
  @@ -5,9 +5,16 @@
   import java.util.*;
   
   /**
  - * Each ASTNode will have access to an instance of
  - * this parser. So we will use the parser as a container
  - * for useful information.
  + * This class is responsible for parsing a Velocity
  + * template. This class was generated by JavaCC using
  + * the JJTree extension to produce an Abstract
  + * Syntax Tree (AST) of the template.
  + *
  + * Please look at the Parser.jjt file which is
  + * what controls the generation of this class.
  + *
  + * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
  + * @version $Id: Parser.java,v 1.3 2000/08/29 06:48:23 jvanzyl Exp $
    */
   public class Parser/*@bgen(jjtree)*/implements ParserTreeConstants, ParserConstants {/*@bgen(jjtree)*/
     protected JJTParserState jjtree = new JJTParserState();
  @@ -41,11 +48,15 @@
           return root;
       }
   
  -/* ------------------------------------------------------------------------
  - *
  - * Program structuring syntax follows.
  - *
  - * ------------------------------------------------------------------------- */
  +/**
  + * This method is what starts the whole parsing
  + * process. After the parsing is complete and
  + * the template has been turned into an AST,
  + * this method returns the root of AST which
  + * can subsequently be traversed by a visitor
  + * which implements the ParserVisitor interface
  + * which is generated automatically by JavaCC
  + */
     final public SimpleNode process() throws ParseException {
                           /*@bgen(jjtree) process */
     ASTprocess jjtn000 = new ASTprocess(this, JJTPROCESS);
  @@ -72,11 +83,14 @@
           case QUOTE:
           case TRUE:
           case FALSE:
  +        case DOLLAR:
  +        case DOT:
           case TEXT:
           case MONEY:
           case VARIABLE:
           case PROPERTY:
           case METHOD:
  +        case METHOD_BODY:
             ;
             break;
           default:
  @@ -111,11 +125,13 @@
       throw new Error("Missing return statement in function");
     }
   
  -/* ------------------------------------------------------------------------
  - *
  - * Statement syntax.
  - * |   Block()
  - * ------------------------------------------------------------------------- */
  +/**
  + * These are the types of statements that
  + * are acceptable in Velocity templates.
  + * I have not found that the order here
  + * matters much. Someone please correct
  + * me here if I'm wrong.
  + */
     final public void Statement() throws ParseException {
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
       case STRING_LITERAL:
  @@ -126,8 +142,11 @@
       case QUOTE:
       case TRUE:
       case FALSE:
  +    case DOLLAR:
  +    case DOT:
       case TEXT:
       case MONEY:
  +    case METHOD_BODY:
         Text();
         break;
       case LBRACKET:
  @@ -173,12 +192,27 @@
       }
     }
   
  +/**
  + * This method corresponds to the #stop
  + * directive which just simulates and EOF
  + * so that parsing stops. The #stop directive
  + * is really only useful for debugging
  + * purposes.
  + */
     final public void StopStatement() throws ParseException {
       jj_consume_token(STOP_DIRECTIVE);
     }
   
   /**
  - * $dynamicContent
  + * This method corresponds to variable
  + * references in Velocity templates.
  + * The following are examples of variable
  + * references that may be found in a
  + * template:
  + *
  + * $foo
  + * $bar
  + *
    */
     final public void Variable() throws ParseException {
                      /*@bgen(jjtree) Variable */
  @@ -195,7 +229,20 @@
     }
   
   /**
  - * $customer.Title
  + * This method corresponds to property
  + * references in Velocity templates.
  + * The following are examples of property
  + * references that my be found in a
  + * template:
  + *
  + * $foo.Bar
  + *
  + * Say the object $foo corresponds to foo
  + * in the context, then the following
  + * method will be invoked:
  + *
  + * foo.getBar()
  + *
    */
     final public void Property() throws ParseException {
                      /*@bgen(jjtree) Property */
  @@ -211,6 +258,11 @@
       }
     }
   
  +/**
  + * This method has yet to be fully implemented
  + * but will allow arbitrarily nested method
  + * calls
  + */
     final public void Parameter() throws ParseException {
                       /*@bgen(jjtree) Parameter */
     ASTParameter jjtn000 = new ASTParameter(this, JJTPARAMETER);
  @@ -256,6 +308,11 @@
       }
     }
   
  +/**
  + * This method has yet to be fully implemented
  + * but will allow arbitrarily nested method
  + * calls
  + */
     final public void Parameters() throws ParseException {
                        /*@bgen(jjtree) Parameters */
     ASTParameters jjtn000 = new ASTParameters(this, JJTPARAMETERS);
  @@ -272,14 +329,14 @@
           label_2:
           while (true) {
             switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
  -          case 37:
  +          case 40:
               ;
               break;
             default:
               jj_la1[3] = jj_gen;
               break label_2;
             }
  -          jj_consume_token(37);
  +          jj_consume_token(40);
             Parameter();
           }
           break;
  @@ -309,6 +366,62 @@
       }
     }
   
  +  final public void PropertyMethod() throws ParseException {
  +                         /*@bgen(jjtree) PropertyMethod */
  +  ASTPropertyMethod jjtn000 = new ASTPropertyMethod(this, JJTPROPERTYMETHOD);
  +  boolean jjtc000 = true;
  +  jjtree.openNodeScope(jjtn000);
  +    try {
  +      jj_consume_token(DOLLAR);
  +      label_3:
  +      while (true) {
  +        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
  +        case IDENTIFIER:
  +          jj_consume_token(IDENTIFIER);
  +          break;
  +        case METHOD_BODY:
  +          jj_consume_token(METHOD_BODY);
  +          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
  +          case DOT:
  +            jj_consume_token(DOT);
  +            break;
  +          default:
  +            jj_la1[5] = jj_gen;
  +            ;
  +          }
  +          break;
  +        default:
  +          jj_la1[6] = jj_gen;
  +          jj_consume_token(-1);
  +          throw new ParseException();
  +        }
  +        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
  +        case IDENTIFIER:
  +        case METHOD_BODY:
  +          ;
  +          break;
  +        default:
  +          jj_la1[7] = jj_gen;
  +          break label_3;
  +        }
  +      }
  +    } finally {
  +      if (jjtc000) {
  +        jjtree.closeNodeScope(jjtn000, true);
  +      }
  +    }
  +  }
  +
  +/**
  + * This method corresponds to a method
  + * reference in a Velocity template.
  + * The following are examples of method
  + * references that may be found in a
  + * template:
  + *
  + * $foo.getBar()
  + *
  + */
     final public void Method() throws ParseException {
                    /*@bgen(jjtree) Method */
     ASTMethod jjtn000 = new ASTMethod(this, JJTMETHOD);
  @@ -323,19 +436,24 @@
       }
     }
   
  -/* ------------------------------------------------------------------------
  - *
  - * This has to be seriously expanded to be
  - * compatible with WebMacro, and to be generally
  - * useful.
  - *
  +/**
    * We're not using this right now, I'm going to look
    * at borrowing the expression grammar from one of
    * the java grammars, there is also an example
    * of it in one of the examples, I'm going to leave
    * if out right now to keep things simple for now.
  + *
  + * This will eventually allow constructs like
  + * 
  + * #if ($this && $that)
  + *
  + * or
  + *
  + * #if ($that || $that)
  + *
  + * And eventually more complicated constructs.
    *
  - * ------------------------------------------------------------------------- */
  + */
     final public void Expression() throws ParseException {
                        /*@bgen(jjtree) Expression */
     ASTExpression jjtn000 = new ASTExpression(this, JJTEXPRESSION);
  @@ -364,10 +482,16 @@
       }
     }
   
  -/* ------------------------------------------------------------------------
  - * I'm going to have to change the way blocks are detected
  - * in order to allow javascript to work correctly.
  - * ------------------------------------------------------------------------- */
  +/**
  + * This method corresponds to a block in
  + * a Velocity template. Blocks are
  + * currently associated with:
  + *
  + * #if
  + * #foreach
  + * #while (not implemented)
  + *
  + */
     final public void Block() throws ParseException {
                   /*@bgen(jjtree) Block */
     ASTBlock jjtn000 = new ASTBlock(this, JJTBLOCK);
  @@ -375,7 +499,7 @@
     jjtree.openNodeScope(jjtn000);
       try {
         jj_consume_token(LBRACKET);
  -      label_3:
  +      label_4:
         while (true) {
           switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
           case INCLUDE_DIRECTIVE:
  @@ -395,16 +519,19 @@
           case QUOTE:
           case TRUE:
           case FALSE:
  +        case DOLLAR:
  +        case DOT:
           case TEXT:
           case MONEY:
           case VARIABLE:
           case PROPERTY:
           case METHOD:
  +        case METHOD_BODY:
             ;
             break;
           default:
  -          jj_la1[5] = jj_gen;
  -          break label_3;
  +          jj_la1[8] = jj_gen;
  +          break label_4;
           }
           Statement();
         }
  @@ -430,9 +557,13 @@
       }
     }
   
  -/* ------------------------------------------------------------------------
  +/**
  + * This method corresponds to an #if directive
  + * in a Velocity template. The following are
  + * examples if #if constructs that are
  + * acceptable in a template:
    *
  - * #if ($customer.owesMoney() && $customer.Name == "Fred")
  + * #if ($customer.owesMoney() && $customer.Name == "Fred") (not implemented)
    * {
    *     Pay up, or else!
    * }
  @@ -443,13 +574,15 @@
    *
    * #if ($dynanmicContent)
    * {
  + *     This is our $dynamicContent
    * }
    *
    * #if ($customer.owesMoney())
    * {
  + *     You better pay up!
    * }
    *
  - * ------------------------------------------------------------------------- */
  + */
     final public void IfStatement() throws ParseException {
                         /*@bgen(jjtree) IfStatement */
     ASTIfStatement jjtn000 = new ASTIfStatement(this, JJTIFSTATEMENT);
  @@ -475,7 +608,7 @@
           jj_consume_token(PROPERTY);
           break;
         default:
  -        jj_la1[6] = jj_gen;
  +        jj_la1[9] = jj_gen;
           jj_consume_token(-1);
           throw new ParseException();
         }
  @@ -487,7 +620,7 @@
           Statement();
           break;
         default:
  -        jj_la1[7] = jj_gen;
  +        jj_la1[10] = jj_gen;
           ;
         }
       } catch (Throwable jjte000) {
  @@ -511,10 +644,29 @@
       }
     }
   
  -/* ------------------------------------------------------------------------
  +/**
  + * This method corresponds to a #foreach
  + * directive in a Velocity template. The
  + * following are examples of #foreach
  + * constructs that are acceptable in
  + * a template:
    *
  + * #foreach $element in $list
  + * {
  + *     This is the fifth $element
  + * }
  + *
  + * #foreach $element in $foo.List
  + * {
  + *     This is the fifth $element
  + * }
  + *
  + * #foreach $element in $foo.getList()
  + * {
  + *     This is the fifth $element
  + * }
    *
  - * ------------------------------------------------------------------------- */
  + */
     final public void ForeachStatement() throws ParseException {
                              /*@bgen(jjtree) ForeachStatement */
     ASTForeachStatement jjtn000 = new ASTForeachStatement(this, JJTFOREACHSTATEMENT);
  @@ -535,7 +687,7 @@
           jj_consume_token(METHOD);
           break;
         default:
  -        jj_la1[8] = jj_gen;
  +        jj_la1[11] = jj_gen;
           jj_consume_token(-1);
           throw new ParseException();
         }
  @@ -561,26 +713,32 @@
       }
     }
   
  -/* ------------------------------------------------------------------------
  - *
  - * This should allow path character, and it should
  - * expand macros before processing.
  +/**
  + * This method corresponds to an #include
  + * directive in a Velocity template. The
  + * following are examples of #include
  + * constructs that are acceptable in
  + * a template:
    *
  - * ------------------------------------------------------------------------- */
  + * #include "foo.inc" 
  + */
     final public void IncludeStatement() throws ParseException {
       jj_consume_token(INCLUDE_DIRECTIVE);
       jj_consume_token(STRING_LITERAL);
     }
   
  -/* ------------------------------------------------------------------------
  +/**
  + * This method corresponds to a #set
  + * directive in a Velocity template. The
  + * following are examples of #set
  + * constructs that are acceptable in
  + * a template:
    *
    * #set name = "Fred"
    * #set $Customer.Name = "Sidney"
  - * #set $Database.findItem($partNum).Description = $newDescription
  - *
  - * I can only do the first right now.
  + * #set $Database.findItem($partNum).Description = $newDescription (not implemented)
    *
  - * ------------------------------------------------------------------------- */
  + */
     final public void SetStatement() throws ParseException {
                          /*@bgen(jjtree) SetStatement */
     ASTSetStatement jjtn000 = new ASTSetStatement(this, JJTSETSTATEMENT);
  @@ -596,7 +754,7 @@
           jj_consume_token(PROPERTY);
           break;
         default:
  -        jj_la1[9] = jj_gen;
  +        jj_la1[12] = jj_gen;
           jj_consume_token(-1);
           throw new ParseException();
         }
  @@ -621,7 +779,7 @@
           jj_consume_token(FALSE);
           break;
         default:
  -        jj_la1[10] = jj_gen;
  +        jj_la1[13] = jj_gen;
           jj_consume_token(-1);
           throw new ParseException();
         }
  @@ -632,25 +790,34 @@
       }
     }
   
  -/* ------------------------------------------------------------------------
  - *
  - * This should allow path character, and it should
  - * expand macros before processing. There is some code
  - * on the mailing list for an #include type instruction
  - * which is exactly what I need here.
  +/**
  + * This method corresponds to a #parse
  + * directive in a Velocity template. The
  + * following are examples of #parse
  + * constructs that are acceptable in
  + * a template:
    *
  - * ------------------------------------------------------------------------- */
  + * #parse "bar.vt"
  + */
     final public void ParseStatement() throws ParseException {
       jj_consume_token(PARSE_DIRECTIVE);
       jj_consume_token(STRING_LITERAL);
     }
   
  -/* ------------------------------------------------------------------------
  - *
  - * I don't care about this right now, I've never
  - * seen anyone use it.
  +/**
  + * This method corresponds to a #use
  + * directive in a Velocity template. The
  + * following are examples of #use
  + * constructs that are acceptable in
  + * a template:
  + *
  + * This has not been implemented and may
  + * not need to be because the Velocity
  + * parser doesn't have any problem with
  + * normal text that isn't part of Velocity's
  + * grammar.
    *
  - * ------------------------------------------------------------------------- */
  + */
     final public void UseStatement() throws ParseException {
                          /*@bgen(jjtree) UseStatement */
     ASTUseStatement jjtn000 = new ASTUseStatement(this, JJTUSESTATEMENT);
  @@ -665,12 +832,16 @@
       }
     }
   
  -/* ------------------------------------------------------------------------
  +/**
  + * This method corresponds to a #param
  + * directive in a Velocity template. The
  + * following are examples of #param
  + * constructs that are acceptable in
  + * a template:
    *
  - * #param author = "Joe"
  - * #param require = [ "user", "document", "session" ]
  + * #param $language = "en"
    *
  - * ------------------------------------------------------------------------- */
  + */
     final public void ParamStatement() throws ParseException {
                            /*@bgen(jjtree) ParamStatement */
     ASTParamStatement jjtn000 = new ASTParamStatement(this, JJTPARAMSTATEMENT);
  @@ -688,11 +859,11 @@
       }
     }
   
  -/* ------------------------------------------------------------------------
  - *
  - * How to cleanly extract all the text (including html).
  - *
  - * ------------------------------------------------------------------------- */
  +/**
  + * This method is responsible for allowing
  + * all non-grammar text to pass through
  + * unscathed.
  + */
     final public void Text() throws ParseException {
                  /*@bgen(jjtree) Text */
     ASTText jjtn000 = new ASTText(this, JJTTEXT);
  @@ -703,12 +874,18 @@
         case TEXT:
           jj_consume_token(TEXT);
           break;
  +      case DOLLAR:
  +        jj_consume_token(DOLLAR);
  +        break;
         case MONEY:
           jj_consume_token(MONEY);
           break;
         case EQUALS:
           jj_consume_token(EQUALS);
           break;
  +      case DOT:
  +        jj_consume_token(DOT);
  +        break;
         case QUOTE:
           jj_consume_token(QUOTE);
           break;
  @@ -730,8 +907,11 @@
         case RPAREN:
           jj_consume_token(RPAREN);
           break;
  +      case METHOD_BODY:
  +        jj_consume_token(METHOD_BODY);
  +        break;
         default:
  -        jj_la1[11] = jj_gen;
  +        jj_la1[14] = jj_gen;
           jj_consume_token(-1);
           throw new ParseException();
         }
  @@ -747,9 +927,9 @@
     public Token token, jj_nt;
     private int jj_ntk;
     private int jj_gen;
  -  final private int[] jj_la1 = new int[12];
  -  final private int[] jj_la1_0 = {0x27effb80,0x27effb80,0x10000,0x0,0x10000,0x27effb80,0x3000000,0x400,0x0,0x0,0x3010000,0x27e70000,};
  -  final private int[] jj_la1_1 = {0x16,0x16,0x16,0x20,0x16,0x16,0x16,0x0,0x16,0x6,0x16,0x0,};
  +  final private int[] jj_la1 = new int[15];
  +  final private int[] jj_la1_0 = {0x9feffb80,0x9feffb80,0x10000,0x0,0x10000,0x8000000,0x0,0x0,0x9feffb80,0x3000000,0x400,0x0,0x0,0x3010000,0x9fe70000,};
  +  final private int[] jj_la1_1 = {0xd8,0xd8,0x58,0x100,0x58,0x0,0x84,0x84,0xd8,0x58,0x0,0x58,0x18,0x58,0x80,};
   
     public Parser(java.io.InputStream stream) {
       jj_input_stream = new ASCII_CharStream(stream, 1, 1);
  @@ -757,7 +937,7 @@
       token = new Token();
       jj_ntk = -1;
       jj_gen = 0;
  -    for (int i = 0; i < 12; i++) jj_la1[i] = -1;
  +    for (int i = 0; i < 15; i++) jj_la1[i] = -1;
     }
   
     public void ReInit(java.io.InputStream stream) {
  @@ -767,7 +947,7 @@
       jj_ntk = -1;
       jjtree.reset();
       jj_gen = 0;
  -    for (int i = 0; i < 12; i++) jj_la1[i] = -1;
  +    for (int i = 0; i < 15; i++) jj_la1[i] = -1;
     }
   
     public Parser(java.io.Reader stream) {
  @@ -776,7 +956,7 @@
       token = new Token();
       jj_ntk = -1;
       jj_gen = 0;
  -    for (int i = 0; i < 12; i++) jj_la1[i] = -1;
  +    for (int i = 0; i < 15; i++) jj_la1[i] = -1;
     }
   
     public void ReInit(java.io.Reader stream) {
  @@ -786,7 +966,7 @@
       jj_ntk = -1;
       jjtree.reset();
       jj_gen = 0;
  -    for (int i = 0; i < 12; i++) jj_la1[i] = -1;
  +    for (int i = 0; i < 15; i++) jj_la1[i] = -1;
     }
   
     public Parser(ParserTokenManager tm) {
  @@ -794,7 +974,7 @@
       token = new Token();
       jj_ntk = -1;
       jj_gen = 0;
  -    for (int i = 0; i < 12; i++) jj_la1[i] = -1;
  +    for (int i = 0; i < 15; i++) jj_la1[i] = -1;
     }
   
     public void ReInit(ParserTokenManager tm) {
  @@ -803,7 +983,7 @@
       jj_ntk = -1;
       jjtree.reset();
       jj_gen = 0;
  -    for (int i = 0; i < 12; i++) jj_la1[i] = -1;
  +    for (int i = 0; i < 15; i++) jj_la1[i] = -1;
     }
   
     final private Token jj_consume_token(int kind) throws ParseException {
  @@ -850,15 +1030,15 @@
   
     final public ParseException generateParseException() {
       jj_expentries.removeAllElements();
  -    boolean[] la1tokens = new boolean[38];
  -    for (int i = 0; i < 38; i++) {
  +    boolean[] la1tokens = new boolean[41];
  +    for (int i = 0; i < 41; i++) {
         la1tokens[i] = false;
       }
       if (jj_kind >= 0) {
         la1tokens[jj_kind] = true;
         jj_kind = -1;
       }
  -    for (int i = 0; i < 12; i++) {
  +    for (int i = 0; i < 15; i++) {
         if (jj_la1[i] == jj_gen) {
           for (int j = 0; j < 32; j++) {
             if ((jj_la1_0[i] & (1<<j)) != 0) {
  @@ -870,7 +1050,7 @@
           }
         }
       }
  -    for (int i = 0; i < 38; i++) {
  +    for (int i = 0; i < 41; i++) {
         if (la1tokens[i]) {
           jj_expentry = new int[1];
           jj_expentry[0] = i;
  
  
  
  1.4       +205 -79   jakarta-velocity/src/java/org/apache/velocity/parser/Parser.jj
  
  Index: Parser.jj
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/parser/Parser.jj,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Parser.jj	2000/08/27 22:18:08	1.3
  +++ Parser.jj	2000/08/29 06:48:24	1.4
  @@ -82,9 +82,16 @@
   import java.util.*;
   
   /**
  - * Each ASTNode will have access to an instance of
  - * this parser. So we will use the parser as a container
  - * for useful information.
  + * This class is responsible for parsing a Velocity
  + * template. This class was generated by JavaCC using
  + * the JJTree extension to produce an Abstract
  + * Syntax Tree (AST) of the template.
  + *
  + * Please look at the Parser.jjt file which is
  + * what controls the generation of this class.
  + *
  + * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
  + * @version $Id: Parser.jj,v 1.4 2000/08/29 06:48:24 jvanzyl Exp $
    */
   public class Parser/*@bgen(jjtree)*/implements ParserTreeConstants/*@egen*/
   {/*@bgen(jjtree)*/
  @@ -197,6 +204,8 @@
   |   <QUOTE: "\"">
   |   <TRUE: "true">
   |   <FALSE: "false">
  +|   <DOLLAR: "$">
  +|   <DOT: ".">
   //|   <COMMA: ",">
   }
   
  @@ -217,10 +226,11 @@
   | <ALPHANUM_CHAR: [ "a"-"z", "A"-"Z", "0"-"9" ] >
   | <IDENTIFIER_CHAR: [ "a"-"z", "A"-"Z", "0"-"9","-" ] >
   | <IDENTIFIER: <ALPHA_CHAR> (<IDENTIFIER_CHAR>)* >
  -| <VARIABLE: "$" <ALPHA_CHAR> (<IDENTIFIER_CHAR>)* >
  -| <PROPERTY: "$" <ALPHA_CHAR> <IDENTIFIER> "." <IDENTIFIER> >
  +| <VARIABLE: "$" <IDENTIFIER> >
  +| <PROPERTY: "$" <IDENTIFIER> "." <IDENTIFIER> >
   | <METHOD_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "\"", ",", "$", "."] >
   | <METHOD: "$" <ALPHA_CHAR> ((<METHOD_CHAR>)* <LPAREN> (<METHOD_CHAR>)* <RPAREN>)+ >
  +| <METHOD_BODY: <IDENTIFIER> <LPAREN> (<METHOD_CHAR>)* <RPAREN> >
   }
   
   /*
  @@ -349,13 +359,16 @@
           }
       } 
   } 
  -
  -/* ------------------------------------------------------------------------
  - *
  - * Program structuring syntax follows.
  - *
  - * ------------------------------------------------------------------------- */
   
  +/**
  + * This method is what starts the whole parsing
  + * process. After the parsing is complete and
  + * the template has been turned into an AST,
  + * this method returns the root of AST which
  + * can subsequently be traversed by a visitor
  + * which implements the ParserVisitor interface
  + * which is generated automatically by JavaCC
  + */
   SimpleNode process() : {/*@bgen(jjtree) process */
     ASTprocess jjtn000 = new ASTprocess(this, JJTPROCESS);
     boolean jjtc000 = true;
  @@ -393,12 +406,13 @@
   /*@egen*/
   }
   
  -/* ------------------------------------------------------------------------
  - *
  - * Statement syntax.
  - * |   Block()
  - * ------------------------------------------------------------------------- */
  -
  +/**
  + * These are the types of statements that
  + * are acceptable in Velocity templates.
  + * I have not found that the order here
  + * matters much. Someone please correct
  + * me here if I'm wrong.
  + */
   void Statement()       : {}
   {
       Text()
  @@ -417,13 +431,28 @@
   
   }
   
  +/**
  + * This method corresponds to the #stop
  + * directive which just simulates and EOF
  + * so that parsing stops. The #stop directive
  + * is really only useful for debugging
  + * purposes.
  + */
   void StopStatement()      : {}
   {    
       <STOP_DIRECTIVE>
   }
   
   /**
  - * $dynamicContent
  + * This method corresponds to variable
  + * references in Velocity templates.
  + * The following are examples of variable
  + * references that may be found in a
  + * template:
  + *
  + * $foo
  + * $bar
  + *
    */
   void Variable() : {/*@bgen(jjtree) Variable */
     ASTVariable jjtn000 = new ASTVariable(this, JJTVARIABLE);
  @@ -443,7 +472,20 @@
   }
   
   /**
  - * $customer.Title
  + * This method corresponds to property
  + * references in Velocity templates.
  + * The following are examples of property
  + * references that my be found in a
  + * template:
  + *
  + * $foo.Bar
  + *
  + * Say the object $foo corresponds to foo
  + * in the context, then the following
  + * method will be invoked:
  + *
  + * foo.getBar()
  + *
    */
   void Property() : {/*@bgen(jjtree) Property */
     ASTProperty jjtn000 = new ASTProperty(this, JJTPROPERTY);
  @@ -462,6 +504,11 @@
   /*@egen*/
   }
   
  +/**
  + * This method has yet to be fully implemented
  + * but will allow arbitrarily nested method
  + * calls
  + */
   void Parameter() : {/*@bgen(jjtree) Parameter */
     ASTParameter jjtn000 = new ASTParameter(this, JJTPARAMETER);
     boolean jjtc000 = true;
  @@ -493,6 +540,11 @@
   /*@egen*/
   }
   
  +/**
  + * This method has yet to be fully implemented
  + * but will allow arbitrarily nested method
  + * calls
  + */
   void Parameters() : {/*@bgen(jjtree) Parameters */
     ASTParameters jjtn000 = new ASTParameters(this, JJTPARAMETERS);
     boolean jjtc000 = true;
  @@ -524,7 +576,33 @@
   /*@egen*/
   }
   
  +void PropertyMethod() : {/*@bgen(jjtree) PropertyMethod */
  +  ASTPropertyMethod jjtn000 = new ASTPropertyMethod(this, JJTPROPERTYMETHOD);
  +  boolean jjtc000 = true;
  +  jjtree.openNodeScope(jjtn000);
  +/*@egen*/}
  +{/*@bgen(jjtree) PropertyMethod */
  +    try {
  +/*@egen*/
  +    <DOLLAR> (<IDENTIFIER> | <METHOD_BODY> [<DOT>])+/*@bgen(jjtree)*/
  +    } finally {
  +      if (jjtc000) {
  +        jjtree.closeNodeScope(jjtn000, true);
  +      }
  +    }
  +/*@egen*/
  +}
   
  +/**
  + * This method corresponds to a method
  + * reference in a Velocity template.
  + * The following are examples of method
  + * references that may be found in a
  + * template:
  + *
  + * $foo.getBar()
  + *
  + */
   void Method() : {/*@bgen(jjtree) Method */
     ASTMethod jjtn000 = new ASTMethod(this, JJTMETHOD);
     boolean jjtc000 = true;
  @@ -546,20 +624,24 @@
       //"$" <IDENTIFIER> "." <IDENTIFIER> "(" ")"
   }
   
  -/* ------------------------------------------------------------------------
  - *
  - * This has to be seriously expanded to be
  - * compatible with WebMacro, and to be generally
  - * useful.
  - *
  +/**
    * We're not using this right now, I'm going to look
    * at borrowing the expression grammar from one of
    * the java grammars, there is also an example
    * of it in one of the examples, I'm going to leave
    * if out right now to keep things simple for now.
    *
  - * ------------------------------------------------------------------------- */
  -
  + * This will eventually allow constructs like
  + * 
  + * #if ($this && $that)
  + *
  + * or
  + *
  + * #if ($that || $that)
  + *
  + * And eventually more complicated constructs.
  + *
  + */
   void Expression() : {/*@bgen(jjtree) Expression */
     ASTExpression jjtn000 = new ASTExpression(this, JJTEXPRESSION);
     boolean jjtc000 = true;
  @@ -591,11 +673,16 @@
   /*@egen*/
   }
   
  -/* ------------------------------------------------------------------------
  - * I'm going to have to change the way blocks are detected
  - * in order to allow javascript to work correctly.
  - * ------------------------------------------------------------------------- */
  -
  +/**
  + * This method corresponds to a block in
  + * a Velocity template. Blocks are
  + * currently associated with:
  + *
  + * #if
  + * #foreach
  + * #while (not implemented)
  + *
  + */
   void Block() : {/*@bgen(jjtree) Block */
     ASTBlock jjtn000 = new ASTBlock(this, JJTBLOCK);
     boolean jjtc000 = true;
  @@ -627,9 +714,13 @@
   /*@egen*/
   }
   
  -/* ------------------------------------------------------------------------
  +/**
  + * This method corresponds to an #if directive
  + * in a Velocity template. The following are
  + * examples if #if constructs that are
  + * acceptable in a template:
    *
  - * #if ($customer.owesMoney() && $customer.Name == "Fred")
  + * #if ($customer.owesMoney() && $customer.Name == "Fred") (not implemented)
    * {
    *     Pay up, or else!
    * }
  @@ -640,14 +731,15 @@
    *
    * #if ($dynanmicContent)
    * {
  + *     This is our $dynamicContent
    * }
    *
    * #if ($customer.owesMoney())
    * {
  + *     You better pay up!
    * }
    *
  - * ------------------------------------------------------------------------- */
  -
  + */
   void IfStatement() : {/*@bgen(jjtree) IfStatement */
     ASTIfStatement jjtn000 = new ASTIfStatement(this, JJTIFSTATEMENT);
     boolean jjtc000 = true;
  @@ -684,11 +776,29 @@
   /*@egen*/
   }
   
  -/* ------------------------------------------------------------------------
  +/**
  + * This method corresponds to a #foreach
  + * directive in a Velocity template. The
  + * following are examples of #foreach
  + * constructs that are acceptable in
  + * a template:
    *
  + * #foreach $element in $list
  + * {
  + *     This is the fifth $element
  + * }
    *
  - * ------------------------------------------------------------------------- */
  -
  + * #foreach $element in $foo.List
  + * {
  + *     This is the fifth $element
  + * }
  + *
  + * #foreach $element in $foo.getList()
  + * {
  + *     This is the fifth $element
  + * }
  + *
  + */
   void ForeachStatement() : {/*@bgen(jjtree) ForeachStatement */
     ASTForeachStatement jjtn000 = new ASTForeachStatement(this, JJTFOREACHSTATEMENT);
     boolean jjtc000 = true;
  @@ -724,29 +834,33 @@
   /*@egen*/
   }
   
  -/* ------------------------------------------------------------------------
  - *
  - * This should allow path character, and it should
  - * expand macros before processing.
  +/**
  + * This method corresponds to an #include
  + * directive in a Velocity template. The
  + * following are examples of #include
  + * constructs that are acceptable in
  + * a template:
    *
  - * ------------------------------------------------------------------------- */
  -
  + * #include "foo.inc" 
  + */
   void IncludeStatement()      : {}
   {
     <INCLUDE_DIRECTIVE> 
     <STRING_LITERAL>
   }
   
  -/* ------------------------------------------------------------------------
  +/**
  + * This method corresponds to a #set
  + * directive in a Velocity template. The
  + * following are examples of #set
  + * constructs that are acceptable in
  + * a template:
    *
    * #set name = "Fred"
    * #set $Customer.Name = "Sidney"
  - * #set $Database.findItem($partNum).Description = $newDescription
  + * #set $Database.findItem($partNum).Description = $newDescription (not implemented)
    *
  - * I can only do the first right now.
  - *
  - * ------------------------------------------------------------------------- */
  - 
  + */
   void SetStatement() : {/*@bgen(jjtree) SetStatement */
     ASTSetStatement jjtn000 = new ASTSetStatement(this, JJTSETSTATEMENT);
     boolean jjtc000 = true;
  @@ -767,27 +881,34 @@
   /*@egen*/
   }
   
  -/* ------------------------------------------------------------------------
  - *
  - * This should allow path character, and it should
  - * expand macros before processing. There is some code
  - * on the mailing list for an #include type instruction
  - * which is exactly what I need here.
  +/**
  + * This method corresponds to a #parse
  + * directive in a Velocity template. The
  + * following are examples of #parse
  + * constructs that are acceptable in
  + * a template:
    *
  - * ------------------------------------------------------------------------- */
  -
  + * #parse "bar.vt"
  + */
   void ParseStatement()      : {}
   {
     <PARSE_DIRECTIVE> <STRING_LITERAL>
   }
   
  -/* ------------------------------------------------------------------------
  - *
  - * I don't care about this right now, I've never
  - * seen anyone use it.
  +/**
  + * This method corresponds to a #use
  + * directive in a Velocity template. The
  + * following are examples of #use
  + * constructs that are acceptable in
  + * a template:
  + *
  + * This has not been implemented and may
  + * not need to be because the Velocity
  + * parser doesn't have any problem with
  + * normal text that isn't part of Velocity's
  + * grammar.
    *
  - * ------------------------------------------------------------------------- */
  -
  + */
   void UseStatement() : {/*@bgen(jjtree) UseStatement */
     ASTUseStatement jjtn000 = new ASTUseStatement(this, JJTUSESTATEMENT);
     boolean jjtc000 = true;
  @@ -805,13 +926,16 @@
   /*@egen*/
   }
   
  -/* ------------------------------------------------------------------------
  +/**
  + * This method corresponds to a #param
  + * directive in a Velocity template. The
  + * following are examples of #param
  + * constructs that are acceptable in
  + * a template:
    *
  - * #param author = "Joe"
  - * #param require = [ "user", "document", "session" ]
  + * #param $language = "en"
    *
  - * ------------------------------------------------------------------------- */
  -
  + */
   void ParamStatement() : {/*@bgen(jjtree) ParamStatement */
     ASTParamStatement jjtn000 = new ASTParamStatement(this, JJTPARAMSTATEMENT);
     boolean jjtc000 = true;
  @@ -828,13 +952,12 @@
     }
   /*@egen*/
   }
  -
  -/* ------------------------------------------------------------------------
  - *
  - * How to cleanly extract all the text (including html).
  - *
  - * ------------------------------------------------------------------------- */
   
  +/**
  + * This method is responsible for allowing
  + * all non-grammar text to pass through
  + * unscathed.
  + */
   void Text() : {/*@bgen(jjtree) Text */
     ASTText jjtn000 = new ASTText(this, JJTTEXT);
     boolean jjtc000 = true;
  @@ -844,19 +967,22 @@
       try {
   /*@egen*/
       <TEXT>
  +|   <DOLLAR>
   |   <MONEY>
  -|   <EQUALS> 
  +|   <EQUALS>
  +|   <DOT>
   |   <QUOTE> 
   |   <STRING_LITERAL>
   |   <IN>
   |   <TRUE>
   |   <FALSE>
   |   <LPAREN>
  -|   <RPAREN>/*@bgen(jjtree)*/
  +|   <RPAREN>
  +|   <METHOD_BODY>/*@bgen(jjtree)*/
       } finally {
         if (jjtc000) {
           jjtree.closeNodeScope(jjtn000, true);
         }
       }
  -/*@egen*/
  +/*@egen*/  // Might be javascript.
   }
  
  
  
  1.5       +15 -4     jakarta-velocity/src/java/org/apache/velocity/parser/Parser.jjt
  
  Index: Parser.jjt
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/parser/Parser.jjt,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Parser.jjt	2000/08/28 08:58:10	1.4
  +++ Parser.jjt	2000/08/29 06:48:24	1.5
  @@ -115,7 +115,7 @@
    * what controls the generation of this class.
    *
    * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
  - * @version $Id: Parser.jjt,v 1.4 2000/08/28 08:58:10 jvanzyl Exp $
  + * @version $Id: Parser.jjt,v 1.5 2000/08/29 06:48:24 jvanzyl Exp $
    */
   public class Parser
   {
  @@ -225,6 +225,8 @@
   |   <QUOTE: "\"">
   |   <TRUE: "true">
   |   <FALSE: "false">
  +|   <DOLLAR: "$">
  +|   <DOT: ".">
   //|   <COMMA: ",">
   }
   
  @@ -245,10 +247,11 @@
   | <ALPHANUM_CHAR: [ "a"-"z", "A"-"Z", "0"-"9" ] >
   | <IDENTIFIER_CHAR: [ "a"-"z", "A"-"Z", "0"-"9","-" ] >
   | <IDENTIFIER: <ALPHA_CHAR> (<IDENTIFIER_CHAR>)* >
  -| <VARIABLE: "$" <ALPHA_CHAR> (<IDENTIFIER_CHAR>)* >
  -| <PROPERTY: "$" <ALPHA_CHAR> <IDENTIFIER> "." <IDENTIFIER> >
  +| <VARIABLE: "$" <IDENTIFIER> >
  +| <PROPERTY: "$" <IDENTIFIER> "." <IDENTIFIER> >
   | <METHOD_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "\"", ",", "$", "."] >
   | <METHOD: "$" <ALPHA_CHAR> ((<METHOD_CHAR>)* <LPAREN> (<METHOD_CHAR>)* <RPAREN>)+ >
  +| <METHOD_BODY: <IDENTIFIER> <LPAREN> (<METHOD_CHAR>)* <RPAREN> >
   }
   
   /*
  @@ -487,6 +490,11 @@
       "(" [ Parameter() ( "," Parameter() )* ] ")"
   }
   
  +void PropertyMethod() : {}
  +{
  +    <DOLLAR> (<IDENTIFIER> | <METHOD_BODY> [<DOT>])+
  +}
  +
   /**
    * This method corresponds to a method
    * reference in a Velocity template.
  @@ -703,8 +711,10 @@
   void Text() : {}
   {
       <TEXT>
  +|   <DOLLAR>
   |   <MONEY>
  -|   <EQUALS> 
  +|   <EQUALS>
  +|   <DOT>
   |   <QUOTE> 
   |   <STRING_LITERAL>
   |   <IN>
  @@ -712,4 +722,5 @@
   |   <FALSE>
   |   <LPAREN>
   |   <RPAREN>
  +|   <METHOD_BODY>  // Might be javascript.
   }
  
  
  
  1.3       +17 -11    jakarta-velocity/src/java/org/apache/velocity/parser/ParserConstants.java
  
  Index: ParserConstants.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/parser/ParserConstants.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ParserConstants.java	2000/08/27 22:18:09	1.2
  +++ ParserConstants.java	2000/08/29 06:48:25	1.3
  @@ -24,17 +24,20 @@
     int QUOTE = 23;
     int TRUE = 24;
     int FALSE = 25;
  -  int TEXT = 26;
  -  int ALPHA_CHAR = 27;
  -  int NUM_CHAR = 28;
  -  int MONEY = 29;
  -  int ALPHANUM_CHAR = 30;
  -  int IDENTIFIER_CHAR = 31;
  -  int IDENTIFIER = 32;
  -  int VARIABLE = 33;
  -  int PROPERTY = 34;
  -  int METHOD_CHAR = 35;
  -  int METHOD = 36;
  +  int DOLLAR = 26;
  +  int DOT = 27;
  +  int TEXT = 28;
  +  int ALPHA_CHAR = 29;
  +  int NUM_CHAR = 30;
  +  int MONEY = 31;
  +  int ALPHANUM_CHAR = 32;
  +  int IDENTIFIER_CHAR = 33;
  +  int IDENTIFIER = 34;
  +  int VARIABLE = 35;
  +  int PROPERTY = 36;
  +  int METHOD_CHAR = 37;
  +  int METHOD = 38;
  +  int METHOD_BODY = 39;
   
     int DEFAULT = 0;
   
  @@ -65,6 +68,8 @@
       "\"\\\"\"",
       "\"true\"",
       "\"false\"",
  +    "\"$\"",
  +    "\".\"",
       "<TEXT>",
       "<ALPHA_CHAR>",
       "<NUM_CHAR>",
  @@ -76,6 +81,7 @@
       "<PROPERTY>",
       "<METHOD_CHAR>",
       "<METHOD>",
  +    "<METHOD_BODY>",
       "\",\"",
     };
   
  
  
  
  1.4       +261 -202  jakarta-velocity/src/java/org/apache/velocity/parser/ParserTokenManager.java
  
  Index: ParserTokenManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/parser/ParserTokenManager.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ParserTokenManager.java	2000/08/27 22:18:10	1.3
  +++ ParserTokenManager.java	2000/08/29 06:48:25	1.4
  @@ -91,82 +91,84 @@
      switch (pos)
      {
         case 0:
  -         if ((active0 & 0x2000000000L) != 0L)
  -         {
  -            jjmatchedKind = 26;
  -            return 9;
  -         }
            if ((active0 & 0xff80L) != 0L)
            {
  -            jjmatchedKind = 26;
  +            jjmatchedKind = 28;
               return 0;
            }
            if ((active0 & 0x800000L) != 0L)
  -            return 33;
  +            return 36;
            if ((active0 & 0x3400000L) != 0L)
  +         {
  +            jjmatchedKind = 28;
  +            return 37;
  +         }
  +         if ((active0 & 0x10000000000L) != 0L)
            {
  -            jjmatchedKind = 26;
  -            return 34;
  +            jjmatchedKind = 28;
  +            return 9;
            }
  -         if ((active0 & 0x380020L) != 0L)
  +         if ((active0 & 0x4000000L) != 0L)
  +            return 23;
  +         if ((active0 & 0x8380020L) != 0L)
               return 9;
            return -1;
         case 1:
            if ((active0 & 0x400000L) != 0L)
  -            return 34;
  +            return 37;
            if ((active0 & 0xff80L) != 0L)
            {
  -            jjmatchedKind = 26;
  +            jjmatchedKind = 28;
               jjmatchedPos = 1;
               return 9;
            }
            if ((active0 & 0x3000000L) != 0L)
            {
  -            jjmatchedKind = 26;
  +            jjmatchedKind = 28;
               jjmatchedPos = 1;
  -            return 34;
  +            return 37;
            }
            return -1;
         case 2:
            if ((active0 & 0xfd80L) != 0L)
            {
  -            jjmatchedKind = 26;
  +            jjmatchedKind = 28;
               jjmatchedPos = 2;
               return 9;
            }
            if ((active0 & 0x3000000L) != 0L)
            {
  -            jjmatchedKind = 26;
  +            jjmatchedKind = 28;
               jjmatchedPos = 2;
  -            return 34;
  +            return 37;
            }
            if ((active0 & 0x200L) != 0L)
               return 9;
            return -1;
         case 3:
  -         if ((active0 & 0x1000000L) != 0L)
  -            return 34;
  -         if ((active0 & 0xad80L) != 0L)
  +         if ((active0 & 0x2000000L) != 0L)
            {
  -            jjmatchedKind = 26;
  +            jjmatchedKind = 28;
               jjmatchedPos = 3;
  -            return 9;
  +            return 37;
            }
  -         if ((active0 & 0x2000000L) != 0L)
  +         if ((active0 & 0x1000000L) != 0L)
  +            return 37;
  +         if ((active0 & 0xad80L) != 0L)
            {
  -            jjmatchedKind = 26;
  +            jjmatchedKind = 28;
               jjmatchedPos = 3;
  -            return 34;
  +            return 9;
            }
            if ((active0 & 0x5000L) != 0L)
               return 9;
            return -1;
         case 4:
            if ((active0 & 0x2000000L) != 0L)
  -            return 34;
  +            return 37;
            if ((active0 & 0x2980L) != 0L)
            {
  -            jjmatchedKind = 26;
  +            jjmatchedKind = 28;
               jjmatchedPos = 4;
               return 9;
            }
  @@ -176,7 +178,7 @@
         case 5:
            if ((active0 & 0x880L) != 0L)
            {
  -            jjmatchedKind = 26;
  +            jjmatchedKind = 28;
               jjmatchedPos = 5;
               return 9;
            }
  @@ -186,7 +188,7 @@
         case 6:
            if ((active0 & 0x880L) != 0L)
            {
  -            jjmatchedKind = 26;
  +            jjmatchedKind = 28;
               jjmatchedPos = 6;
               return 9;
            }
  @@ -220,15 +222,19 @@
         case 12:
            return jjStartNfaWithStates_0(0, 5, 9);
         case 34:
  -         return jjStartNfaWithStates_0(0, 23, 33);
  +         return jjStartNfaWithStates_0(0, 23, 36);
         case 35:
            return jjMoveStringLiteralDfa1_0(0xff80L);
  +      case 36:
  +         return jjStartNfaWithStates_0(0, 26, 23);
         case 40:
            return jjStopAtPos(0, 17);
         case 41:
            return jjStopAtPos(0, 18);
         case 44:
  -         return jjStartNfaWithStates_0(0, 26, 9);
  +         return jjStartNfaWithStates_0(0, 28, 9);
  +      case 46:
  +         return jjStartNfaWithStates_0(0, 27, 9);
         case 61:
            return jjStartNfaWithStates_0(0, 21, 9);
         case 102:
  @@ -264,7 +270,7 @@
            return jjMoveStringLiteralDfa2_0(active0, 0x280L);
         case 110:
            if ((active0 & 0x400000L) != 0L)
  -            return jjStartNfaWithStates_0(1, 22, 34);
  +            return jjStartNfaWithStates_0(1, 22, 37);
            break;
         case 112:
            return jjMoveStringLiteralDfa2_0(active0, 0x2100L);
  @@ -332,7 +338,7 @@
            if ((active0 & 0x4000L) != 0L)
               return jjStartNfaWithStates_0(3, 14, 9);
            else if ((active0 & 0x1000000L) != 0L)
  -            return jjStartNfaWithStates_0(3, 24, 34);
  +            return jjStartNfaWithStates_0(3, 24, 37);
            break;
         case 111:
            return jjMoveStringLiteralDfa4_0(active0, 0x8000L);
  @@ -366,7 +372,7 @@
            if ((active0 & 0x400L) != 0L)
               return jjStartNfaWithStates_0(4, 10, 9);
            else if ((active0 & 0x2000000L) != 0L)
  -            return jjStartNfaWithStates_0(4, 25, 34);
  +            return jjStartNfaWithStates_0(4, 25, 37);
            return jjMoveStringLiteralDfa5_0(active0, 0x800L);
         case 108:
            return jjMoveStringLiteralDfa5_0(active0, 0x80L);
  @@ -490,7 +496,7 @@
   {
      int[] nextStates;
      int startsAt = 0;
  -   jjnewStateCnt = 33;
  +   jjnewStateCnt = 36;
      int i = 1;
      jjstateSet[0] = startState;
      int j, kind = 0x7fffffff;
  @@ -505,7 +511,7 @@
            {
               switch(jjstateSet[--i])
               {
  -               case 33:
  +               case 36:
                     if ((0xfffffffbffffffffL & l) != 0L)
                        jjCheckNAddTwoStates(7, 8);
                     else if (curChar == 34)
  @@ -515,76 +521,94 @@
                     }
                     if ((0xfffffceeffffd9ffL & l) != 0L)
                     {
  -                     if (kind > 26)
  -                        kind = 26;
  -                     jjCheckNAdd(9);
  -                  }
  -                  break;
  -               case 0:
  -                  if ((0xfffffceeffffd9ffL & l) != 0L)
  -                  {
  -                     if (kind > 26)
  -                        kind = 26;
  -                     jjCheckNAdd(9);
  -                  }
  -                  if (curChar == 35)
  -                     jjCheckNAddStates(0, 2);
  -                  break;
  -               case 34:
  -                  if ((0xfffffceeffffd9ffL & l) != 0L)
  -                  {
  -                     if (kind > 26)
  -                        kind = 26;
  +                     if (kind > 28)
  +                        kind = 28;
                        jjCheckNAdd(9);
                     }
  -                  if ((0x3ff200000000000L & l) != 0L)
  -                  {
  -                     if (kind > 32)
  -                        kind = 32;
  -                     jjCheckNAdd(15);
  -                  }
                     break;
                  case 5:
                     if ((0xfffffceeffffd9ffL & l) != 0L)
                     {
  -                     if (kind > 26)
  -                        kind = 26;
  +                     if (kind > 28)
  +                        kind = 28;
                        jjCheckNAdd(9);
                     }
                     else if (curChar == 36)
                     {
  -                     if (kind > 29)
  -                        kind = 29;
  -                     jjCheckNAddStates(3, 7);
  +                     if (kind > 31)
  +                        kind = 31;
  +                     jjCheckNAddStates(0, 4);
                     }
                     if ((0x3ff501400000000L & l) != 0L)
                     {
  -                     if (kind > 35)
  -                        kind = 35;
  +                     if (kind > 37)
  +                        kind = 37;
                     }
                     else if (curChar == 35)
                        jjstateSet[jjnewStateCnt++] = 0;
                     if ((0x3ff200000000000L & l) != 0L)
                     {
  -                     if (kind > 31)
  -                        kind = 31;
  +                     if (kind > 33)
  +                        kind = 33;
                     }
                     else if (curChar == 34)
                        jjCheckNAddTwoStates(7, 8);
                     if ((0x3ff000000000000L & l) != 0L)
                     {
  +                     if (kind > 32)
  +                        kind = 32;
  +                  }
  +                  if ((0x3ff000000000000L & l) != 0L)
  +                  {
                        if (kind > 30)
                           kind = 30;
                     }
  +                  break;
  +               case 23:
                     if ((0x3ff000000000000L & l) != 0L)
                     {
  +                     if (kind > 31)
  +                        kind = 31;
  +                     jjCheckNAddStates(5, 7);
  +                  }
  +                  else if (curChar == 46)
  +                  {
  +                     if (kind > 31)
  +                        kind = 31;
  +                     jjCheckNAdd(22);
  +                  }
  +                  break;
  +               case 0:
  +                  if ((0xfffffceeffffd9ffL & l) != 0L)
  +                  {
                        if (kind > 28)
                           kind = 28;
  +                     jjCheckNAdd(9);
  +                  }
  +                  if (curChar == 35)
  +                     jjCheckNAddStates(8, 10);
  +                  break;
  +               case 37:
  +                  if ((0xfffffceeffffd9ffL & l) != 0L)
  +                  {
  +                     if (kind > 28)
  +                        kind = 28;
  +                     jjCheckNAdd(9);
  +                  }
  +                  else if (curChar == 40)
  +                     jjCheckNAddTwoStates(18, 19);
  +                  if ((0x3ff200000000000L & l) != 0L)
  +                     jjCheckNAddTwoStates(16, 17);
  +                  if ((0x3ff200000000000L & l) != 0L)
  +                  {
  +                     if (kind > 34)
  +                        kind = 34;
  +                     jjCheckNAdd(15);
                     }
                     break;
                  case 1:
                     if ((0xffffffffffffdbffL & l) != 0L)
  -                     jjCheckNAddStates(0, 2);
  +                     jjCheckNAddStates(8, 10);
                     break;
                  case 2:
                     if ((0x2400L & l) != 0L && kind > 6)
  @@ -613,101 +637,117 @@
                  case 9:
                     if ((0xfffffceeffffd9ffL & l) == 0L)
                        break;
  -                  if (kind > 26)
  -                     kind = 26;
  +                  if (kind > 28)
  +                     kind = 28;
                     jjCheckNAdd(9);
                     break;
                  case 10:
  -                  if ((0x3ff000000000000L & l) != 0L && kind > 28)
  -                     kind = 28;
  -                  break;
  -               case 11:
                     if ((0x3ff000000000000L & l) != 0L && kind > 30)
                        kind = 30;
                     break;
  +               case 11:
  +                  if ((0x3ff000000000000L & l) != 0L && kind > 32)
  +                     kind = 32;
  +                  break;
                  case 12:
  -                  if ((0x3ff200000000000L & l) != 0L && kind > 31)
  -                     kind = 31;
  +                  if ((0x3ff200000000000L & l) != 0L && kind > 33)
  +                     kind = 33;
                     break;
                  case 13:
  -                  if ((0x3ff501400000000L & l) != 0L && kind > 35)
  -                     kind = 35;
  +                  if ((0x3ff501400000000L & l) != 0L && kind > 37)
  +                     kind = 37;
                     break;
                  case 15:
                     if ((0x3ff200000000000L & l) == 0L)
                        break;
  -                  if (kind > 32)
  -                     kind = 32;
  +                  if (kind > 34)
  +                     kind = 34;
                     jjCheckNAdd(15);
                     break;
                  case 16:
  +                  if ((0x3ff200000000000L & l) != 0L)
  +                     jjCheckNAddTwoStates(16, 17);
  +                  break;
  +               case 17:
  +                  if (curChar == 40)
  +                     jjCheckNAddTwoStates(18, 19);
  +                  break;
  +               case 18:
  +                  if ((0x3ff501400000000L & l) != 0L)
  +                     jjCheckNAddTwoStates(18, 19);
  +                  break;
  +               case 19:
  +                  if (curChar == 41 && kind > 39)
  +                     kind = 39;
  +                  break;
  +               case 20:
                     if (curChar != 36)
                        break;
  -                  if (kind > 29)
  -                     kind = 29;
  -                  jjCheckNAddStates(3, 7);
  +                  if (kind > 31)
  +                     kind = 31;
  +                  jjCheckNAddStates(0, 4);
                     break;
  -               case 17:
  +               case 21:
                     if (curChar != 46)
                        break;
  -                  if (kind > 29)
  -                     kind = 29;
  -                  jjCheckNAdd(18);
  +                  if (kind > 31)
  +                     kind = 31;
  +                  jjCheckNAdd(22);
                     break;
  -               case 18:
  +               case 22:
                     if ((0x3ff000000000000L & l) == 0L)
                        break;
  -                  if (kind > 29)
  -                     kind = 29;
  -                  jjCheckNAdd(18);
  +                  if (kind > 31)
  +                     kind = 31;
  +                  jjCheckNAdd(22);
                     break;
  -               case 20:
  +               case 24:
                     if ((0x3ff200000000000L & l) == 0L)
                        break;
  -                  if (kind > 33)
  -                     kind = 33;
  -                  jjstateSet[jjnewStateCnt++] = 20;
  +                  if (kind > 35)
  +                     kind = 35;
  +                  jjstateSet[jjnewStateCnt++] = 24;
                     break;
  -               case 23:
  +               case 26:
                     if ((0x3ff200000000000L & l) != 0L)
  -                     jjAddStates(8, 9);
  +                     jjAddStates(11, 12);
                     break;
  -               case 24:
  +               case 27:
                     if (curChar == 46)
  -                     jjstateSet[jjnewStateCnt++] = 25;
  +                     jjstateSet[jjnewStateCnt++] = 28;
                     break;
  -               case 26:
  +               case 29:
                     if ((0x3ff200000000000L & l) == 0L)
                        break;
  -                  if (kind > 34)
  -                     kind = 34;
  -                  jjstateSet[jjnewStateCnt++] = 26;
  +                  if (kind > 36)
  +                     kind = 36;
  +                  jjstateSet[jjnewStateCnt++] = 29;
                     break;
  -               case 28:
  +               case 31:
                     if ((0x3ff501400000000L & l) != 0L)
  -                     jjCheckNAddTwoStates(28, 29);
  +                     jjCheckNAddTwoStates(31, 32);
                     break;
  -               case 29:
  +               case 32:
                     if (curChar == 40)
  -                     jjCheckNAddTwoStates(30, 31);
  +                     jjCheckNAddTwoStates(33, 34);
                     break;
  -               case 30:
  +               case 33:
                     if ((0x3ff501400000000L & l) != 0L)
  -                     jjCheckNAddTwoStates(30, 31);
  +                     jjCheckNAddTwoStates(33, 34);
                     break;
  -               case 31:
  +               case 34:
                     if (curChar != 41)
                        break;
  -                  if (kind > 36)
  -                     kind = 36;
  -                  jjCheckNAddTwoStates(28, 29);
  +                  if (kind > 38)
  +                     kind = 38;
  +                  jjCheckNAddTwoStates(31, 32);
                     break;
  -               case 32:
  +               case 35:
                     if ((0x3ff000000000000L & l) == 0L)
                        break;
  -                  if (kind > 29)
  -                     kind = 29;
  -                  jjCheckNAddStates(10, 12);
  +                  if (kind > 31)
  +                     kind = 31;
  +                  jjCheckNAddStates(5, 7);
                     break;
                  default : break;
               }
  @@ -720,120 +760,137 @@
            {
               switch(jjstateSet[--i])
               {
  -               case 33:
  -                  if (kind > 26)
  -                     kind = 26;
  +               case 36:
  +                  if (kind > 28)
  +                     kind = 28;
                     jjCheckNAdd(9);
                     jjCheckNAddTwoStates(7, 8);
  -                  break;
  -               case 0:
  -               case 9:
  -                  if (kind > 26)
  -                     kind = 26;
  -                  jjCheckNAdd(9);
                     break;
  -               case 34:
  -                  if (kind > 26)
  -                     kind = 26;
  +               case 5:
  +                  if (kind > 28)
  +                     kind = 28;
                     jjCheckNAdd(9);
                     if ((0x7fffffe07fffffeL & l) != 0L)
                     {
  +                     if (kind > 29)
  +                        kind = 29;
  +                     jjCheckNAddStates(13, 15);
  +                  }
  +                  if ((0x7fffffe07fffffeL & l) != 0L)
  +                  {
  +                     if (kind > 37)
  +                        kind = 37;
  +                  }
  +                  if ((0x7fffffe07fffffeL & l) != 0L)
  +                  {
  +                     if (kind > 33)
  +                        kind = 33;
  +                  }
  +                  if ((0x7fffffe07fffffeL & l) != 0L)
  +                  {
                        if (kind > 32)
                           kind = 32;
  -                     jjCheckNAdd(15);
                     }
                     break;
  -               case 5:
  -                  if (kind > 26)
  -                     kind = 26;
  -                  jjCheckNAdd(9);
  +               case 23:
                     if ((0x7fffffe07fffffeL & l) != 0L)
  -                  {
  -                     if (kind > 27)
  -                        kind = 27;
  -                     jjCheckNAdd(15);
  -                  }
  +                     jjCheckNAddTwoStates(31, 32);
                     if ((0x7fffffe07fffffeL & l) != 0L)
  +                     jjCheckNAddTwoStates(26, 27);
  +                  if ((0x7fffffe07fffffeL & l) != 0L)
                     {
                        if (kind > 35)
                           kind = 35;
  +                     jjCheckNAdd(24);
                     }
  +                  break;
  +               case 0:
  +               case 9:
  +                  if (kind > 28)
  +                     kind = 28;
  +                  jjCheckNAdd(9);
  +                  break;
  +               case 37:
  +                  if (kind > 28)
  +                     kind = 28;
  +                  jjCheckNAdd(9);
                     if ((0x7fffffe07fffffeL & l) != 0L)
  -                  {
  -                     if (kind > 31)
  -                        kind = 31;
  -                  }
  +                     jjCheckNAddTwoStates(16, 17);
                     if ((0x7fffffe07fffffeL & l) != 0L)
                     {
  -                     if (kind > 30)
  -                        kind = 30;
  +                     if (kind > 34)
  +                        kind = 34;
  +                     jjCheckNAdd(15);
                     }
                     break;
                  case 1:
  -                  jjAddStates(0, 2);
  +                  jjAddStates(8, 10);
                     break;
                  case 7:
                     jjCheckNAddTwoStates(7, 8);
                     break;
                  case 11:
  -                  if ((0x7fffffe07fffffeL & l) != 0L && kind > 30)
  -                     kind = 30;
  +                  if ((0x7fffffe07fffffeL & l) != 0L && kind > 32)
  +                     kind = 32;
                     break;
                  case 12:
  -                  if ((0x7fffffe07fffffeL & l) != 0L && kind > 31)
  -                     kind = 31;
  +                  if ((0x7fffffe07fffffeL & l) != 0L && kind > 33)
  +                     kind = 33;
                     break;
                  case 13:
  -                  if ((0x7fffffe07fffffeL & l) != 0L && kind > 35)
  -                     kind = 35;
  +                  if ((0x7fffffe07fffffeL & l) != 0L && kind > 37)
  +                     kind = 37;
                     break;
                  case 14:
                     if ((0x7fffffe07fffffeL & l) == 0L)
                        break;
  -                  if (kind > 27)
  -                     kind = 27;
  -                  jjCheckNAdd(15);
  +                  if (kind > 29)
  +                     kind = 29;
  +                  jjCheckNAddStates(13, 15);
                     break;
                  case 15:
                     if ((0x7fffffe07fffffeL & l) == 0L)
                        break;
  -                  if (kind > 32)
  -                     kind = 32;
  +                  if (kind > 34)
  +                     kind = 34;
                     jjCheckNAdd(15);
                     break;
  -               case 19:
  -               case 20:
  -                  if ((0x7fffffe07fffffeL & l) == 0L)
  -                     break;
  -                  if (kind > 33)
  -                     kind = 33;
  -                  jjCheckNAdd(20);
  -                  break;
  -               case 21:
  +               case 16:
                     if ((0x7fffffe07fffffeL & l) != 0L)
  -                     jjstateSet[jjnewStateCnt++] = 22;
  +                     jjCheckNAddTwoStates(16, 17);
                     break;
  -               case 22:
  -               case 23:
  +               case 18:
                     if ((0x7fffffe07fffffeL & l) != 0L)
  -                     jjCheckNAddTwoStates(23, 24);
  +                     jjAddStates(16, 17);
                     break;
  +               case 24:
  +                  if ((0x7fffffe07fffffeL & l) == 0L)
  +                     break;
  +                  if (kind > 35)
  +                     kind = 35;
  +                  jjCheckNAdd(24);
  +                  break;
                  case 25:
                  case 26:
  +                  if ((0x7fffffe07fffffeL & l) != 0L)
  +                     jjCheckNAddTwoStates(26, 27);
  +                  break;
  +               case 28:
  +               case 29:
                     if ((0x7fffffe07fffffeL & l) == 0L)
                        break;
  -                  if (kind > 34)
  -                     kind = 34;
  -                  jjCheckNAdd(26);
  +                  if (kind > 36)
  +                     kind = 36;
  +                  jjCheckNAdd(29);
                     break;
  -               case 27:
  -               case 28:
  +               case 30:
  +               case 31:
                     if ((0x7fffffe07fffffeL & l) != 0L)
  -                     jjCheckNAddTwoStates(28, 29);
  +                     jjCheckNAddTwoStates(31, 32);
                     break;
  -               case 30:
  +               case 33:
                     if ((0x7fffffe07fffffeL & l) != 0L)
  -                     jjAddStates(13, 14);
  +                     jjAddStates(18, 19);
                     break;
                  default : break;
               }
  @@ -847,41 +904,41 @@
            {
               switch(jjstateSet[--i])
               {
  -               case 33:
  +               case 36:
                     if ((jjbitVec0[i2] & l2) != 0L)
                        jjCheckNAddTwoStates(7, 8);
                     if ((jjbitVec0[i2] & l2) != 0L)
                     {
  -                     if (kind > 26)
  -                        kind = 26;
  +                     if (kind > 28)
  +                        kind = 28;
                        jjCheckNAdd(9);
                     }
                     break;
  -               case 0:
  +               case 5:
                  case 9:
                     if ((jjbitVec0[i2] & l2) == 0L)
                        break;
  -                  if (kind > 26)
  -                     kind = 26;
  +                  if (kind > 28)
  +                     kind = 28;
                     jjCheckNAdd(9);
                     break;
  -               case 34:
  +               case 0:
                     if ((jjbitVec0[i2] & l2) == 0L)
                        break;
  -                  if (kind > 26)
  -                     kind = 26;
  +                  if (kind > 28)
  +                     kind = 28;
                     jjCheckNAdd(9);
                     break;
  -               case 5:
  +               case 37:
                     if ((jjbitVec0[i2] & l2) == 0L)
                        break;
  -                  if (kind > 26)
  -                     kind = 26;
  +                  if (kind > 28)
  +                     kind = 28;
                     jjCheckNAdd(9);
                     break;
                  case 1:
                     if ((jjbitVec0[i2] & l2) != 0L)
  -                     jjAddStates(0, 2);
  +                     jjAddStates(8, 10);
                     break;
                  case 7:
                     if ((jjbitVec0[i2] & l2) != 0L)
  @@ -898,26 +955,28 @@
            kind = 0x7fffffff;
         }
         ++curPos;
  -      if ((i = jjnewStateCnt) == (startsAt = 33 - (jjnewStateCnt = startsAt)))
  +      if ((i = jjnewStateCnt) == (startsAt = 36 - (jjnewStateCnt = startsAt)))
            return curPos;
         try { curChar = input_stream.readChar(); }
         catch(java.io.IOException e) { return curPos; }
      }
   }
   static final int[] jjnextStates = {
  -   1, 2, 4, 17, 19, 21, 27, 32, 23, 24, 17, 18, 32, 30, 31, 
  +   21, 23, 25, 30, 35, 21, 22, 35, 1, 2, 4, 26, 27, 15, 16, 17, 
  +   18, 19, 33, 34, 
   };
   public static final String[] jjstrLiteralImages = {
   "", null, null, null, null, null, null, "\43\151\156\143\154\165\144\145", 
   "\43\160\141\162\163\145", "\43\151\146", "\43\145\154\163\145", "\43\146\157\162\145\141\143\150", 
   "\43\163\145\164", "\43\160\141\162\141\155", "\43\165\163\145", "\43\163\164\157\160", null, 
   "\50", "\51", "\173", "\175", "\75", "\151\156", "\42", "\164\162\165\145", 
  -"\146\141\154\163\145", null, null, null, null, null, null, null, null, null, null, null, "\54", };
  +"\146\141\154\163\145", "\44", "\56", null, null, null, null, null, null, null, null, null, null, null, 
  +null, "\54", };
   public static final String[] lexStateNames = {
      "DEFAULT", 
   };
   static final long[] jjtoToken = {
  -   0x3fffffff81L, 
  +   0x1ffffffff81L, 
   };
   static final long[] jjtoSkip = {
      0x7eL, 
  @@ -926,8 +985,8 @@
      0x40L, 
   };
   private ASCII_CharStream input_stream;
  -private final int[] jjrounds = new int[33];
  -private final int[] jjstateSet = new int[66];
  +private final int[] jjrounds = new int[36];
  +private final int[] jjstateSet = new int[72];
   StringBuffer image;
   int jjimageLen;
   int lengthOfMatch;
  @@ -954,7 +1013,7 @@
   {
      int i;
      jjround = 0x80000001;
  -   for (i = 33; i-- > 0;)
  +   for (i = 36; i-- > 0;)
         jjrounds[i] = 0x80000000;
   }
   public void ReInit(ASCII_CharStream stream, int lexState)
  
  
  
  1.2       +11 -9     jakarta-velocity/src/java/org/apache/velocity/parser/ParserTreeConstants.java
  
  Index: ParserTreeConstants.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/parser/ParserTreeConstants.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ParserTreeConstants.java	2000/08/24 21:42:48	1.1
  +++ ParserTreeConstants.java	2000/08/29 06:48:25	1.2
  @@ -10,15 +10,16 @@
     public int JJTPROPERTY = 3;
     public int JJTPARAMETER = 4;
     public int JJTPARAMETERS = 5;
  -  public int JJTMETHOD = 6;
  -  public int JJTEXPRESSION = 7;
  -  public int JJTBLOCK = 8;
  -  public int JJTIFSTATEMENT = 9;
  -  public int JJTFOREACHSTATEMENT = 10;
  -  public int JJTSETSTATEMENT = 11;
  -  public int JJTUSESTATEMENT = 12;
  -  public int JJTPARAMSTATEMENT = 13;
  -  public int JJTTEXT = 14;
  +  public int JJTPROPERTYMETHOD = 6;
  +  public int JJTMETHOD = 7;
  +  public int JJTEXPRESSION = 8;
  +  public int JJTBLOCK = 9;
  +  public int JJTIFSTATEMENT = 10;
  +  public int JJTFOREACHSTATEMENT = 11;
  +  public int JJTSETSTATEMENT = 12;
  +  public int JJTUSESTATEMENT = 13;
  +  public int JJTPARAMSTATEMENT = 14;
  +  public int JJTTEXT = 15;
   
   
     public String[] jjtNodeName = {
  @@ -28,6 +29,7 @@
       "Property",
       "Parameter",
       "Parameters",
  +    "PropertyMethod",
       "Method",
       "Expression",
       "Block",
  
  
  
  1.2       +1 -0      jakarta-velocity/src/java/org/apache/velocity/parser/ParserVisitor.java
  
  Index: ParserVisitor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/parser/ParserVisitor.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ParserVisitor.java	2000/08/24 21:42:48	1.1
  +++ ParserVisitor.java	2000/08/29 06:48:25	1.2
  @@ -10,6 +10,7 @@
     public Object visit(ASTProperty node, Object data);
     public Object visit(ASTParameter node, Object data);
     public Object visit(ASTParameters node, Object data);
  +  public Object visit(ASTPropertyMethod node, Object data);
     public Object visit(ASTMethod node, Object data);
     public Object visit(ASTExpression node, Object data);
     public Object visit(ASTBlock node, Object data);
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/parser/ASTPropertyMethod.java
  
  Index: ASTPropertyMethod.java
  ===================================================================
  /* Generated By:JJTree: Do not edit this line. ASTPropertyMethod.java */
  
  package org.apache.velocity.parser;
  
  public class ASTPropertyMethod extends SimpleNode {
    public ASTPropertyMethod(int id) {
      super(id);
    }
  
    public ASTPropertyMethod(Parser p, int id) {
      super(p, id);
    }
  
  
    /** Accept the visitor. **/
    public Object jjtAccept(ParserVisitor visitor, Object data) {
      return visitor.visit(this, data);
    }
  }