geirm       00/11/01 19:53:57

  Modified:    src/java/org/apache/velocity/runtime/parser Parser.java
                        Parser.jj ParserTokenManager.java
  Log:
  The generated companions to Parser.jjt (for the "#000000" fix )
  
  Revision  Changes    Path
  1.16      +161 -149  
jakarta-velocity/src/java/org/apache/velocity/runtime/parser/Parser.java
  
  Index: Parser.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/parser/Parser.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- Parser.java       2000/11/02 01:25:19     1.15
  +++ Parser.java       2000/11/02 03:53:55     1.16
  @@ -18,7 +18,7 @@
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
    * @author <a href="mailto:[EMAIL PROTECTED]">Geir Magnusson Jr.</a>
  - * @version $Id: Parser.java,v 1.15 2000/11/02 01:25:19 geirm Exp $ 
  + * @version $Id: Parser.java,v 1.16 2000/11/02 03:53:55 geirm Exp $ 
   */
   public class Parser/*@bgen(jjtree)*/implements ParserTreeConstants, ParserConstants 
{/*@bgen(jjtree)*/
     protected JJTParserState jjtree = new JJTParserState();
  @@ -57,7 +57,16 @@
       {
           token_source.clearStateVars();
           ReInit(stream);
  -        return process();
  +
  +       // return process();
  +
  +        SimpleNode n = null;
  +
  +        try {
  +            n = process();
  +        } catch (Exception e ) { System.out.println( e ); }
  +
  +        return n;
       }
   
