You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by ge...@apache.org on 2002/03/23 14:38:32 UTC

cvs commit: jakarta-velocity/src/java/org/apache/velocity/runtime/parser/node ASTEscape.java

geirm       02/03/23 05:38:32

  Modified:    src/java/org/apache/velocity/runtime/parser Parser.java
                        Parser.jj Parser.jjt ParserTokenManager.java
               src/java/org/apache/velocity/runtime/parser/node
                        ASTEscape.java
  Log:
  Fix for bug #7380, where \\\\\\\\\\\ wasn't correctly rendered
  
  Revision  Changes    Path
  1.71      +18 -18    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.70
  retrieving revision 1.71
  diff -u -r1.70 -r1.71
  --- Parser.java	22 Feb 2002 21:40:38 -0000	1.70
  +++ Parser.java	23 Mar 2002 13:38:31 -0000	1.71
  @@ -21,7 +21,7 @@
    *
    * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: Parser.java,v 1.70 2002/02/22 21:40:38 geirm Exp $ 
  + * @version $Id: Parser.java,v 1.71 2002/03/23 13:38:31 geirm Exp $
   */
   public class Parser/*@bgen(jjtree)*/implements ParserTreeConstants, ParserConstants {/*@bgen(jjtree)*/
     protected JJTParserState jjtree = new JJTParserState();/**
  @@ -38,9 +38,9 @@
   
       private RuntimeServices rsvc = null;
   
  -    /** 
  +    /**
        * This constructor was added to allow the re-use of parsers.
  -     * The normal constructor takes a single argument which 
  +     * The normal constructor takes a single argument which
        * an InputStream. This simply creates a re-usable parser
        * object, we satisfy the requirement of an InputStream
        * by using a newline character as an input stream.
  @@ -66,7 +66,7 @@
           rsvc = rs;
       }
   
  -    /** 
  +    /**
        * This was also added to allow parsers to be
        * re-usable. Normal JavaCC use entails passing an
        * input stream to the constructor and the parsing
  @@ -139,7 +139,7 @@
       }
   
       /**
  -     *  This method finds out of the directive exists in the directives 
  +     *  This method finds out of the directive exists in the directives
        *  Hashtable.
        */
       public boolean isDirective(String directive)
  @@ -152,7 +152,7 @@
   
   
       /**
  -     * Produces a processed output for an escaped control or 
  +     * Produces a processed output for an escaped control or
        * pluggable directive
        */
       private String escapedDirective( String strImage )
  @@ -406,10 +406,10 @@
           else if ( rsvc.isVelocimacro( t.next.image.substring(1), currentTemplateName))
               control = true;
   
  -        t.image = "";
  +        jjtn000.val = "";
   
           for( int i = 0; i < count; i++)
  -            t.image += ( control ? "\\" : "\\\\");
  +            jjtn000.val += ( control ? "\\" : "\\\\");
       } finally {
         if (jjtc000) {
           jjtree.closeNodeScope(jjtn000, true);
  @@ -514,7 +514,7 @@
   
   /**
    *   Supports the arguments for the Pluggable Directives
  - *   We add whitespace in here as a token so the VMs can 
  + *   We add whitespace in here as a token so the VMs can
    *   easily reconstruct a macro body from the token stream
    *   See Directive()
    */
  @@ -574,7 +574,7 @@
       boolean doItNow = false;
       try {
         /*
  -           * note that if we were escaped, that is now handled by 
  +           * note that if we were escaped, that is now handled by
              * EscapedDirective()
              */
             t = jj_consume_token(WORD);
  @@ -594,7 +594,7 @@
           }
   
           /*
  -         * set the directive name from here.  No reason for the thing to know 
  +         * set the directive name from here.  No reason for the thing to know
            * about parser tokens
            */
   
  @@ -602,7 +602,7 @@
   
           if ( d == null)
           {
  -            /*      
  +            /*
                *  if null, then not a real directive, but maybe a Velocimacro
   	         */
   
  @@ -720,7 +720,7 @@
         jjtree.closeNodeScope(jjtn000, true);
         jjtc000 = false;
           /*
  -         *  VM : if we are processing a #macro directive, we need to 
  +         *  VM : if we are processing a #macro directive, we need to
            *     process the block.  In truth, I can just register the name
            *     and do the work later when init-ing.  That would work
            *     as long as things were always defined before use.  This way
  @@ -818,7 +818,7 @@
   
   /**
    *  supports the [n..m] vector generator for use in
  - *  the #foreach() to generate measured ranges w/o 
  + *  the #foreach() to generate measured ranges w/o
    *  needing explicit support from the app/servlet
    */
     final public void IntegerRange() throws ParseException {
  @@ -1194,9 +1194,9 @@
     }
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *  Defined Directive Syntax
  - * 
  + *
    * ----------------------------------------------------------------------*/
     final public void IfStatement() throws ParseException {
                         /*@bgen(jjtree) IfStatement */
  @@ -1557,9 +1557,9 @@
     }
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *  Expression Syntax
  - * 
  + *
    * ----------------------------------------------------------------------*/
     final public void Expression() throws ParseException {
                        /*@bgen(jjtree) Expression */
  
  
  
  1.69      +272 -272  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.68
  retrieving revision 1.69
  diff -u -r1.68 -r1.69
  --- Parser.jj	22 Feb 2002 21:40:38 -0000	1.68
  +++ Parser.jj	23 Mar 2002 13:38:32 -0000	1.69
  @@ -59,18 +59,18 @@
    */
   
   options
  -{                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
  -    
  +{                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
  +
       /**
        * The parser must be non-static in order for the
        * above option to work, otherwise the parser value
        * is passed in as null, which isn't all the useful ;)
        */
  -    STATIC=false;                                                                                                                                                                                                                                                                                                                  
  +    STATIC=false;                                                                                                                                                                                                                                                                                                              
   
       /**
        * Declare that we are accepting unicode input and
  -     * that we are using a custom character stream class    
  +     * that we are using a custom character stream class
        * Note that the char stream class is really a slightly
        * modified ASCII_CharStream, as it appears we are safe
        * because we only deal with pre-encoding-converted
  @@ -84,7 +84,7 @@
        */
       DEBUG_PARSER=false;
       DEBUG_TOKEN_MANAGER=false;
  -}    
  +}
   
   PARSER_BEGIN(Parser)
   
  @@ -110,7 +110,7 @@
    *
    * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: Parser.jj,v 1.68 2002/02/22 21:40:38 geirm Exp $ 
  + * @version $Id: Parser.jj,v 1.69 2002/03/23 13:38:32 geirm Exp $
   */
   public class Parser/*@bgen(jjtree)*/implements ParserTreeConstants/*@egen*/
   {/*@bgen(jjtree)*/
  @@ -121,19 +121,19 @@
        *  This Hashtable contains a list of all of the dynamic directives.
        */
       private Hashtable directives = new Hashtable(0);
  -  
  +
       /**
        *  Name of current template we are parsing.  Passed to us in parse()
        */
       String currentTemplateName = "";
   
  -    VelocityCharStream velcharstream = null; 
  +    VelocityCharStream velcharstream = null;
   
       private RuntimeServices rsvc = null;
   
  -    /** 
  +    /**
        * This constructor was added to allow the re-use of parsers.
  -     * The normal constructor takes a single argument which 
  +     * The normal constructor takes a single argument which
        * an InputStream. This simply creates a re-usable parser
        * object, we satisfy the requirement of an InputStream
        * by using a newline character as an input stream.
  @@ -144,13 +144,13 @@
            * need to call the CTOR first thing.
            */
   
  -        this(   new VelocityCharStream( 
  +        this(   new VelocityCharStream(
                   new ByteArrayInputStream("\n".getBytes()), 1, 1 ));
   
           /*
            * now setup a VCS for later use
  -         */    
  -        velcharstream = new VelocityCharStream( 
  +         */
  +        velcharstream = new VelocityCharStream(
                   new ByteArrayInputStream("\n".getBytes()), 1, 1 );
   
           /*
  @@ -159,7 +159,7 @@
           rsvc = rs;
       }
   
  -    /** 
  +    /**
        * This was also added to allow parsers to be
        * re-usable. Normal JavaCC use entails passing an
        * input stream to the constructor and the parsing
  @@ -168,11 +168,11 @@
        * method and re-initializing the lexer with
        * the new stream that we want parsed.
        */
  -    public SimpleNode parse( Reader reader, String templateName ) 
  +    public SimpleNode parse( Reader reader, String templateName )
           throws ParseException
       {
           SimpleNode sn = null;
  -        
  +
           currentTemplateName = templateName;
   
           try
  @@ -183,7 +183,7 @@
                *  reinitialize the VelocityCharStream
                *  with the new reader
                */
  -            velcharstream.ReInit( reader, 1, 1 );   
  +            velcharstream.ReInit( reader, 1, 1 );
   
               /*
                * now reinit the Parser with this CharStream
  @@ -198,10 +198,10 @@
           catch (ParseException pe)
           {
               rsvc.error ("Parser Exception: " + templateName + " : " + StringUtils.stackTrace(pe));
  -            throw new ParseException (pe.currentToken, 
  +            throw new ParseException (pe.currentToken,
                   pe.expectedTokenSequences, pe.tokenImage);
           }
  -        catch (TokenMgrError tme) 
  +        catch (TokenMgrError tme)
           {
               throw new ParseException("Lexical error: " + tme.toString());
           }
  @@ -213,7 +213,7 @@
           currentTemplateName = "";
   
           return sn;
  -    }        
  +    }
   
       /**
        *  This method sets the directives Hashtable
  @@ -232,7 +232,7 @@
       }
   
       /**
  -     *  This method finds out of the directive exists in the directives 
  +     *  This method finds out of the directive exists in the directives
        *  Hashtable.
        */
       public boolean isDirective(String directive)
  @@ -241,11 +241,11 @@
               return true;
           else
               return false;
  -    }            
  +    }
  +
   
  -   
       /**
  -     * Produces a processed output for an escaped control or 
  +     * Produces a processed output for an escaped control or
        * pluggable directive
        */
       private String escapedDirective( String strImage )
  @@ -298,8 +298,8 @@
   
   PARSER_END(Parser)
   
  -TOKEN_MGR_DECLS: 
  -{  
  +TOKEN_MGR_DECLS:
  +{
       private int fileDepth = 0;
   
       private int lparen = 0;
  @@ -338,15 +338,15 @@
   
           if( debugPrint )
               System.out.println(
  -                " stack pop (" + stateStack.size() + ") : lparen=" + 
  -                    ( (Integer) h.get("lparen")).intValue() + 
  +                " stack pop (" + stateStack.size() + ") : lparen=" +
  +                    ( (Integer) h.get("lparen")).intValue() +
                           " newstate=" + ( (Integer) h.get("lexstate")).intValue() );
  -       
  +
           lparen = ( (Integer) h.get("lparen")).intValue();
           rparen = ( (Integer) h.get("rparen")).intValue();
   
  -        SwitchTo( ( (Integer) h.get("lexstate")).intValue() ); 
  -    
  +        SwitchTo( ( (Integer) h.get("lexstate")).intValue() );
  +
           return true;
       }
   
  @@ -358,9 +358,9 @@
       public boolean stateStackPush()
       {
           if( debugPrint )
  -            System.out.println(" (" + stateStack.size() + ") pushing cur state : " + 
  +            System.out.println(" (" + stateStack.size() + ") pushing cur state : " +
                   curLexState );
  -            
  +
           Hashtable h = new Hashtable();
   
           h.put("lexstate", new Integer( curLexState ) );
  @@ -379,62 +379,62 @@
        *  start values, clears stateStack.  Call
        *  before parsing.
        *  @return void
  -     */   
  +     */
       public void clearStateVars()
       {
           stateStack.clear();
  -        
  +
           lparen = 0;
           rparen = 0;
           inReference = false;
           inDirective = false;
           inComment = false;
           inSet = false;
  -        
  +
           return;
       }
   
  - 
  +
       /**
        *  handles the dropdown logic when encountering a RPAREN
        */
       private void RPARENHandler()
       {
           /*
  -         *  Ultimately, we want to drop down to the state below 
  -         *  the one that has an open (if we hit bottom (DEFAULT), 
  +         *  Ultimately, we want to drop down to the state below
  +         *  the one that has an open (if we hit bottom (DEFAULT),
            *  that's fine. It's just text schmoo.
            */
  -   
  +
           boolean closed = false;
   
           if (inComment)
               closed = true;
   
  -        while( !closed ) 
  +        while( !closed )
           {
               /*
  -             * look at current state.  If we haven't seen a lparen 
  -             * in this state then we drop a state, because this 
  +             * look at current state.  If we haven't seen a lparen
  +             * in this state then we drop a state, because this
                * lparen clearly closes our state
                */
   
               if( lparen > 0)
               {
                   /*
  -                 *  if rparen + 1 == lparen, then this state is closed. 
  +                 *  if rparen + 1 == lparen, then this state is closed.
                    * Otherwise, increment and keep parsing
                    */
   
                    if( lparen == rparen + 1)
                    {
                          stateStackPop();
  -                 }  
  +                 }
                   else
  -                {   
  +                {
                       rparen++;
                   }
  -                      
  +
                    closed = true;
               }
               else
  @@ -442,19 +442,19 @@
                   /*
                    * now, drop a state
                    */
  -        
  +
                   if(!stateStackPop())
                       break;
  -            } 
  +            }
           }
       }
  -} 
  +}
   
   /* ------------------------------------------------------------------------
    *
    * Tokens
    *
  - *  Note : we now have another state, REFMODIFIER.  This is sort of a 
  + *  Note : we now have another state, REFMODIFIER.  This is sort of a
    *  type of REFERENCE state, simply use to use the DIRECTIVE token
    *  set when we are processing a $foo.bar() construct
    *
  @@ -462,7 +462,7 @@
   
   <DIRECTIVE,REFMOD2>
   TOKEN:
  -{ 
  +{
       <LBRACKET: "[">
   |   <RBRACKET: "]">
   |   <COMMA:",">
  @@ -484,17 +484,17 @@
               lparen++;
   
           /*
  -         * If in REFERENCE and we have seen the dot, then move 
  +         * If in REFERENCE and we have seen the dot, then move
            * to REFMOD2 -> Modifier()
            */
   
           if (curLexState == REFMODIFIER )
  -            SwitchTo( REFMOD2 ); 
  +            SwitchTo( REFMOD2 );
       }
   }
   
  -/* 
  - * we never will see a ')' in anything but DIRECTIVE and REFMOD2.  
  +/*
  + * we never will see a ')' in anything but DIRECTIVE and REFMOD2.
    * Each have their own
    */
   <DIRECTIVE>
  @@ -506,7 +506,7 @@
       <RPAREN: ")" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ))?>
       {
          RPARENHandler();
  -    }    
  +    }
   }
   
   
  @@ -514,19 +514,19 @@
   TOKEN:
   {
       /*
  -     * in REFMOD2, we don't want to bind the whitespace and \n like we 
  +     * in REFMOD2, we don't want to bind the whitespace and \n like we
        * do when closing a directive.
        */
       <REFMOD2_RPAREN: ")">
       {
           /*
            * need to simply switch back to REFERENCE, not drop down the stack
  -         * because we can (infinitely) chain, ala 
  +         * because we can (infinitely) chain, ala
            * $foo.bar().blargh().woogie().doogie()
            */
   
           SwitchTo( REFERENCE );
  -    }    
  +    }
   }
   
   /*----------------------------------------------
  @@ -539,7 +539,7 @@
       /*
        *  We have to do this, because we want these to be a Text node, and
        *  whatever follows to be peer to this text in the tree.
  -     *  
  +     *
        *  We need to touch the ASTs for these, because we want an even # of \'s
        *  to render properly in front of the block
        *
  @@ -547,30 +547,30 @@
        *  grammatical context, but I am neither smart nor rested, a receipe
        *  for disaster, another long night with Mr. Parser, or both.
        */
  -    
  +
       <ESCAPE_DIRECTIVE :  (<DOUBLE_ESCAPE>)* "\\#" <WORD> >
   }
   
   
   /*
  - * needed because #set is so wacky in it's desired behavior.  We want set 
  - * to eat any preceeding whitespace so it is invisible in formatting. 
  + * needed because #set is so wacky in it's desired behavior.  We want set
  + * to eat any preceeding whitespace so it is invisible in formatting.
    * (As it should be.)  If this works well, I am going to chuck the whole MORE:
  - * token abomination. 
  + * token abomination.
    */
   TOKEN:
   {
     <SET_DIRECTIVE: (" "|"\t")*  "#set" >
  -    { 
  +    {
           if (! inComment)
           {
               inDirective = true;
   
               if ( debugPrint )
                   System.out.print("#set :  going to " + DIRECTIVE );
  -            
  +
               stateStackPush();
  -            inSet = true; 
  +            inSet = true;
               SwitchTo(DIRECTIVE);
           }
      }
  @@ -583,15 +583,15 @@
        *   Note : DOLLARBANG is a duplicate of DOLLAR.  They must be identical.
        */
   
  -    <DOLLAR: ("\\")* "$"> 
  -    { 
  +    <DOLLAR: ("\\")* "$">
  +    {
           if (! inComment)
           {
               /*
                * if we find ourselves in REFERENCE, we need to pop down
                * to end the previous ref
                */
  - 
  +
               if (curLexState == REFERENCE)
               {
                   inReference = false;
  @@ -605,24 +605,24 @@
   
               stateStackPush();
               SwitchTo(REFERENCE);
  -        }            
  +        }
       }
   
  -|   <DOLLARBANG: ("\\")* "$" ("\\")* "!"> 
  -    { 
  +|   <DOLLARBANG: ("\\")* "$" ("\\")* "!">
  +    {
           if (! inComment)
           {
               /*
                * if we find ourselves in REFERENCE, we need to pop down
                * to end the previous ref
                */
  -           
  +
               if (curLexState == REFERENCE)
               {
                   inReference = false;
                   stateStackPop();
               }
  -            
  +
               inReference = true;
   
               if ( debugPrint )
  @@ -630,11 +630,11 @@
   
               stateStackPush();
               SwitchTo(REFERENCE);
  -        }            
  +        }
       }
   
   |   "##"
  -   { 
  +   {
           if (!inComment)
           {
               if (curLexState == REFERENCE)
  @@ -649,29 +649,29 @@
           }
        }
   
  -|   <"#**" ~["#"]> 
  -    { 
  -        input_stream.backup(1); 
  -        inComment = true; 
  +|   <"#**" ~["#"]>
  +    {
  +        input_stream.backup(1);
  +        inComment = true;
           stateStackPush();
           SwitchTo( IN_FORMAL_COMMENT);
  -    } 
  -    
  -|   "#*" 
  -    { 
  +    }
  +
  +|   "#*"
  +    {
           inComment=true;
           stateStackPush();
  -        SwitchTo( IN_MULTI_LINE_COMMENT ); 
  -    } 
  +        SwitchTo( IN_MULTI_LINE_COMMENT );
  +    }
   
  -|   <HASH : "#" > 
  -    { 
  +|   <HASH : "#" >
  +    {
           if (! inComment)
           {
               /*
  -             * We can have the situation where #if($foo)$foo#end.  
  -             * We need to transition out of REFERENCE before going to DIRECTIVE. 
  -             * I don't really like this, but I can't think of a legal way 
  +             * We can have the situation where #if($foo)$foo#end.
  +             * We need to transition out of REFERENCE before going to DIRECTIVE.
  +             * I don't really like this, but I can't think of a legal way
                * you are going into DIRECTIVE while in REFERENCE.  -gmj
                */
   
  @@ -685,54 +685,54 @@
   
               if ( debugPrint )
                   System.out.print("# :  going to " + DIRECTIVE );
  -            
  +
               stateStackPush();
               SwitchTo(PRE_DIRECTIVE);
           }
  -    } 
  -}   
  +    }
  +}
   
   TOKEN :
   {
       <DOUBLE_ESCAPE : "\\\\">
  -|   <ESCAPE: "\\" >   
  +|   <ESCAPE: "\\" >
   |   <TEXT: (~["$", "#", "\\"])+ >
  -}    
  +}
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *   *_COMMENT Lexical tokens
    *
    *-----------------------------------------------------------------------*/
   <IN_SINGLE_LINE_COMMENT>
   TOKEN :
   {
  -  <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > 
  -  { 
  +  <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" >
  +  {
        inComment = false;
        stateStackPop();
  -  } 
  +  }
   
   }
   
   <IN_FORMAL_COMMENT>
   TOKEN :
   {
  -  <FORMAL_COMMENT: "*#" > 
  -  {     
  +  <FORMAL_COMMENT: "*#" >
  +  {
       inComment = false;
       stateStackPop();
  -  } 
  +  }
   }
   
   <IN_MULTI_LINE_COMMENT>
   TOKEN :
   {
  -  <MULTI_LINE_COMMENT: "*#" > 
  -  { 
  -    inComment = false; 
  +  <MULTI_LINE_COMMENT: "*#" >
  +  {
  +    inComment = false;
       stateStackPop();
  -  } 
  +  }
   }
   
   <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
  @@ -742,9 +742,9 @@
   }
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *  DIRECTIVE Lexical State (some of it, anyway)
  - * 
  + *
    * ---------------------------------------------------------------------- */
   
   <DIRECTIVE,REFMOD2>
  @@ -778,16 +778,16 @@
           "\'"
         )
     >
  -   
  +
       {
           /*
  -         *  - if we are in DIRECTIVE and haven't seen ( yet, then also drop out. 
  +         *  - if we are in DIRECTIVE and haven't seen ( yet, then also drop out.
            *      don't forget to account for the beloved yet wierd #set
            *  - finally, if we are in REFMOD2 (remember : $foo.bar( ) then " is ok!
            */
   
            if( curLexState == DIRECTIVE && !inSet && lparen == 0)
  -            stateStackPop();    
  +            stateStackPop();
       }
   }
   
  @@ -806,19 +806,19 @@
           if ( debugPrint )
               System.out.println(" NEWLINE :");
   
  -        stateStackPop();      
  -        
  +        stateStackPop();
  +
           if (inSet)
               inSet = false;
  -        
  +
           if (inDirective)
               inDirective = false;
  -    }        
  -}    
  +    }
  +}
   
   
   <DIRECTIVE>
  -TOKEN : 
  +TOKEN :
   {
       <MINUS: "-">
   |   <PLUS: "+">
  @@ -837,14 +837,14 @@
   |   <EQUALS: "=" >
   }
   
  -<PRE_DIRECTIVE> 
  +<PRE_DIRECTIVE>
   TOKEN :
   {
  -    <END: "end" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )? > 
  -    { 
  -        inDirective = false; 
  +    <END: "end" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )? >
  +    {
  +        inDirective = false;
           stateStackPop();
  -    } 
  +    }
   
   |   <IF_DIRECTIVE: "if">
       {
  @@ -856,11 +856,11 @@
           SwitchTo(DIRECTIVE);
       }
   
  -|   <ELSE_DIRECTIVE: "else" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )?  > 
  -     { 
  -        inDirective = false; 
  +|   <ELSE_DIRECTIVE: "else" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )?  >
  +     {
  +        inDirective = false;
           stateStackPop();
  -    } 
  +    }
   
   |   <STOP_DIRECTIVE: "stop">
       {
  @@ -885,7 +885,7 @@
           {
               stateStackPop();
           }
  -       
  +
       }
   }
   
  @@ -899,7 +899,7 @@
   }
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *  REFERENCE Lexical States
    *
    *  This is more than a single state, because of the  structure of
  @@ -909,7 +909,7 @@
    *  $foo.bar( "arg" )
    *  ^   ^   ^
    *  |   |   |
  - *  ----------- >  REFERENCE : state initiated by the '$' character.  Continues 
  + *  ----------- >  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
  @@ -919,32 +919,32 @@
    *
    * ---------------------------------------------------------------------------- */
   
  -<REFERENCE,REFMODIFIER,REFMOD2> 
  +<REFERENCE,REFMODIFIER,REFMOD2>
   TOKEN :
   {
       <#ALPHA_CHAR: ["a"-"z", "A"-"Z"] >
   |   <#ALPHANUM_CHAR: [ "a"-"z", "A"-"Z", "0"-"9" ] >
   |   <#IDENTIFIER_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "-", "_" ] >
   |   <IDENTIFIER:  ( <ALPHA_CHAR> | ["_"]) (<IDENTIFIER_CHAR>)* >
  -|   <DOT: "." <ALPHA_CHAR>> 
  -    { 
  +|   <DOT: "." <ALPHA_CHAR>>
  +    {
           /*
  -         * push the alpha char back into the stream so the following identifier 
  +         * push the alpha char back into the stream so the following identifier
            * is complete
            */
   
  -        input_stream.backup(1); 
  +        input_stream.backup(1);
   
           /*
  -         * and munge the <DOT> so we just get a . when we have normal text that 
  +         * and munge the <DOT> so we just get a . when we have normal text that
            * looks like a ref.ident
            */
   
           matchedToken.image = ".";
   
  -        if ( debugPrint ) 
  -            System.out.print("DOT : switching to " + REFMODIFIER); 
  -        SwitchTo(REFMODIFIER); 
  +        if ( debugPrint )
  +            System.out.print("DOT : switching to " + REFMODIFIER);
  +        SwitchTo(REFMODIFIER);
   
       }
   |   <LCURLY: "{">
  @@ -954,37 +954,37 @@
       }
   }
   
  -<REFERENCE,REFMODIFIER,REFMOD2> 
  +<REFERENCE,REFMODIFIER,REFMOD2>
   SPECIAL_TOKEN :
   {
       <REFERENCE_TERMINATOR: ~[] >
  -    {   
  +    {
           /*
  -         * push every terminator character back into the stream  
  +         * push every terminator character back into the stream
            */
   
           input_stream.backup(1);
  -      
  +
           inReference = false;
  -    
  +
           if ( debugPrint )
               System.out.print("REF_TERM :");
  -        
  +
           stateStackPop();
       }
   }
   
  -<PRE_DIRECTIVE> 
  +<PRE_DIRECTIVE>
   SPECIAL_TOKEN :
   {
       <DIRECTIVE_TERMINATOR: ~[] >
       {
           if ( debugPrint )
               System.out.print("DIRECTIVE_TERM :");
  - 
  -        input_stream.backup(1); 
  +
  +        input_stream.backup(1);
           inDirective = false;
  -        stateStackPop();       
  +        stateStackPop();
       }
   }
   
  @@ -1065,9 +1065,9 @@
   /*@egen*/}
   {/*@bgen(jjtree) EscapedDirective */
       try {
  -/*@egen*/ 
  -    {    
  -        Token t = null; 
  +/*@egen*/
  +    {
  +        Token t = null;
       }
   
       t = <ESCAPE_DIRECTIVE>/*@bgen(jjtree)*/
  @@ -1104,7 +1104,7 @@
   /*@egen*/}
   {/*@bgen(jjtree) Escape */
       try {
  -/*@egen*/   
  +/*@egen*/
       {
           Token t = null;
           int count = 0;
  @@ -1137,17 +1137,17 @@
   
           /*
            * if that failed, lets lookahead to see if we matched a PD or a VM
  -         */ 
  +         */
   
           if ( isDirective( t.next.image.substring(1)))
               control = true;
           else if ( rsvc.isVelocimacro( t.next.image.substring(1), currentTemplateName))
               control = true;
   
  -        t.image = "";
  -        
  +        jjtn000.val = "";
  +
           for( int i = 0; i < count; i++)
  -            t.image += ( control ? "\\" : "\\\\");
  +            jjtn000.val += ( control ? "\\" : "\\\\");
       }/*@bgen(jjtree)*/
       } finally {
         if (jjtc000) {
  @@ -1192,7 +1192,7 @@
         }
       }
   /*@egen*/
  -}    
  +}
   
   void StringLiteral() : {/*@bgen(jjtree) StringLiteral */
     ASTStringLiteral jjtn000 = new ASTStringLiteral(this, JJTSTRINGLITERAL);
  @@ -1209,7 +1209,7 @@
         }
       }
   /*@egen*/
  -}    
  +}
   
   /**
    * This method corresponds to variable
  @@ -1229,7 +1229,7 @@
   /*@egen*/}
   {/*@bgen(jjtree) Identifier */
       try {
  -/*@egen*/    
  +/*@egen*/
       <IDENTIFIER>/*@bgen(jjtree)*/
       } finally {
         if (jjtc000) {
  @@ -1254,21 +1254,21 @@
         }
       }
   /*@egen*/
  -}    
  +}
   
   /**
    *   Supports the arguments for the Pluggable Directives
  - *   We add whitespace in here as a token so the VMs can 
  + *   We add whitespace in here as a token so the VMs can
    *   easily reconstruct a macro body from the token stream
    *   See Directive()
    */
   void DirectiveArg()       : {}
   {
       Reference()
  -|   Word()  
  +|   Word()
   |   StringLiteral()
   |   NumberLiteral()
  -|   LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()    
  +|   LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()
   |   ObjectArray()
   |   True()
   |   False()
  @@ -1279,7 +1279,7 @@
    *   Supports the Pluggable Directives
    *     #foo( arg+ )
    */
  -SimpleNode Directive() : 
  +SimpleNode Directive() :
   {/*@bgen(jjtree) Directive */
       ASTDirective jjtn000 = new ASTDirective(this, JJTDIRECTIVE);
       boolean jjtc000 = true;
  @@ -1294,13 +1294,13 @@
       try {
   /*@egen*/
       /*
  -     * note that if we were escaped, that is now handled by 
  +     * note that if we were escaped, that is now handled by
        * EscapedDirective()
        */
  -    t = <WORD> 
  +    t = <WORD>
       {
           String directiveName = t.image.substring(1);
  - 
  +
           d = (Directive) directives.get( directiveName );
   
           /*
  @@ -1309,38 +1309,38 @@
            *   right then. (So available if used w/in the current template )
            */
   
  -        if ( directiveName.equals("macro"))  
  +        if ( directiveName.equals("macro"))
           {
                doItNow = true;
           }
   
           /*
  -         * set the directive name from here.  No reason for the thing to know 
  +         * set the directive name from here.  No reason for the thing to know
            * about parser tokens
            */
   
           jjtn000.setDirectiveName( directiveName );
   
  -        if ( d == null) 
  +        if ( d == null)
           {
  -            /*      
  +            /*
                *  if null, then not a real directive, but maybe a Velocimacro
   	         */
   
               //d  =  (Directive) rsvc.getVelocimacro( directiveName, currentTemplateName );
   
  -            if ( !rsvc.isVelocimacro( directiveName, currentTemplateName ) ) 
  -            {   
  +            if ( !rsvc.isVelocimacro( directiveName, currentTemplateName ) )
  +            {
                   token_source.stateStackPop();
                   token_source.inDirective = false;
                   return jjtn000;
  -            }    
  +            }
   
               /*
                *  Currently, all VMs are LINE directives
                */
   
  -            directiveType = Directive.LINE; 
  +            directiveType = Directive.LINE;
           }
           else
           {
  @@ -1374,7 +1374,7 @@
       /*
        *  and the following block if the PD needs it
        */
  -   
  +
       ( Statement() )+/*@bgen(jjtree)*/
       } catch (Throwable jjte001) {
         if (jjtc001) {
  @@ -1395,23 +1395,23 @@
           jjtree.closeNodeScope(jjtn001, true);
         }
       }
  -/*@egen*/ 
  +/*@egen*/
       <END>/*@bgen(jjtree)*/
       {
         jjtree.closeNodeScope(jjtn000, true);
         jjtc000 = false;
       }
  -/*@egen*/ 
  +/*@egen*/
       {
           /*
  -         *  VM : if we are processing a #macro directive, we need to 
  +         *  VM : if we are processing a #macro directive, we need to
            *     process the block.  In truth, I can just register the name
            *     and do the work later when init-ing.  That would work
            *     as long as things were always defined before use.  This way
            *     we don't have to worry about forward references and such...
            */
  -      
  -        if ( doItNow )  
  +
  +        if ( doItNow )
           {
               Macro.processAndRegister( rsvc, jjtn000, currentTemplateName );
           }
  @@ -1441,8 +1441,8 @@
           jjtree.closeNodeScope(jjtn000, true);
         }
       }
  -/*@egen*/ 
  -}    
  +/*@egen*/
  +}
   
   void ObjectArray() : {/*@bgen(jjtree) ObjectArray */
     ASTObjectArray jjtn000 = new ASTObjectArray(this, JJTOBJECTARRAY);
  @@ -1477,7 +1477,7 @@
   
   /**
    *  supports the [n..m] vector generator for use in
  - *  the #foreach() to generate measured ranges w/o 
  + *  the #foreach() to generate measured ranges w/o
    *  needing explicit support from the app/servlet
    */
   void IntegerRange() : {/*@bgen(jjtree) IntegerRange */
  @@ -1488,10 +1488,10 @@
   {/*@bgen(jjtree) IntegerRange */
       try {
   /*@egen*/
  -    <LBRACKET> [<WHITESPACE>] 
  -    ( Reference() | NumberLiteral()) 
  -    [<WHITESPACE>] <DOUBLEDOT> [<WHITESPACE>] 
  -    (Reference() | NumberLiteral()) 
  +    <LBRACKET> [<WHITESPACE>]
  +    ( Reference() | NumberLiteral())
  +    [<WHITESPACE>] <DOUBLEDOT> [<WHITESPACE>]
  +    (Reference() | NumberLiteral())
       [<WHITESPACE>] <RBRACKET>/*@bgen(jjtree)*/
       } catch (Throwable jjte000) {
         if (jjtc000) {
  @@ -1526,7 +1526,7 @@
       [<WHITESPACE>]
       (
           StringLiteral()
  -        | LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()       
  +        | LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()
           | ObjectArray()
           | True()
           | False()
  @@ -1579,20 +1579,20 @@
   /*@egen*/}
   {/*@bgen(jjtree) Reference */
         try {
  -/*@egen*/ 
  +/*@egen*/
       /*
        *  A reference is either ${<FOO>} or  $<FOO>
        */
  -     
  -      ( 
  -         <IDENTIFIER> 
  -         (LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ))* 
  +
  +      (
  +         <IDENTIFIER>
  +         (LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ))*
         )
  -      |      
  -      ( 
  -         <LCURLY> 
  -         <IDENTIFIER>  
  -         (LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ))* 
  +      |
  +      (
  +         <LCURLY>
  +         <IDENTIFIER>
  +         (LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ))*
            <RCURLY>
         )/*@bgen(jjtree)*/
         } catch (Throwable jjte000) {
  @@ -1682,9 +1682,9 @@
   }
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *  Defined Directive Syntax
  - * 
  + *
    * ----------------------------------------------------------------------*/
   
   void IfStatement() : {/*@bgen(jjtree) IfStatement */
  @@ -1723,7 +1723,7 @@
           jjtree.closeNodeScope(jjtn001, true);
         }
       }
  -/*@egen*/ 
  +/*@egen*/
       [ LOOKAHEAD(1) ( ElseIfStatement() )+ ]
       [ LOOKAHEAD(1) ElseStatement() ]
       <END>/*@bgen(jjtree)*/
  @@ -1765,7 +1765,7 @@
         jjtree.openNodeScope(jjtn001);
       }
       try {
  -/*@egen*/ 
  +/*@egen*/
       ( Statement() )+/*@bgen(jjtree)*/
       } catch (Throwable jjte001) {
         if (jjtc001) {
  @@ -1817,7 +1817,7 @@
   {/*@bgen(jjtree) ElseIfStatement */
       try {
   /*@egen*/
  -    <ELSEIF_DIRECTIVE> [<WHITESPACE>] 
  +    <ELSEIF_DIRECTIVE> [<WHITESPACE>]
       <LPAREN> Expression() <RPAREN>/*@bgen(jjtree) Block */
       {
         ASTBlock jjtn001 = new ASTBlock(this, JJTBLOCK);
  @@ -1882,15 +1882,15 @@
   {/*@bgen(jjtree) SetDirective */
       try {
   /*@egen*/
  -    <SET_DIRECTIVE>  
  -    [ LOOKAHEAD(2) <WHITESPACE> ] 
  +    <SET_DIRECTIVE>
  +    [ LOOKAHEAD(2) <WHITESPACE> ]
       ( <LPAREN> Expression() <RPAREN>
  -    { 
  +    {
           /*
            * ensure that inSet is false.  Leads to some amusing bugs...
            */
  -    
  -        token_source.inSet = false; 
  +
  +        token_source.inSet = false;
       }
       [<NEWLINE>] )/*@bgen(jjtree)*/
       } catch (Throwable jjte000) {
  @@ -1913,7 +1913,7 @@
         }
       }
   /*@egen*/
  -}    
  +}
   
   /**
    * This method corresponds to the #stop
  @@ -1923,14 +1923,14 @@
    * purposes.
    */
   void StopStatement()      : {}
  -{    
  +{
       <STOP_DIRECTIVE>
   }
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *  Expression Syntax
  - * 
  + *
    * ----------------------------------------------------------------------*/
   
   void Expression() : {/*@bgen(jjtree) Expression */
  @@ -2066,7 +2066,7 @@
   void EqualityExpression()       : {}
   {
       RelationalExpression()
  -    (           
  +    (
          <LOGICAL_EQUALS>/*@bgen(jjtree) #EQNode( 2) */
                           {
                             ASTEQNode jjtn001 = new ASTEQNode(this, JJTEQNODE);
  @@ -2122,13 +2122,13 @@
                                   jjtree.closeNodeScope(jjtn002,  2);
                                 }
                               }
  -/*@egen*/    
  +/*@egen*/
       )*
   }
   
   void RelationalExpression()       : {}
   {
  -    AdditiveExpression() 
  +    AdditiveExpression()
       (
           <LOGICAL_LT>/*@bgen(jjtree) #LTNode( 2) */
                         {
  @@ -2241,7 +2241,7 @@
                             jjtree.closeNodeScope(jjtn004,  2);
                           }
                         }
  -/*@egen*/  
  +/*@egen*/
       )*
   }
   
  @@ -2304,7 +2304,7 @@
                       jjtree.closeNodeScope(jjtn002,  2);
                     }
                   }
  -/*@egen*/    
  +/*@egen*/
       )*
   }
   
  @@ -2429,17 +2429,17 @@
                                                       }
                                                     }
   /*@egen*/
  -|   PrimaryExpression() 
  +|   PrimaryExpression()
   }
   
   void PrimaryExpression()       : {}
  -{  
  -    [<WHITESPACE>] 
  -    (  
  +{
  +    [<WHITESPACE>]
  +    (
        StringLiteral()
  -    | NumberLiteral()    
  +    | NumberLiteral()
       | Reference()
  -    | LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()     
  +    | LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()
       | ObjectArray()
       | True()
       | False()
  @@ -2450,53 +2450,53 @@
   
   
   /* ======================================================================
  - 
  +
      Notes
      -----
  - 
  -    template == the input stream for this parser, contains 'VTL' 
  +
  +    template == the input stream for this parser, contains 'VTL'
       mixed in with 'schmoo'
  -    
  +
       VTL == Velocity Template Language : the references, directives, etc
  -    
  +
       shmoo == the non-VTL component of a template
  -    
  +
       reference == VTL entity that represents data within the context. ex. $foo
  -    
  +
       directive == VTL entity that denotes 'action' (#set, #foreach, #if )
  -    
  -    defined directive (DD) == VTL directive entity that is expressed 
  +
  +    defined directive (DD) == VTL directive entity that is expressed
       explicitly w/in this grammar
  -    
  -    pluggable directive (PD) == VTL directive entity that is defined outside of the 
  +
  +    pluggable directive (PD) == VTL directive entity that is defined outside of the
       grammar.  PD's allow VTL to be easily expandable w/o parser modification.
  - 
  -    The problem with parsing VTL is that an input stream consists generally of 
  -    little bits of VTL mixed in with 'other stuff, 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. It must simply output the schmoo and keep going.  
  - 
  +
  +    The problem with parsing VTL is that an input stream consists generally of
  +    little bits of VTL mixed in with 'other stuff, 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. It must simply output the schmoo and keep going.
  +
       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(), 
  +     - define the VTL grammar, expressed (mostly) in the productions such as Text(),
        SetStatement(), etc.
  -   
  -    It is clear that this expression of the VTL grammar (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 
  +
  +    It is clear that this expression of the VTL grammar (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 :  This is the base or starting state, and strangely enough, the
       default state.
  - 
  -    PRE_DIRECTIVE : State immediately following '#' before we figure out which 
  +
  +    PRE_DIRECTIVE : State immediately following '#' before we figure out which
       defined or pluggable directive (or neither) we are working with.
  -     
  +
       DIRECTIVE : This state is triggered by the a match of a DD or a PD.
   
       REFERENCE : Triggered by '$'. Analagous to PRE_DIRECTIVE.
  @@ -2504,51 +2504,51 @@
       REFMODIFIER : Triggered by .<alpha> when in REFERENCE.
   
       REFMOD2 : Triggered by ( when in REFMODIFIER
  - 
  +
       (cont)
   
       Escape Sequences
       ----------------
  -    The escape processing in VTL is very simple.  The '\' character acts 
  +    The escape processing in VTL is very simple.  The '\' character acts
       only as an escape when :
  -    
  +
           1) On or more touch a VTL element.
   
       A VTL element is either :
   
           1) It preceeds a reference that is in the context.
   
  -        2) It preceeds a defined directive (#set, #if, #end, etc) or a valid 
  +        2) It preceeds a defined directive (#set, #if, #end, etc) or a valid
           pluggable directive, such as #foreach
   
  -    In all other cases the '\' is just another piece of text.  The purpose of this 
  -    is to allow the non-VTL parts of a template (the 'schmoo') to not have to be 
  +    In all other cases the '\' is just another piece of text.  The purpose of this
  +    is to allow the non-VTL parts of a template (the 'schmoo') to not have to be
       altered for processing by Velocity.
   
  -    So if in the context $foo and $bar were defined and $woogie was not 
  -        
  +    So if in the context $foo and $bar were defined and $woogie was not
  +
           \$foo  \$bar \$woogie
   
       would output
   
           $foo  $bar  \$woogie
   
  -    Further, you can stack them and they affect left to right, just like convention 
  +    Further, you can stack them and they affect left to right, just like convention
       escape characters in other languages.
   
           \$foo = $foo
           \\$foo = \<foo>
           \\\$foo = \$foo
   
  -    
  +
       What You Expect
       ---------------
  -    The recent versions of the parser are trying to support precise output to 
  -    support general template use. The directives do not render trailing 
  -    whitespace and newlines if followed by a newline.  They will render 
  -    preceeding whitespace. The only exception is #set, which also eats 
  +    The recent versions of the parser are trying to support precise output to
  +    support general template use. The directives do not render trailing
  +    whitespace and newlines if followed by a newline.  They will render
  +    preceeding whitespace. The only exception is #set, which also eats
       preceeding whitespace.
  - 
  +
       So, with a template :
   
           ------
  @@ -2565,4 +2565,4 @@
           ------
   
   */
  - 
  +
  
  
  
  1.72      +272 -272  jakarta-velocity/src/java/org/apache/velocity/runtime/parser/Parser.jjt
  
  Index: Parser.jjt
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/parser/Parser.jjt,v
  retrieving revision 1.71
  retrieving revision 1.72
  diff -u -r1.71 -r1.72
  --- Parser.jjt	22 Feb 2002 21:40:22 -0000	1.71
  +++ Parser.jjt	23 Mar 2002 13:38:32 -0000	1.72
  @@ -64,7 +64,7 @@
   
       /** A source file will be generated for each non-terminal */
       MULTI=true;
  -    
  +
       /**
        * Each node will have access to the parser, I did this so
        * some global information can be shared via the parser. I
  @@ -75,14 +75,14 @@
        * what not.
        */
       NODE_USES_PARSER=true;
  -    
  +
       /**
        * The parser must be non-static in order for the
        * above option to work, otherwise the parser value
        * is passed in as null, which isn't all the useful ;)
        */
       STATIC=false;
  -    
  +
       /**
        * Enables the use of a visitor that each of nodes
        * will accept. This way we can separate the logic
  @@ -94,7 +94,7 @@
   
       /**
        * Declare that we are accepting unicode input and
  -     * that we are using a custom character stream class    
  +     * that we are using a custom character stream class
        * Note that the char stream class is really a slightly
        * modified ASCII_CharStream, as it appears we are safe
        * because we only deal with pre-encoding-converted
  @@ -108,7 +108,7 @@
        */
       DEBUG_PARSER=false;
       DEBUG_TOKEN_MANAGER=false;
  -}    
  +}
   
   PARSER_BEGIN(Parser)
   
  @@ -134,7 +134,7 @@
    *
    * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: Parser.jjt,v 1.71 2002/02/22 21:40:22 geirm Exp $ 
  + * @version $Id: Parser.jjt,v 1.72 2002/03/23 13:38:32 geirm Exp $
   */
   public class Parser
   {
  @@ -142,19 +142,19 @@
        *  This Hashtable contains a list of all of the dynamic directives.
        */
       private Hashtable directives = new Hashtable(0);
  -  
  +
       /**
        *  Name of current template we are parsing.  Passed to us in parse()
        */
       String currentTemplateName = "";
   
  -    VelocityCharStream velcharstream = null; 
  +    VelocityCharStream velcharstream = null;
   
       private RuntimeServices rsvc = null;
   
  -    /** 
  +    /**
        * This constructor was added to allow the re-use of parsers.
  -     * The normal constructor takes a single argument which 
  +     * The normal constructor takes a single argument which
        * an InputStream. This simply creates a re-usable parser
        * object, we satisfy the requirement of an InputStream
        * by using a newline character as an input stream.
  @@ -165,13 +165,13 @@
            * need to call the CTOR first thing.
            */
   
  -        this(   new VelocityCharStream( 
  +        this(   new VelocityCharStream(
                   new ByteArrayInputStream("\n".getBytes()), 1, 1 ));
   
           /*
            * now setup a VCS for later use
  -         */    
  -        velcharstream = new VelocityCharStream( 
  +         */
  +        velcharstream = new VelocityCharStream(
                   new ByteArrayInputStream("\n".getBytes()), 1, 1 );
   
           /*
  @@ -180,7 +180,7 @@
           rsvc = rs;
       }
   
  -    /** 
  +    /**
        * This was also added to allow parsers to be
        * re-usable. Normal JavaCC use entails passing an
        * input stream to the constructor and the parsing
  @@ -189,11 +189,11 @@
        * method and re-initializing the lexer with
        * the new stream that we want parsed.
        */
  -    public SimpleNode parse( Reader reader, String templateName ) 
  +    public SimpleNode parse( Reader reader, String templateName )
           throws ParseException
       {
           SimpleNode sn = null;
  -        
  +
           currentTemplateName = templateName;
   
           try
  @@ -204,7 +204,7 @@
                *  reinitialize the VelocityCharStream
                *  with the new reader
                */
  -            velcharstream.ReInit( reader, 1, 1 );   
  +            velcharstream.ReInit( reader, 1, 1 );
   
               /*
                * now reinit the Parser with this CharStream
  @@ -219,10 +219,10 @@
           catch (ParseException pe)
           {
               rsvc.error ("Parser Exception: " + templateName + " : " + StringUtils.stackTrace(pe));
  -            throw new ParseException (pe.currentToken, 
  +            throw new ParseException (pe.currentToken,
                   pe.expectedTokenSequences, pe.tokenImage);
           }
  -        catch (TokenMgrError tme) 
  +        catch (TokenMgrError tme)
           {
               throw new ParseException("Lexical error: " + tme.toString());
           }
  @@ -234,7 +234,7 @@
           currentTemplateName = "";
   
           return sn;
  -    }        
  +    }
   
       /**
        *  This method sets the directives Hashtable
  @@ -253,7 +253,7 @@
       }
   
       /**
  -     *  This method finds out of the directive exists in the directives 
  +     *  This method finds out of the directive exists in the directives
        *  Hashtable.
        */
       public boolean isDirective(String directive)
  @@ -262,11 +262,11 @@
               return true;
           else
               return false;
  -    }            
  +    }
  +
   
  -   
       /**
  -     * Produces a processed output for an escaped control or 
  +     * Produces a processed output for an escaped control or
        * pluggable directive
        */
       private String escapedDirective( String strImage )
  @@ -319,8 +319,8 @@
   
   PARSER_END(Parser)
   
  -TOKEN_MGR_DECLS: 
  -{  
  +TOKEN_MGR_DECLS:
  +{
       private int fileDepth = 0;
   
       private int lparen = 0;
  @@ -359,15 +359,15 @@
   
           if( debugPrint )
               System.out.println(
  -                " stack pop (" + stateStack.size() + ") : lparen=" + 
  -                    ( (Integer) h.get("lparen")).intValue() + 
  +                " stack pop (" + stateStack.size() + ") : lparen=" +
  +                    ( (Integer) h.get("lparen")).intValue() +
                           " newstate=" + ( (Integer) h.get("lexstate")).intValue() );
  -       
  +
           lparen = ( (Integer) h.get("lparen")).intValue();
           rparen = ( (Integer) h.get("rparen")).intValue();
   
  -        SwitchTo( ( (Integer) h.get("lexstate")).intValue() ); 
  -    
  +        SwitchTo( ( (Integer) h.get("lexstate")).intValue() );
  +
           return true;
       }
   
  @@ -379,9 +379,9 @@
       public boolean stateStackPush()
       {
           if( debugPrint )
  -            System.out.println(" (" + stateStack.size() + ") pushing cur state : " + 
  +            System.out.println(" (" + stateStack.size() + ") pushing cur state : " +
                   curLexState );
  -            
  +
           Hashtable h = new Hashtable();
   
           h.put("lexstate", new Integer( curLexState ) );
  @@ -400,62 +400,62 @@
        *  start values, clears stateStack.  Call
        *  before parsing.
        *  @return void
  -     */   
  +     */
       public void clearStateVars()
       {
           stateStack.clear();
  -        
  +
           lparen = 0;
           rparen = 0;
           inReference = false;
           inDirective = false;
           inComment = false;
           inSet = false;
  -        
  +
           return;
       }
   
  - 
  +
       /**
        *  handles the dropdown logic when encountering a RPAREN
        */
       private void RPARENHandler()
       {
           /*
  -         *  Ultimately, we want to drop down to the state below 
  -         *  the one that has an open (if we hit bottom (DEFAULT), 
  +         *  Ultimately, we want to drop down to the state below
  +         *  the one that has an open (if we hit bottom (DEFAULT),
            *  that's fine. It's just text schmoo.
            */
  -   
  +
           boolean closed = false;
   
           if (inComment)
               closed = true;
   
  -        while( !closed ) 
  +        while( !closed )
           {
               /*
  -             * look at current state.  If we haven't seen a lparen 
  -             * in this state then we drop a state, because this 
  +             * look at current state.  If we haven't seen a lparen
  +             * in this state then we drop a state, because this
                * lparen clearly closes our state
                */
   
               if( lparen > 0)
               {
                   /*
  -                 *  if rparen + 1 == lparen, then this state is closed. 
  +                 *  if rparen + 1 == lparen, then this state is closed.
                    * Otherwise, increment and keep parsing
                    */
   
                    if( lparen == rparen + 1)
                    {
                          stateStackPop();
  -                 }  
  +                 }
                   else
  -                {   
  +                {
                       rparen++;
                   }
  -                      
  +
                    closed = true;
               }
               else
  @@ -463,19 +463,19 @@
                   /*
                    * now, drop a state
                    */
  -        
  +
                   if(!stateStackPop())
                       break;
  -            } 
  +            }
           }
       }
  -} 
  +}
   
   /* ------------------------------------------------------------------------
    *
    * Tokens
    *
  - *  Note : we now have another state, REFMODIFIER.  This is sort of a 
  + *  Note : we now have another state, REFMODIFIER.  This is sort of a
    *  type of REFERENCE state, simply use to use the DIRECTIVE token
    *  set when we are processing a $foo.bar() construct
    *
  @@ -483,7 +483,7 @@
   
   <DIRECTIVE,REFMOD2>
   TOKEN:
  -{ 
  +{
       <LBRACKET: "[">
   |   <RBRACKET: "]">
   |   <COMMA:",">
  @@ -505,17 +505,17 @@
               lparen++;
   
           /*
  -         * If in REFERENCE and we have seen the dot, then move 
  +         * If in REFERENCE and we have seen the dot, then move
            * to REFMOD2 -> Modifier()
            */
   
           if (curLexState == REFMODIFIER )
  -            SwitchTo( REFMOD2 ); 
  +            SwitchTo( REFMOD2 );
       }
   }
   
  -/* 
  - * we never will see a ')' in anything but DIRECTIVE and REFMOD2.  
  +/*
  + * we never will see a ')' in anything but DIRECTIVE and REFMOD2.
    * Each have their own
    */
   <DIRECTIVE>
  @@ -527,7 +527,7 @@
       <RPAREN: ")" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ))?>
       {
          RPARENHandler();
  -    }    
  +    }
   }
   
   
  @@ -535,19 +535,19 @@
   TOKEN:
   {
       /*
  -     * in REFMOD2, we don't want to bind the whitespace and \n like we 
  +     * in REFMOD2, we don't want to bind the whitespace and \n like we
        * do when closing a directive.
        */
       <REFMOD2_RPAREN: ")">
       {
           /*
            * need to simply switch back to REFERENCE, not drop down the stack
  -         * because we can (infinitely) chain, ala 
  +         * because we can (infinitely) chain, ala
            * $foo.bar().blargh().woogie().doogie()
            */
   
           SwitchTo( REFERENCE );
  -    }    
  +    }
   }
   
   /*----------------------------------------------
  @@ -560,7 +560,7 @@
       /*
        *  We have to do this, because we want these to be a Text node, and
        *  whatever follows to be peer to this text in the tree.
  -     *  
  +     *
        *  We need to touch the ASTs for these, because we want an even # of \'s
        *  to render properly in front of the block
        *
  @@ -568,30 +568,30 @@
        *  grammatical context, but I am neither smart nor rested, a receipe
        *  for disaster, another long night with Mr. Parser, or both.
        */
  -    
  +
       <ESCAPE_DIRECTIVE :  (<DOUBLE_ESCAPE>)* "\\#" <WORD> >
   }
   
   
   /*
  - * needed because #set is so wacky in it's desired behavior.  We want set 
  - * to eat any preceeding whitespace so it is invisible in formatting. 
  + * needed because #set is so wacky in it's desired behavior.  We want set
  + * to eat any preceeding whitespace so it is invisible in formatting.
    * (As it should be.)  If this works well, I am going to chuck the whole MORE:
  - * token abomination. 
  + * token abomination.
    */
   TOKEN:
   {
     <SET_DIRECTIVE: (" "|"\t")*  "#set" >
  -    { 
  +    {
           if (! inComment)
           {
               inDirective = true;
   
               if ( debugPrint )
                   System.out.print("#set :  going to " + DIRECTIVE );
  -            
  +
               stateStackPush();
  -            inSet = true; 
  +            inSet = true;
               SwitchTo(DIRECTIVE);
           }
      }
  @@ -604,15 +604,15 @@
        *   Note : DOLLARBANG is a duplicate of DOLLAR.  They must be identical.
        */
   
  -    <DOLLAR: ("\\")* "$"> 
  -    { 
  +    <DOLLAR: ("\\")* "$">
  +    {
           if (! inComment)
           {
               /*
                * if we find ourselves in REFERENCE, we need to pop down
                * to end the previous ref
                */
  - 
  +
               if (curLexState == REFERENCE)
               {
                   inReference = false;
  @@ -626,24 +626,24 @@
   
               stateStackPush();
               SwitchTo(REFERENCE);
  -        }            
  +        }
       }
   
  -|   <DOLLARBANG: ("\\")* "$" ("\\")* "!"> 
  -    { 
  +|   <DOLLARBANG: ("\\")* "$" ("\\")* "!">
  +    {
           if (! inComment)
           {
               /*
                * if we find ourselves in REFERENCE, we need to pop down
                * to end the previous ref
                */
  -           
  +
               if (curLexState == REFERENCE)
               {
                   inReference = false;
                   stateStackPop();
               }
  -            
  +
               inReference = true;
   
               if ( debugPrint )
  @@ -651,11 +651,11 @@
   
               stateStackPush();
               SwitchTo(REFERENCE);
  -        }            
  +        }
       }
   
   |   "##"
  -   { 
  +   {
           if (!inComment)
           {
               if (curLexState == REFERENCE)
  @@ -670,29 +670,29 @@
           }
        }
   
  -|   <"#**" ~["#"]> 
  -    { 
  -        input_stream.backup(1); 
  -        inComment = true; 
  +|   <"#**" ~["#"]>
  +    {
  +        input_stream.backup(1);
  +        inComment = true;
           stateStackPush();
           SwitchTo( IN_FORMAL_COMMENT);
  -    } 
  -    
  -|   "#*" 
  -    { 
  +    }
  +
  +|   "#*"
  +    {
           inComment=true;
           stateStackPush();
  -        SwitchTo( IN_MULTI_LINE_COMMENT ); 
  -    } 
  +        SwitchTo( IN_MULTI_LINE_COMMENT );
  +    }
   
  -|   <HASH : "#" > 
  -    { 
  +|   <HASH : "#" >
  +    {
           if (! inComment)
           {
               /*
  -             * We can have the situation where #if($foo)$foo#end.  
  -             * We need to transition out of REFERENCE before going to DIRECTIVE. 
  -             * I don't really like this, but I can't think of a legal way 
  +             * We can have the situation where #if($foo)$foo#end.
  +             * We need to transition out of REFERENCE before going to DIRECTIVE.
  +             * I don't really like this, but I can't think of a legal way
                * you are going into DIRECTIVE while in REFERENCE.  -gmj
                */
   
  @@ -706,54 +706,54 @@
   
               if ( debugPrint )
                   System.out.print("# :  going to " + DIRECTIVE );
  -            
  +
               stateStackPush();
               SwitchTo(PRE_DIRECTIVE);
           }
  -    } 
  -}   
  +    }
  +}
   
   TOKEN :
   {
       <DOUBLE_ESCAPE : "\\\\">
  -|   <ESCAPE: "\\" >   
  +|   <ESCAPE: "\\" >
   |   <TEXT: (~["$", "#", "\\"])+ >
  -}    
  +}
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *   *_COMMENT Lexical tokens
    *
    *-----------------------------------------------------------------------*/
   <IN_SINGLE_LINE_COMMENT>
   TOKEN :
   {
  -  <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > 
  -  { 
  +  <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" >
  +  {
        inComment = false;
        stateStackPop();
  -  } 
  +  }
   
   }
   
   <IN_FORMAL_COMMENT>
   TOKEN :
   {
  -  <FORMAL_COMMENT: "*#" > 
  -  {     
  +  <FORMAL_COMMENT: "*#" >
  +  {
       inComment = false;
       stateStackPop();
  -  } 
  +  }
   }
   
   <IN_MULTI_LINE_COMMENT>
   TOKEN :
   {
  -  <MULTI_LINE_COMMENT: "*#" > 
  -  { 
  -    inComment = false; 
  +  <MULTI_LINE_COMMENT: "*#" >
  +  {
  +    inComment = false;
       stateStackPop();
  -  } 
  +  }
   }
   
   <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
  @@ -763,9 +763,9 @@
   }
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *  DIRECTIVE Lexical State (some of it, anyway)
  - * 
  + *
    * ---------------------------------------------------------------------- */
   
   <DIRECTIVE,REFMOD2>
  @@ -799,16 +799,16 @@
           "\'"
         )
     >
  -   
  +
       {
           /*
  -         *  - if we are in DIRECTIVE and haven't seen ( yet, then also drop out. 
  +         *  - if we are in DIRECTIVE and haven't seen ( yet, then also drop out.
            *      don't forget to account for the beloved yet wierd #set
            *  - finally, if we are in REFMOD2 (remember : $foo.bar( ) then " is ok!
            */
   
            if( curLexState == DIRECTIVE && !inSet && lparen == 0)
  -            stateStackPop();    
  +            stateStackPop();
       }
   }
   
  @@ -827,19 +827,19 @@
           if ( debugPrint )
               System.out.println(" NEWLINE :");
   
  -        stateStackPop();      
  -        
  +        stateStackPop();
  +
           if (inSet)
               inSet = false;
  -        
  +
           if (inDirective)
               inDirective = false;
  -    }        
  -}    
  +    }
  +}
   
   
   <DIRECTIVE>
  -TOKEN : 
  +TOKEN :
   {
       <MINUS: "-">
   |   <PLUS: "+">
  @@ -858,14 +858,14 @@
   |   <EQUALS: "=" >
   }
   
  -<PRE_DIRECTIVE> 
  +<PRE_DIRECTIVE>
   TOKEN :
   {
  -    <END: "end" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )? > 
  -    { 
  -        inDirective = false; 
  +    <END: "end" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )? >
  +    {
  +        inDirective = false;
           stateStackPop();
  -    } 
  +    }
   
   |   <IF_DIRECTIVE: "if">
       {
  @@ -877,11 +877,11 @@
           SwitchTo(DIRECTIVE);
       }
   
  -|   <ELSE_DIRECTIVE: "else" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )?  > 
  -     { 
  -        inDirective = false; 
  +|   <ELSE_DIRECTIVE: "else" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )?  >
  +     {
  +        inDirective = false;
           stateStackPop();
  -    } 
  +    }
   
   |   <STOP_DIRECTIVE: "stop">
       {
  @@ -906,7 +906,7 @@
           {
               stateStackPop();
           }
  -       
  +
       }
   }
   
  @@ -920,7 +920,7 @@
   }
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *  REFERENCE Lexical States
    *
    *  This is more than a single state, because of the  structure of
  @@ -930,7 +930,7 @@
    *  $foo.bar( "arg" )
    *  ^   ^   ^
    *  |   |   |
  - *  ----------- >  REFERENCE : state initiated by the '$' character.  Continues 
  + *  ----------- >  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
  @@ -940,32 +940,32 @@
    *
    * ---------------------------------------------------------------------------- */
   
  -<REFERENCE,REFMODIFIER,REFMOD2> 
  +<REFERENCE,REFMODIFIER,REFMOD2>
   TOKEN :
   {
       <#ALPHA_CHAR: ["a"-"z", "A"-"Z"] >
   |   <#ALPHANUM_CHAR: [ "a"-"z", "A"-"Z", "0"-"9" ] >
   |   <#IDENTIFIER_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "-", "_" ] >
   |   <IDENTIFIER:  ( <ALPHA_CHAR> | ["_"]) (<IDENTIFIER_CHAR>)* >
  -|   <DOT: "." <ALPHA_CHAR>> 
  -    { 
  +|   <DOT: "." <ALPHA_CHAR>>
  +    {
           /*
  -         * push the alpha char back into the stream so the following identifier 
  +         * push the alpha char back into the stream so the following identifier
            * is complete
            */
   
  -        input_stream.backup(1); 
  +        input_stream.backup(1);
   
           /*
  -         * and munge the <DOT> so we just get a . when we have normal text that 
  +         * and munge the <DOT> so we just get a . when we have normal text that
            * looks like a ref.ident
            */
   
           matchedToken.image = ".";
   
  -        if ( debugPrint ) 
  -            System.out.print("DOT : switching to " + REFMODIFIER); 
  -        SwitchTo(REFMODIFIER); 
  +        if ( debugPrint )
  +            System.out.print("DOT : switching to " + REFMODIFIER);
  +        SwitchTo(REFMODIFIER);
   
       }
   |   <LCURLY: "{">
  @@ -975,37 +975,37 @@
       }
   }
   
  -<REFERENCE,REFMODIFIER,REFMOD2> 
  +<REFERENCE,REFMODIFIER,REFMOD2>
   SPECIAL_TOKEN :
   {
       <REFERENCE_TERMINATOR: ~[] >
  -    {   
  +    {
           /*
  -         * push every terminator character back into the stream  
  +         * push every terminator character back into the stream
            */
   
           input_stream.backup(1);
  -      
  +
           inReference = false;
  -    
  +
           if ( debugPrint )
               System.out.print("REF_TERM :");
  -        
  +
           stateStackPop();
       }
   }
   
  -<PRE_DIRECTIVE> 
  +<PRE_DIRECTIVE>
   SPECIAL_TOKEN :
   {
       <DIRECTIVE_TERMINATOR: ~[] >
       {
           if ( debugPrint )
               System.out.print("DIRECTIVE_TERM :");
  - 
  -        input_stream.backup(1); 
  +
  +        input_stream.backup(1);
           inDirective = false;
  -        stateStackPop();       
  +        stateStackPop();
       }
   }
   
  @@ -1049,9 +1049,9 @@
    *  the further parsing of the Directive() tree.
    */
   void EscapedDirective() : {}
  -{ 
  -    {    
  -        Token t = null; 
  +{
  +    {
  +        Token t = null;
       }
   
       t = <ESCAPE_DIRECTIVE>
  @@ -1071,7 +1071,7 @@
    *  the escapes to render correctly
    */
   void Escape() : {}
  -{   
  +{
       {
           Token t = null;
           int count = 0;
  @@ -1099,17 +1099,17 @@
   
           /*
            * if that failed, lets lookahead to see if we matched a PD or a VM
  -         */ 
  +         */
   
           if ( isDirective( t.next.image.substring(1)))
               control = true;
           else if ( rsvc.isVelocimacro( t.next.image.substring(1), currentTemplateName))
               control = true;
   
  -        t.image = "";
  -        
  +        jjtThis.val = "";
  +
           for( int i = 0; i < count; i++)
  -            t.image += ( control ? "\\" : "\\\\");
  +            jjtThis.val += ( control ? "\\" : "\\\\");
       }
   
   }
  @@ -1124,12 +1124,12 @@
   void NumberLiteral() : {}
   {
       <NUMBER_LITERAL>
  -}    
  +}
   
   void StringLiteral() : {}
   {
       <STRING_LITERAL>
  -}    
  +}
   
   /**
    * This method corresponds to variable
  @@ -1143,28 +1143,28 @@
    *
    */
   void Identifier() : {}
  -{    
  +{
       <IDENTIFIER>
   }
   
   void Word() : {}
   {
       <WORD>
  -}    
  +}
   
   /**
    *   Supports the arguments for the Pluggable Directives
  - *   We add whitespace in here as a token so the VMs can 
  + *   We add whitespace in here as a token so the VMs can
    *   easily reconstruct a macro body from the token stream
    *   See Directive()
    */
   void DirectiveArg() #void : {}
   {
       Reference()
  -|   Word()  
  +|   Word()
   |   StringLiteral()
   |   NumberLiteral()
  -|   LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()    
  +|   LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()
   |   ObjectArray()
   |   True()
   |   False()
  @@ -1175,7 +1175,7 @@
    *   Supports the Pluggable Directives
    *     #foo( arg+ )
    */
  -SimpleNode Directive() : 
  +SimpleNode Directive() :
   {
       Token t = null;
       Directive d;
  @@ -1184,13 +1184,13 @@
   }
   {
       /*
  -     * note that if we were escaped, that is now handled by 
  +     * note that if we were escaped, that is now handled by
        * EscapedDirective()
        */
  -    t = <WORD> 
  +    t = <WORD>
       {
           String directiveName = t.image.substring(1);
  - 
  +
           d = (Directive) directives.get( directiveName );
   
           /*
  @@ -1199,38 +1199,38 @@
            *   right then. (So available if used w/in the current template )
            */
   
  -        if ( directiveName.equals("macro"))  
  +        if ( directiveName.equals("macro"))
           {
                doItNow = true;
           }
   
           /*
  -         * set the directive name from here.  No reason for the thing to know 
  +         * set the directive name from here.  No reason for the thing to know
            * about parser tokens
            */
   
           jjtThis.setDirectiveName( directiveName );
   
  -        if ( d == null) 
  +        if ( d == null)
           {
  -            /*      
  +            /*
                *  if null, then not a real directive, but maybe a Velocimacro
   	         */
   
               //d  =  (Directive) rsvc.getVelocimacro( directiveName, currentTemplateName );
   
  -            if ( !rsvc.isVelocimacro( directiveName, currentTemplateName ) ) 
  -            {   
  +            if ( !rsvc.isVelocimacro( directiveName, currentTemplateName ) )
  +            {
                   token_source.stateStackPop();
                   token_source.inDirective = false;
                   return jjtThis;
  -            }    
  +            }
   
               /*
                *  Currently, all VMs are LINE directives
                */
   
  -            directiveType = Directive.LINE; 
  +            directiveType = Directive.LINE;
           }
           else
           {
  @@ -1257,19 +1257,19 @@
       /*
        *  and the following block if the PD needs it
        */
  -   
  -    ( Statement() )+ #Block 
  -    <END> 
  +
  +    ( Statement() )+ #Block
  +    <END>
       {
           /*
  -         *  VM : if we are processing a #macro directive, we need to 
  +         *  VM : if we are processing a #macro directive, we need to
            *     process the block.  In truth, I can just register the name
            *     and do the work later when init-ing.  That would work
            *     as long as things were always defined before use.  This way
            *     we don't have to worry about forward references and such...
            */
  -      
  -        if ( doItNow )  
  +
  +        if ( doItNow )
           {
               Macro.processAndRegister( rsvc, jjtThis, currentTemplateName );
           }
  @@ -1279,8 +1279,8 @@
            */
   
           return jjtThis;
  -    } 
  -}    
  +    }
  +}
   
   void ObjectArray() : {}
   {
  @@ -1289,15 +1289,15 @@
   
   /**
    *  supports the [n..m] vector generator for use in
  - *  the #foreach() to generate measured ranges w/o 
  + *  the #foreach() to generate measured ranges w/o
    *  needing explicit support from the app/servlet
    */
   void IntegerRange() : {}
   {
  -    <LBRACKET> [<WHITESPACE>] 
  -    ( Reference() | NumberLiteral()) 
  -    [<WHITESPACE>] <DOUBLEDOT> [<WHITESPACE>] 
  -    (Reference() | NumberLiteral()) 
  +    <LBRACKET> [<WHITESPACE>]
  +    ( Reference() | NumberLiteral())
  +    [<WHITESPACE>] <DOUBLEDOT> [<WHITESPACE>]
  +    (Reference() | NumberLiteral())
       [<WHITESPACE>] <RBRACKET>
   }
   
  @@ -1312,7 +1312,7 @@
       [<WHITESPACE>]
       (
           StringLiteral()
  -        | LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()       
  +        | LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()
           | ObjectArray()
           | True()
           | False()
  @@ -1333,20 +1333,20 @@
   }
   
   void Reference() : {}
  -{ 
  +{
       /*
        *  A reference is either ${<FOO>} or  $<FOO>
        */
  -     
  -      ( 
  -         <IDENTIFIER> 
  -         (LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ))* 
  +
  +      (
  +         <IDENTIFIER>
  +         (LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ))*
         )
  -      |      
  -      ( 
  -         <LCURLY> 
  -         <IDENTIFIER>  
  -         (LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ))* 
  +      |
  +      (
  +         <LCURLY>
  +         <IDENTIFIER>
  +         (LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ))*
            <RCURLY>
         )
   }
  @@ -1380,15 +1380,15 @@
   }
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *  Defined Directive Syntax
  - * 
  + *
    * ----------------------------------------------------------------------*/
   
   void IfStatement() : {}
   {
       <IF_DIRECTIVE> [<WHITESPACE>] <LPAREN> Expression() <RPAREN>
  -    ( Statement() )+ #Block 
  +    ( Statement() )+ #Block
       [ LOOKAHEAD(1) ( ElseIfStatement() )+ ]
       [ LOOKAHEAD(1) ElseStatement() ]
       <END>
  @@ -1397,13 +1397,13 @@
   
   void ElseStatement() : {}
   {
  -   <ELSE_DIRECTIVE> 
  +   <ELSE_DIRECTIVE>
       ( Statement() )+ #Block
   }
   
   void ElseIfStatement() : {}
   {
  -    <ELSEIF_DIRECTIVE> [<WHITESPACE>] 
  +    <ELSEIF_DIRECTIVE> [<WHITESPACE>]
       <LPAREN> Expression() <RPAREN>
       ( Statement() )+ #Block
   }
  @@ -1415,18 +1415,18 @@
    */
   void SetDirective() : {}
   {
  -    <SET_DIRECTIVE>  
  -    [ LOOKAHEAD(2) <WHITESPACE> ] 
  +    <SET_DIRECTIVE>
  +    [ LOOKAHEAD(2) <WHITESPACE> ]
       ( <LPAREN> Expression() <RPAREN>
  -    { 
  +    {
           /*
            * ensure that inSet is false.  Leads to some amusing bugs...
            */
  -    
  -        token_source.inSet = false; 
  +
  +        token_source.inSet = false;
       }
       [<NEWLINE>] )
  -}    
  +}
   
   /**
    * This method corresponds to the #stop
  @@ -1436,14 +1436,14 @@
    * purposes.
    */
   void StopStatement() #void: {}
  -{    
  +{
       <STOP_DIRECTIVE>
   }
   
   /* -----------------------------------------------------------------------
  - * 
  + *
    *  Expression Syntax
  - * 
  + *
    * ----------------------------------------------------------------------*/
   
   void Expression() : {}
  @@ -1473,20 +1473,20 @@
   void EqualityExpression() #void : {}
   {
       RelationalExpression()
  -    (           
  +    (
          <LOGICAL_EQUALS> RelationalExpression()     #EQNode(2)
  -     | <LOGICAL_NOT_EQUALS> RelationalExpression() #NENode(2)    
  +     | <LOGICAL_NOT_EQUALS> RelationalExpression() #NENode(2)
       )*
   }
   
   void RelationalExpression() #void : {}
   {
  -    AdditiveExpression() 
  +    AdditiveExpression()
       (
           <LOGICAL_LT>  AdditiveExpression() #LTNode(2)
         | <LOGICAL_GT>  AdditiveExpression() #GTNode(2)
         | <LOGICAL_LE>  AdditiveExpression() #LENode(2)
  -      | <LOGICAL_GE>  AdditiveExpression() #GENode(2)  
  +      | <LOGICAL_GE>  AdditiveExpression() #GENode(2)
       )*
   }
   
  @@ -1495,7 +1495,7 @@
       MultiplicativeExpression()
       (
           <PLUS>  MultiplicativeExpression() #AddNode(2)
  -      | <MINUS> MultiplicativeExpression() #SubtractNode(2)    
  +      | <MINUS> MultiplicativeExpression() #SubtractNode(2)
       )*
   }
   
  @@ -1512,17 +1512,17 @@
   void UnaryExpression() #void : {}
   {
        LOOKAHEAD(2)  [<WHITESPACE>]  <LOGICAL_NOT>  UnaryExpression() #NotNode(1)
  -|   PrimaryExpression() 
  +|   PrimaryExpression()
   }
   
   void PrimaryExpression() #void : {}
  -{  
  -    [<WHITESPACE>] 
  -    (  
  +{
  +    [<WHITESPACE>]
  +    (
        StringLiteral()
  -    | NumberLiteral()    
  +    | NumberLiteral()
       | Reference()
  -    | LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()     
  +    | LOOKAHEAD(  <LBRACKET> [<WHITESPACE>]    ( Reference() | NumberLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()
       | ObjectArray()
       | True()
       | False()
  @@ -1533,53 +1533,53 @@
   
   
   /* ======================================================================
  - 
  +
      Notes
      -----
  - 
  -    template == the input stream for this parser, contains 'VTL' 
  +
  +    template == the input stream for this parser, contains 'VTL'
       mixed in with 'schmoo'
  -    
  +
       VTL == Velocity Template Language : the references, directives, etc
  -    
  +
       shmoo == the non-VTL component of a template
  -    
  +
       reference == VTL entity that represents data within the context. ex. $foo
  -    
  +
       directive == VTL entity that denotes 'action' (#set, #foreach, #if )
  -    
  -    defined directive (DD) == VTL directive entity that is expressed 
  +
  +    defined directive (DD) == VTL directive entity that is expressed
       explicitly w/in this grammar
  -    
  -    pluggable directive (PD) == VTL directive entity that is defined outside of the 
  +
  +    pluggable directive (PD) == VTL directive entity that is defined outside of the
       grammar.  PD's allow VTL to be easily expandable w/o parser modification.
  - 
  -    The problem with parsing VTL is that an input stream consists generally of 
  -    little bits of VTL mixed in with 'other stuff, 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. It must simply output the schmoo and keep going.  
  - 
  +
  +    The problem with parsing VTL is that an input stream consists generally of
  +    little bits of VTL mixed in with 'other stuff, 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. It must simply output the schmoo and keep going.
  +
       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(), 
  +     - define the VTL grammar, expressed (mostly) in the productions such as Text(),
        SetStatement(), etc.
  -   
  -    It is clear that this expression of the VTL grammar (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 
  +
  +    It is clear that this expression of the VTL grammar (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 :  This is the base or starting state, and strangely enough, the
       default state.
  - 
  -    PRE_DIRECTIVE : State immediately following '#' before we figure out which 
  +
  +    PRE_DIRECTIVE : State immediately following '#' before we figure out which
       defined or pluggable directive (or neither) we are working with.
  -     
  +
       DIRECTIVE : This state is triggered by the a match of a DD or a PD.
   
       REFERENCE : Triggered by '$'. Analagous to PRE_DIRECTIVE.
  @@ -1587,51 +1587,51 @@
       REFMODIFIER : Triggered by .<alpha> when in REFERENCE.
   
       REFMOD2 : Triggered by ( when in REFMODIFIER
  - 
  +
       (cont)
   
       Escape Sequences
       ----------------
  -    The escape processing in VTL is very simple.  The '\' character acts 
  +    The escape processing in VTL is very simple.  The '\' character acts
       only as an escape when :
  -    
  +
           1) On or more touch a VTL element.
   
       A VTL element is either :
   
           1) It preceeds a reference that is in the context.
   
  -        2) It preceeds a defined directive (#set, #if, #end, etc) or a valid 
  +        2) It preceeds a defined directive (#set, #if, #end, etc) or a valid
           pluggable directive, such as #foreach
   
  -    In all other cases the '\' is just another piece of text.  The purpose of this 
  -    is to allow the non-VTL parts of a template (the 'schmoo') to not have to be 
  +    In all other cases the '\' is just another piece of text.  The purpose of this
  +    is to allow the non-VTL parts of a template (the 'schmoo') to not have to be
       altered for processing by Velocity.
   
  -    So if in the context $foo and $bar were defined and $woogie was not 
  -        
  +    So if in the context $foo and $bar were defined and $woogie was not
  +
           \$foo  \$bar \$woogie
   
       would output
   
           $foo  $bar  \$woogie
   
  -    Further, you can stack them and they affect left to right, just like convention 
  +    Further, you can stack them and they affect left to right, just like convention
       escape characters in other languages.
   
           \$foo = $foo
           \\$foo = \<foo>
           \\\$foo = \$foo
   
  -    
  +
       What You Expect
       ---------------
  -    The recent versions of the parser are trying to support precise output to 
  -    support general template use. The directives do not render trailing 
  -    whitespace and newlines if followed by a newline.  They will render 
  -    preceeding whitespace. The only exception is #set, which also eats 
  +    The recent versions of the parser are trying to support precise output to
  +    support general template use. The directives do not render trailing
  +    whitespace and newlines if followed by a newline.  They will render
  +    preceeding whitespace. The only exception is #set, which also eats
       preceeding whitespace.
  - 
  +
       So, with a template :
   
           ------
  @@ -1648,4 +1648,4 @@
           ------
   
   */
  - 
  +
  
  
  
  1.50      +14 -14    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.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- ParserTokenManager.java	22 Feb 2002 21:40:38 -0000	1.49
  +++ ParserTokenManager.java	23 Mar 2002 13:38:32 -0000	1.50
  @@ -111,8 +111,8 @@
       private void RPARENHandler()
       {
           /*
  -         *  Ultimately, we want to drop down to the state below 
  -         *  the one that has an open (if we hit bottom (DEFAULT), 
  +         *  Ultimately, we want to drop down to the state below
  +         *  the one that has an open (if we hit bottom (DEFAULT),
            *  that's fine. It's just text schmoo.
            */
   
  @@ -124,15 +124,15 @@
           while( !closed )
           {
               /*
  -             * look at current state.  If we haven't seen a lparen 
  -             * in this state then we drop a state, because this 
  +             * look at current state.  If we haven't seen a lparen
  +             * in this state then we drop a state, because this
                * lparen clearly closes our state
                */
   
               if( lparen > 0)
               {
                   /*
  -                 *  if rparen + 1 == lparen, then this state is closed. 
  +                 *  if rparen + 1 == lparen, then this state is closed.
                    * Otherwise, increment and keep parsing
                    */
   
  @@ -3558,7 +3558,7 @@
            else
               image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
           /*
  -         * push every terminator character back into the stream  
  +         * push every terminator character back into the stream
            */
   
           input_stream.backup(1);
  @@ -3696,9 +3696,9 @@
           if (! inComment)
           {
               /*
  -             * We can have the situation where #if($foo)$foo#end.  
  -             * We need to transition out of REFERENCE before going to DIRECTIVE. 
  -             * I don't really like this, but I can't think of a legal way 
  +             * We can have the situation where #if($foo)$foo#end.
  +             * We need to transition out of REFERENCE before going to DIRECTIVE.
  +             * I don't really like this, but I can't think of a legal way
                * you are going into DIRECTIVE while in REFERENCE.  -gmj
                */
   
  @@ -3734,7 +3734,7 @@
               lparen++;
   
           /*
  -         * If in REFERENCE and we have seen the dot, then move 
  +         * If in REFERENCE and we have seen the dot, then move
            * to REFMOD2 -> Modifier()
            */
   
  @@ -3755,7 +3755,7 @@
               image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
           /*
            * need to simply switch back to REFERENCE, not drop down the stack
  -         * because we can (infinitely) chain, ala 
  +         * because we can (infinitely) chain, ala
            * $foo.bar().blargh().woogie().doogie()
            */
   
  @@ -3808,7 +3808,7 @@
            else
               image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
           /*
  -         *  - if we are in DIRECTIVE and haven't seen ( yet, then also drop out. 
  +         *  - if we are in DIRECTIVE and haven't seen ( yet, then also drop out.
            *      don't forget to account for the beloved yet wierd #set
            *  - finally, if we are in REFMOD2 (remember : $foo.bar( ) then " is ok!
            */
  @@ -3892,14 +3892,14 @@
            else
               image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
           /*
  -         * push the alpha char back into the stream so the following identifier 
  +         * push the alpha char back into the stream so the following identifier
            * is complete
            */
   
           input_stream.backup(1);
   
           /*
  -         * and munge the <DOT> so we just get a . when we have normal text that 
  +         * and munge the <DOT> so we just get a . when we have normal text that
            * looks like a ref.ident
            */
   
  
  
  
  1.5       +8 -6      jakarta-velocity/src/java/org/apache/velocity/runtime/parser/node/ASTEscape.java
  
  Index: ASTEscape.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity/src/java/org/apache/velocity/runtime/parser/node/ASTEscape.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ASTEscape.java	19 Mar 2001 18:33:09 -0000	1.4
  +++ ASTEscape.java	23 Mar 2002 13:38:32 -0000	1.5
  @@ -59,6 +59,7 @@
   
   import org.apache.velocity.context.InternalContextAdapter;
   import org.apache.velocity.runtime.parser.Parser;
  +import org.apache.velocity.runtime.parser.Token;
   
   /**
    * This class is responsible for handling Escapes
  @@ -68,13 +69,14 @@
    * what controls the generation of this class.
    *
    * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  - * @version $Id: ASTEscape.java,v 1.4 2001/03/19 18:33:09 geirm Exp $ 
  + * @version $Id: ASTEscape.java,v 1.5 2002/03/23 13:38:32 geirm Exp $ 
    */
   public class ASTEscape extends SimpleNode 
   {
  -    private String text = "";
  -  
  -    public ASTEscape(int id) 
  +    public String val;
  +    private char[] ctext;
  +
  +    public ASTEscape(int id)
       {
           super(id);
       }
  @@ -93,14 +95,14 @@
       public Object init( InternalContextAdapter context, Object data) 
           throws Exception
       {
  -        text =  getFirstToken().image;
  +        ctext =  val.toCharArray();
           return data;
       }
   
       public boolean render( InternalContextAdapter context, Writer writer)
           throws IOException
       {
  -        writer.write( text );
  +        writer.write(ctext);
           return true;
       }
   }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>