       public void setDirectives(Hashtable directives)
  @@ -148,18 +157,9 @@
       throw new Error("Missing return statement in function");
     }
   
  -// -----------------------------------------------------------------------
  -// 
  -// Statement Syntax
  -// 
  -// -----------------------------------------------------------------------
  -
   /**
    * 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) {
  @@ -299,6 +299,10 @@
       }
     }
   
  +/**
  + *   Supports the arguments for the Pluggable Directives
  + *   @see Directive()
  + */
     final public void DirectiveArg() throws ParseException {
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
       case IDENTIFIER:
  @@ -324,6 +328,10 @@
       }
     }
   
  +/**
  + *   Supports the Pluggable Directives
  + *     #foo( arg+ )
  + */
     final public SimpleNode Directive() throws ParseException {
    /*@bgen(jjtree) Directive */
       ASTDirective jjtn000 = new ASTDirective(this, JJTDIRECTIVE);
  @@ -331,7 +339,11 @@
       jjtree.openNodeScope(jjtn000);Token t;
       Directive d;
       try {
  -      t = jj_consume_token(WORD);
  +      /*
  +           *  Get the directive identifier and check to see if this is a directive.
  +           *   Note that because '#' is a <MORE> token, the identifier is preceeded 
by the '#'
  +           */
  +          t = jj_consume_token(WORD);
           d = (Directive) directives.get(t.image.substring(1));
   
           if (d == null)
  @@ -738,11 +750,11 @@
       }
     }
   
  -// -----------------------------------------------------------------------
  -// 
  -// Directive Syntax
  -// 
  -// -----------------------------------------------------------------------
  +/* -----------------------------------------------------------------------
  + * 
  + *  Defined Directive Syntax
  + * 
  + * ----------------------------------------------------------------------*/
     final public void IfStatement() throws ParseException {
                         /*@bgen(jjtree) IfStatement */
     ASTIfStatement jjtn000 = new ASTIfStatement(this, JJTIFSTATEMENT);
  @@ -1072,18 +1084,18 @@
    * 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
  + * is useful for end-user debugging
    * purposes.
    */
     final public void StopStatement() throws ParseException {
       jj_consume_token(STOP_DIRECTIVE);
     }
   
  -// -----------------------------------------------------------------------
  -// 
  -// Expression Syntax
  -// 
  -// -----------------------------------------------------------------------
  +/* -----------------------------------------------------------------------
  + * 
  + *  Expression Syntax
  + * 
  + * ----------------------------------------------------------------------*/
     final public void Expression() throws ParseException {
                        /*@bgen(jjtree) Expression */
     ASTExpression jjtn000 = new ASTExpression(this, JJTEXPRESSION);
  @@ -1730,105 +1742,26 @@
       return retval;
     }
   
  -  final private boolean jj_3R_61() {
  -    if (jj_scan_token(LOGICAL_NOT_EQUALS)) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    if (jj_3R_56()) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    return false;
  -  }
  -
  -  final private boolean jj_3R_56() {
  -    if (jj_3R_58()) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    Token xsp;
  -    while (true) {
  -      xsp = jj_scanpos;
  -      if (jj_3R_59()) { jj_scanpos = xsp; break; }
  -      if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    }
  -    return false;
  -  }
  -
  -  final private boolean jj_3R_60() {
  -    if (jj_scan_token(LOGICAL_EQUALS)) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    if (jj_3R_56()) return true;
  +  final private boolean jj_3R_52() {
  +    if (jj_scan_token(LOGICAL_OR)) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    return false;
  -  }
  -
  -  final private boolean jj_3R_57() {
  -    Token xsp;
  -    xsp = jj_scanpos;
  -    if (jj_3R_60()) {
  -    jj_scanpos = xsp;
  -    if (jj_3R_61()) return true;
  +    if (jj_3R_51()) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
       return false;
     }
   
  -  final private boolean jj_3R_55() {
  -    if (jj_scan_token(COMMA)) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +  final private boolean jj_3R_21() {
       if (jj_3R_29()) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    return false;
  -  }
  -
  -  final private boolean jj_3R_53() {
  -    if (jj_3R_56()) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
       Token xsp;
       while (true) {
         xsp = jj_scanpos;
  -      if (jj_3R_57()) { jj_scanpos = xsp; break; }
  -      if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    }
  -    return false;
  -  }
  -
  -  final private boolean jj_3R_54() {
  -    if (jj_scan_token(LOGICAL_AND)) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    if (jj_3R_53()) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    return false;
  -  }
  -
  -  final private boolean jj_3_2() {
  -    if (jj_3R_18()) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    return false;
  -  }
  -
  -  final private boolean jj_3R_51() {
  -    if (jj_3R_53()) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    Token xsp;
  -    while (true) {
  -      xsp = jj_scanpos;
  -      if (jj_3R_54()) { jj_scanpos = xsp; break; }
  +      if (jj_3R_55()) { jj_scanpos = xsp; break; }
         if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
       }
       return false;
     }
   
  -  final private boolean jj_3R_20() {
  -    if (jj_scan_token(IDENTIFIER)) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    return false;
  -  }
  -
  -  final private boolean jj_3R_52() {
  -    if (jj_scan_token(LOGICAL_OR)) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    if (jj_3R_51()) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    return false;
  -  }
  -
     final private boolean jj_3_3() {
       if (jj_3R_19()) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  @@ -1837,18 +1770,6 @@
       return false;
     }
   
  -  final private boolean jj_3R_21() {
  -    if (jj_3R_29()) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    Token xsp;
  -    while (true) {
  -      xsp = jj_scanpos;
  -      if (jj_3R_55()) { jj_scanpos = xsp; break; }
  -      if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    }
  -    return false;
  -  }
  -
     final private boolean jj_3R_50() {
       if (jj_3R_51()) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  @@ -1928,20 +1849,14 @@
       return false;
     }
   
  -  final private boolean jj_3R_30() {
  -    if (jj_scan_token(STRING_LITERAL)) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    return false;
  -  }
  -
     final private boolean jj_3R_42() {
       if (jj_scan_token(LCURLY)) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
       return false;
     }
   
  -  final private boolean jj_3R_31() {
  -    if (jj_scan_token(NUMBER_LITERAL)) return true;
  +  final private boolean jj_3R_20() {
  +    if (jj_scan_token(IDENTIFIER)) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
       return false;
     }
  @@ -1986,6 +1901,12 @@
       return false;
     }
   
  +  final private boolean jj_3R_30() {
  +    if (jj_scan_token(STRING_LITERAL)) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
     final private boolean jj_3R_41() {
       if (jj_3R_32()) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  @@ -2016,6 +1937,12 @@
       return false;
     }
   
  +  final private boolean jj_3R_38() {
  +    if (jj_3R_33()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
     final private boolean jj_3R_28() {
       if (jj_scan_token(LPAREN)) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  @@ -2026,20 +1953,14 @@
       return false;
     }
   
  -  final private boolean jj_3R_38() {
  -    if (jj_3R_33()) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    return false;
  -  }
  -
  -  final private boolean jj_3R_27() {
  -    if (jj_3R_35()) return true;
  +  final private boolean jj_3R_37() {
  +    if (jj_3R_30()) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
       return false;
     }
   
  -  final private boolean jj_3R_37() {
  -    if (jj_3R_30()) return true;
  +  final private boolean jj_3R_31() {
  +    if (jj_scan_token(NUMBER_LITERAL)) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
       return false;
     }
  @@ -2064,6 +1985,12 @@
       return false;
     }
   
  +  final private boolean jj_3R_27() {
  +    if (jj_3R_35()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
     final private boolean jj_3R_26() {
       if (jj_3R_34()) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  @@ -2126,6 +2053,18 @@
       return false;
     }
   
  +  final private boolean jj_3R_33() {
  +    if (jj_scan_token(LBRACKET)) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    Token xsp;
  +    xsp = jj_scanpos;
  +    if (jj_3R_44()) jj_scanpos = xsp;
  +    else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    if (jj_scan_token(RBRACKET)) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
     final private boolean jj_3R_76() {
       if (jj_scan_token(MODULUS)) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  @@ -2153,18 +2092,6 @@
       return false;
     }
   
  -  final private boolean jj_3R_33() {
  -    if (jj_scan_token(LBRACKET)) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    Token xsp;
  -    xsp = jj_scanpos;
  -    if (jj_3R_44()) jj_scanpos = xsp;
  -    else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    if (jj_scan_token(RBRACKET)) return true;
  -    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  -    return false;
  -  }
  -
     final private boolean jj_3R_75() {
       if (jj_scan_token(DIVIDE)) return true;
       if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  @@ -2304,6 +2231,91 @@
       } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
       } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
       } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
  +  final private boolean jj_3R_61() {
  +    if (jj_scan_token(LOGICAL_NOT_EQUALS)) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    if (jj_3R_56()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
  +  final private boolean jj_3R_56() {
  +    if (jj_3R_58()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    Token xsp;
  +    while (true) {
  +      xsp = jj_scanpos;
  +      if (jj_3R_59()) { jj_scanpos = xsp; break; }
  +      if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    }
  +    return false;
  +  }
  +
  +  final private boolean jj_3R_60() {
  +    if (jj_scan_token(LOGICAL_EQUALS)) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    if (jj_3R_56()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
  +  final private boolean jj_3R_57() {
  +    Token xsp;
  +    xsp = jj_scanpos;
  +    if (jj_3R_60()) {
  +    jj_scanpos = xsp;
  +    if (jj_3R_61()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
  +  final private boolean jj_3R_55() {
  +    if (jj_scan_token(COMMA)) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    if (jj_3R_29()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
  +  final private boolean jj_3R_53() {
  +    if (jj_3R_56()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    Token xsp;
  +    while (true) {
  +      xsp = jj_scanpos;
  +      if (jj_3R_57()) { jj_scanpos = xsp; break; }
  +      if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    }
  +    return false;
  +  }
  +
  +  final private boolean jj_3R_54() {
  +    if (jj_scan_token(LOGICAL_AND)) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    if (jj_3R_53()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
  +  final private boolean jj_3_2() {
  +    if (jj_3R_18()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    return false;
  +  }
  +
  +  final private boolean jj_3R_51() {
  +    if (jj_3R_53()) return true;
  +    if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    Token xsp;
  +    while (true) {
  +      xsp = jj_scanpos;
  +      if (jj_3R_54()) { jj_scanpos = xsp; break; }
  +      if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
  +    }
       return false;
     }
   
  
  
  
  1.16      +131 -75   
jakarta-velocity/src/java/org/apache/velocity/runtime/parser/Parser.jj
  
  Index: Parser.jj
  ===================================================================
  RCS file: 
/home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/parser/Parser.jj,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- Parser.jj 2000/11/02 01:25:20     1.15
  +++ Parser.jj 2000/11/02 03:53:56     1.16
  @@ -54,24 +54,10 @@
    */
   
   /*
  - *  Background
  - *  ----------
  - *
  - *  VTL == Velocity Template Language
  - *
  - *  The problem with parsing VTL is that an input stream consists generally of 
little
  - *  bits of VTL mixed in with 'other stuff' (hereafter referred to as 'schmoo').  
Unlike
  - *  other languages, like C or Java, where the parser can punt whenever it 
encounters 
  - *  input that doesn't conform to the grammar, the VTL parser can't do that.  
  - *
  - *  There are a few things that we do here :
  - *    - define a set of parser states (DEFAULT, DIRECTIVE, REFERENCE, etc)
  - *    - define for each parser state a set of tokens for each state
  - *    - define the VTL grammar, expressed (mostly) in the productions such as 
Text(), SetStatement(), etc.
  - *  
  - *   (cont)
  + *  NOTE : please see documentation at bottom of this file. (It was placed there 
its tiring
  + *    to always have to page past it... :)
    */
  - 
  +
   options
   {                                                                                   
                                                                                       
                                                                                       
                                                                                       
                                                                                       
                                                                                       
                                                                                 
       
  @@ -117,7 +103,7 @@
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
    * @author <a href="mailto:[EMAIL PROTECTED]">Geir Magnusson Jr.</a>
  - * @version $Id: Parser.jj,v 1.15 2000/11/02 01:25:20 geirm Exp $ 
  + * @version $Id: Parser.jj,v 1.16 2000/11/02 03:53:56 geirm Exp $ 
   */
   public class Parser/*@bgen(jjtree)*/implements ParserTreeConstants/*@egen*/
   {/*@bgen(jjtree)*/
  @@ -160,7 +146,16 @@
       {
           token_source.clearStateVars();
           ReInit(stream);  
  -        return process();
  +    
  +       // return process();
  +
  +        SimpleNode n = null;
  +
  +        try {
  +            n = process();
  +        } catch (Exception e ) { System.out.println( e ); }
  +
  +        return n;
       }        
   
       public void setDirectives(Hashtable directives)
  @@ -449,12 +444,11 @@
               lparen++;
   
           /*
  -         *  if we have seen the dot, then move to REFMOD2 -> Modifier()
  +         *  if in REFERENCE and we have seen the dot, then move to REFMOD2 -> 
Modifier()
            */
   
           if (curLexState == REFMODIFIER )
  -            SwitchTo( REFMOD2 );
  -
  +            SwitchTo( REFMOD2 ); 
       }
   
   |   <RPAREN: ")" (" ")* ("\n")?>
  @@ -533,9 +527,8 @@
           SwitchTo( IN_MULTI_LINE_COMMENT ); 
       } 
   
  -
   |   <HASH : "#"> 
  -  { 
  +    { 
           if (! inComment)
           {
               inDirective = true;
  @@ -554,14 +547,12 @@
       <ESCAPE_SEQUENCE: "\\" ~[] >
   |   <TEXT: (~["$", "#", "\\"])+ >
   }    
  -
   
  -// -----------------------------------------------------------------------
  -// 
  -// COMMENT Lexical States
  -// 
  -// -----------------------------------------------------------------------
  -
  +/* -----------------------------------------------------------------------
  + * 
  + *   *_COMMENT Lexical tokens
  + *
  + *-----------------------------------------------------------------------*/
   <IN_SINGLE_LINE_COMMENT>
   TOKEN :
   {
  @@ -601,13 +592,12 @@
   {
     < ~[] >
   }
  -
  -// -----------------------------------------------------------------------
  -// 
  -// DIRECTIVE Lexical State
  -// 
  -// -----------------------------------------------------------------------
   
  +/* -----------------------------------------------------------------------
  + * 
  + *  DIRECTIVE Lexical State (some of it, anyway)
  + * 
  + * ---------------------------------------------------------------------- */
   <DIRECTIVE,REFMOD2> 
   SKIP:
   {
  @@ -617,6 +607,7 @@
   //|   "\r"
   }
   
  +
   <REFERENCE,DIRECTIVE,REFMODIFIER,REFMOD2>
   TOKEN :
   {
  @@ -670,6 +661,7 @@
       }        
   }    
   
  +
   <DIRECTIVE>
   TOKEN : 
   {
  @@ -700,7 +692,9 @@
       } 
   
   |   <INCLUDE_DIRECTIVE: "include"> 
  -    { incMode = true; }
  +    { 
  +        incMode = true; 
  +    }
   
   |   <IF_DIRECTIVE: "if">
   
  @@ -724,23 +718,41 @@
   |   <#DIGIT: [ "0"-"9" ] >
   |   <NUMBER_LITERAL: (<DIGIT>)+ >
       {
  -        //!!! fixed <bcolor="#333333"/>
  -        // needs to be more thorough.
  -       // if (lparen == 0)
  -       //     SwitchTo(DEFAULT);
  -    }            
  -    
  -    //!!! fixed #FFFFFF
  +        /*
  +         *  in the spirit of Jason's fix :)
  +         *  but check to see if we are in set
  +         *    ex.  #set $foo = $foo + 3
  +         *  because we want to handle the \n after
  +         */
  +
  +        if ( lparen == 0 && !inSet )
  +            stateStackPop();
  +    }
  +
   |   <#LETTER: [ "a"-"z", "A" - "Z" ] >
   |   <WORD: (<LETTER>)+ >
   }
  -
   
  -// -----------------------------------------------------------------------
  -// 
  -// REFERENCE Lexical State
  -// 
  -// -----------------------------------------------------------------------
  +/* -----------------------------------------------------------------------
  + * 
  + *  REFERENCE Lexical States
  + *
  + *  This is more than a single state, because of the  structure of
  + *  the VTL references.  We use three states because the set of tokens
  + *  for each state is different.
  + *
  + *  $foo.bar( "arg" )
  + *  ^   ^   ^
  + *  |   |   |
  + *  ----------- >  REFERENCE : state initiated by the '$' character.  Continues 
  + *      |   |       until end of the reference, or the . character.
  + *      |------ >  REFMODIFIER : state switched to when the <DOT> is encountered.
  + *          |       note that this is a switch, not a push. See notes at bottom
  + *          |       re stateStack.
  + *          |-- >  REFMOD2 : state switch to when the LPAREN is encountered.
  + *                  again, this is a switch, not a push.
  + *
  + * ---------------------------------------------------------------------------- */
   
   <REFERENCE,REFMODIFIER,REFMOD2> 
   TOKEN :
  @@ -771,7 +783,6 @@
   |   <LCURLY: "{">
   |   <RCURLY: "}">
       {
  -        // was :DEFAULT
           stateStackPop();
       }
   }
  @@ -859,23 +870,13 @@
   /*@egen*/
   }
   
  -// -----------------------------------------------------------------------
  -// 
  -// Statement Syntax
  -// 
  -// -----------------------------------------------------------------------
  -
   /**
    * 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()       : {}
   {
  -   IfStatement()
  +    IfStatement()
   |   IncludeStatement()
   |   StopStatement()
   |   Reference()
  @@ -983,6 +984,10 @@
   /*@egen*/
   }    
   
  +/**
  + *   Supports the arguments for the Pluggable Directives
  + *   @see Directive()
  + */
   void DirectiveArg()       : {}
   {
       Reference()
  @@ -992,6 +997,10 @@
   |   ObjectArray()
   }
   
  +/**
  + *   Supports the Pluggable Directives
  + *     #foo( arg+ )
  + */
   SimpleNode Directive() : 
   {/*@bgen(jjtree) Directive */
       ASTDirective jjtn000 = new ASTDirective(this, JJTDIRECTIVE);
  @@ -1004,6 +1013,10 @@
   {/*@bgen(jjtree) Directive */
       try {
   /*@egen*/
  +    /*
  +     *  Get the directive identifier and check to see if this is a directive.
  +     *   Note that because '#' is a <MORE> token, the identifier is preceeded by 
the '#'
  +     */
       t = <WORD>
       {
           d = (Directive) directives.get(t.image.substring(1));
  @@ -1016,6 +1029,10 @@
           }            
       }
   
  +    /*
  +     *  if this is indeed a token, match the #foo ( arg ) pattern
  +     */
  +
       <LPAREN> (DirectiveArg())+ <RPAREN>
       {
           if (d.getType() == Directive.LINE)
  @@ -1028,6 +1045,10 @@
       }
       try {
   /*@egen*/
  +
  +    /*
  +     *  and the following block if the PD needs it
  +     */
       
       ( Statement() )+/*@bgen(jjtree)*/
       } catch (Throwable jjte001) {
  @@ -1170,7 +1191,6 @@
   {/*@bgen(jjtree) Reference */
       try {
   /*@egen*/ 
  -
       // This should be changed to Indentifier() now. Make
       // it easier to walk the AST.
       [<LCURLY>]
  @@ -1274,11 +1294,11 @@
   
   }
   
  -// -----------------------------------------------------------------------
  -// 
  -// Directive Syntax
  -// 
  -// -----------------------------------------------------------------------
  +/* -----------------------------------------------------------------------
  + * 
  + *  Defined Directive Syntax
  + * 
  + * ----------------------------------------------------------------------*/
   
   void IfStatement() : {/*@bgen(jjtree) IfStatement */
     ASTIfStatement jjtn000 = new ASTIfStatement(this, JJTIFSTATEMENT);
  @@ -1510,7 +1530,7 @@
    * 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
  + * is useful for end-user debugging
    * purposes.
    */
   void StopStatement()      : {}
  @@ -1518,11 +1538,11 @@
       <STOP_DIRECTIVE>
   }
   
  -// -----------------------------------------------------------------------
  -// 
  -// Expression Syntax
  -// 
  -// -----------------------------------------------------------------------
  +/* -----------------------------------------------------------------------
  + * 
  + *  Expression Syntax
  + * 
  + * ----------------------------------------------------------------------*/
   
   void Expression() : {/*@bgen(jjtree) Expression */
     ASTExpression jjtn000 = new ASTExpression(this, JJTEXPRESSION);
  @@ -2033,3 +2053,39 @@
   |   False()
   |   <LPAREN> Expression() <RPAREN>
   }
  +
  +
  +/* ======================================================================
  + *
  + *  Background
  + *  ----------
  + *
  + *  VTL == Velocity Template Language
  + *
  + *  The problem with parsing VTL is that an input stream consists generally of 
little
  + *  bits of VTL mixed in with 'other stuff' (hereafter referred to as 'schmoo').  
Unlike
  + *  other languages, like C or Java, where the parser can punt whenever it 
encounters 
  + *  input that doesn't conform to the grammar, the VTL parser can't do that.  
  + *
  + *  There are a few things that we do here :
  + *    - define a set of parser states (DEFAULT, DIRECTIVE, REFERENCE, etc)
  + *    - define for each parser state a set of tokens for each state
  + *    - define the VTL grammar, expressed (mostly) in the productions such as 
Text(), SetStatement(), etc.
  + *  
  + *  It is clear that this expression of the VTL grammer (the contents of this .jjt 
file) is maturing and
  + *  evolving as we learn more about how to parse VTL ( and as I learn about 
parsing...), so in the event 
  + *  this documentation is in disagreement w/ the source, the source takes 
precedence.
  + *
  + *  Parser States
  + *  -------------
  + *  DEFAULT :  This is the base or starting state, and strangely enough, the 
default state.
  + *
  + *  DIRECTIVE : This state is triggered by the '#' character, and is used when 
processing both
  + *     'defined' directives such as #if() #else #elseif() #end #set #foreach() as 
well as the 
  + *     so-called 'pluggable' directives (PDs), which include #foreach(), #macro() 
etc.  The
  + *     PDs are able to be implemented entirely outside of the parser.
  + *      - with the exception of #set, #else and #else, the 'shape' of a directive 
is  
  + *           #foo( optional args )
  + *      - 
  + */
  + 
  \ No newline at end of file
  
  
  
  1.14      +17 -3     
jakarta-velocity/src/java/org/apache/velocity/runtime/parser/ParserTokenManager.java
  
  Index: ParserTokenManager.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/parser/ParserTokenManager.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ParserTokenManager.java   2000/11/01 23:15:57     1.13
  +++ ParserTokenManager.java   2000/11/02 03:53:56     1.14
  @@ -2833,7 +2833,7 @@
               lparen++;
   
           /*
  -         *  if we have seen the dot, then move to REFMOD2 -> Modifier()
  +         *  if in REFERENCE and we have seen the dot, then move to REFMOD2 -> 
Modifier()
            */
   
           if (curLexState == REFMODIFIER )
  @@ -2934,7 +2934,7 @@
               image = new StringBuffer(new String(input_stream.GetSuffix(jjimageLen + 
(lengthOfMatch = jjmatchedPos + 1))));
            else
               image.append(new String(input_stream.GetSuffix(jjimageLen + 
(lengthOfMatch = jjmatchedPos + 1))));
  -      incMode = true;
  +        incMode = true;
            break;
         case 44 :
           if (image == null)
  @@ -2959,6 +2959,21 @@
           matchedToken.kind = EOF;
           fileDepth = 0;
            break;
  +      case 48 :
  +        if (image == null)
  +            image = new StringBuffer(new String(input_stream.GetSuffix(jjimageLen + 
(lengthOfMatch = jjmatchedPos + 1))));
  +         else
  +            image.append(new String(input_stream.GetSuffix(jjimageLen + 
(lengthOfMatch = jjmatchedPos + 1))));
  +        /*
  +         *  in the spirit of Jason's fix :)
  +         *  but check to see if we are in set
  +         *    ex.  #set $foo = $foo + 3
  +         *  because we want to handle the \n after
  +         */
  +
  +        if ( lparen == 0 && !inSet )
  +            stateStackPop();
  +         break;
         case 55 :
           if (image == null)
               image = new StringBuffer(new String(input_stream.GetSuffix(jjimageLen + 
(lengthOfMatch = jjmatchedPos + 1))));
  @@ -2985,7 +3000,6 @@
               image = new StringBuffer(new String(input_stream.GetSuffix(jjimageLen + 
(lengthOfMatch = jjmatchedPos + 1))));
            else
               image.append(new String(input_stream.GetSuffix(jjimageLen + 
(lengthOfMatch = jjmatchedPos + 1))));
  -        // was :DEFAULT
           stateStackPop();
            break;
         default : 
  
  
  

Reply via email to