geirm       00/11/01 19:53:04

  Modified:    src/java/org/apache/velocity/runtime/parser Parser.jjt
  Log:
  Fix for the "#000000" bug pointed out by Dave Bryson <[EMAIL PROTECTED]>.  To be 
fair, this
  was pointed out before, and Jason fixed it, but it got unfixed in my last big parser 
change-fest.
  I will add this and similar examples to diabolical.vm so I don't unfix this again. :)
  There is also some more comment work.
  
  Revision  Changes    Path
  1.15      +131 -75   
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.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- Parser.jjt        2000/11/02 01:24:49     1.14
  +++ Parser.jjt        2000/11/02 03:53:04     1.15
  @@ -53,24 +53,10 @@
    */
   
   /*
  - *  Background
  - *  ----------
  - *
  - *  VTL == Velocity Template Language
  - *
  - *  The problem with parsing VTL is that an input stream consists generally of 
little
  - *  bits of VTL mixed in with 'other stuff' (hereafter referred to as 'schmoo').  
Unlike
  - *  other languages, like C or Java, where the parser can punt whenever it 
encounters 
  - *  input that doesn't conform to the grammar, the VTL parser can't do that.  
  - *
  - *  There are a few things that we do here :
  - *    - define a set of parser states (DEFAULT, DIRECTIVE, REFERENCE, etc)
  - *    - define for each parser state a set of tokens for each state
  - *    - define the VTL grammar, expressed (mostly) in the productions such as 
Text(), SetStatement(), etc.
  - *  
  - *   (cont)
  + *  NOTE : please see documentation at bottom of this file. (It was placed there 
its tiring
  + *    to always have to page past it... :)
    */
  - 
  +
   options
   {
       /** The default package for this parser kit */
  @@ -141,7 +127,7 @@
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a>
    * @author <a href="mailto:[EMAIL PROTECTED]">Geir Magnusson Jr.</a>
  - * @version $Id: Parser.jjt,v 1.14 2000/11/02 01:24:49 geirm Exp $ 
  + * @version $Id: Parser.jjt,v 1.15 2000/11/02 03:53:04 geirm Exp $ 
   */
   public class Parser
   {
  @@ -181,7 +167,16 @@
       {
           token_source.clearStateVars();
           ReInit(stream);  
  -        return process();
  +    
  +       // return process();
  +
  +        SimpleNode n = null;
  +
  +        try {
  +            n = process();
  +        } catch (Exception e ) { System.out.println( e ); }
  +
  +        return n;
       }        
   
       public void setDirectives(Hashtable directives)
  @@ -470,12 +465,11 @@
               lparen++;
   
           /*
  -         *  if we have seen the dot, then move to REFMOD2 -> Modifier()
  +         *  if in REFERENCE and we have seen the dot, then move to REFMOD2 -> 
Modifier()
            */
   
           if (curLexState == REFMODIFIER )
  -            SwitchTo( REFMOD2 );
  -
  +            SwitchTo( REFMOD2 ); 
       }
   
   |   <RPAREN: ")" (" ")* ("\n")?>
  @@ -554,9 +548,8 @@
           SwitchTo( IN_MULTI_LINE_COMMENT ); 
       } 
   
  -
   |   <HASH : "#"> 
  -  { 
  +    { 
           if (! inComment)
           {
               inDirective = true;
  @@ -575,14 +568,12 @@
       <ESCAPE_SEQUENCE: "\\" ~[] >
   |   <TEXT: (~["$", "#", "\\"])+ >
   }    
  -
   
  -// -----------------------------------------------------------------------
  -// 
  -// COMMENT Lexical States
  -// 
  -// -----------------------------------------------------------------------
  -
  +/* -----------------------------------------------------------------------
  + * 
  + *   *_COMMENT Lexical tokens
  + *
  + *-----------------------------------------------------------------------*/
   <IN_SINGLE_LINE_COMMENT>
   TOKEN :
   {
  @@ -622,13 +613,12 @@
   {
     < ~[] >
   }
  -
  -// -----------------------------------------------------------------------
  -// 
  -// DIRECTIVE Lexical State
  -// 
  -// -----------------------------------------------------------------------
   
  +/* -----------------------------------------------------------------------
  + * 
  + *  DIRECTIVE Lexical State (some of it, anyway)
  + * 
  + * ---------------------------------------------------------------------- */
   <DIRECTIVE,REFMOD2> 
   SKIP:
   {
  @@ -638,6 +628,7 @@
   //|   "\r"
   }
   
  +
   <REFERENCE,DIRECTIVE,REFMODIFIER,REFMOD2>
   TOKEN :
   {
  @@ -691,6 +682,7 @@
       }        
   }    
   
  +
   <DIRECTIVE>
   TOKEN : 
   {
  @@ -721,7 +713,9 @@
       } 
   
   |   <INCLUDE_DIRECTIVE: "include"> 
  -    { incMode = true; }
  +    { 
  +        incMode = true; 
  +    }
   
   |   <IF_DIRECTIVE: "if">
   
  @@ -745,23 +739,41 @@
   |   <#DIGIT: [ "0"-"9" ] >
   |   <NUMBER_LITERAL: (<DIGIT>)+ >
       {
  -        //!!! fixed <bcolor="#333333"/>
  -        // needs to be more thorough.
  -       // if (lparen == 0)
  -       //     SwitchTo(DEFAULT);
  -    }            
  -    
  -    //!!! fixed #FFFFFF
  +        /*
  +         *  in the spirit of Jason's fix :)
  +         *  but check to see if we are in set
  +         *    ex.  #set $foo = $foo + 3
  +         *  because we want to handle the \n after
  +         */
  +
  +        if ( lparen == 0 && !inSet )
  +            stateStackPop();
  +    }
  +
   |   <#LETTER: [ "a"-"z", "A" - "Z" ] >
   |   <WORD: (<LETTER>)+ >
   }
  -
   
  -// -----------------------------------------------------------------------
  -// 
  -// REFERENCE Lexical State
  -// 
  -// -----------------------------------------------------------------------
  +/* -----------------------------------------------------------------------
  + * 
  + *  REFERENCE Lexical States
  + *
  + *  This is more than a single state, because of the  structure of
  + *  the VTL references.  We use three states because the set of tokens
  + *  for each state is different.
  + *
  + *  $foo.bar( "arg" )
  + *  ^   ^   ^
  + *  |   |   |
  + *  ----------- >  REFERENCE : state initiated by the '$' character.  Continues 
  + *      |   |       until end of the reference, or the . character.
  + *      |------ >  REFMODIFIER : state switched to when the <DOT> is encountered.
  + *          |       note that this is a switch, not a push. See notes at bottom
  + *          |       re stateStack.
  + *          |-- >  REFMOD2 : state switch to when the LPAREN is encountered.
  + *                  again, this is a switch, not a push.
  + *
  + * ---------------------------------------------------------------------------- */
   
   <REFERENCE,REFMODIFIER,REFMOD2> 
   TOKEN :
  @@ -792,7 +804,6 @@
   |   <LCURLY: "{">
   |   <RCURLY: "}">
       {
  -        // was :DEFAULT
           stateStackPop();
       }
   }
  @@ -849,23 +860,13 @@
      { return jjtThis; }
   }
   
  -// -----------------------------------------------------------------------
  -// 
  -// Statement Syntax
  -// 
  -// -----------------------------------------------------------------------
  -
   /**
    * These are the types of statements that
    * are acceptable in Velocity templates.
  - * I have not found that the order here
  - * matters much. Someone please correct
  - * me here if I'm wrong.
    */
  -
   void Statement() #void : {}
   {
  -   IfStatement()
  +    IfStatement()
   |   IncludeStatement()
   |   StopStatement()
   |   Reference()
  @@ -913,6 +914,10 @@
       <WORD>
   }    
   
  +/**
  + *   Supports the arguments for the Pluggable Directives
  + *   @see Directive()
  + */
   void DirectiveArg() #void : {}
   {
       Reference()
  @@ -922,12 +927,20 @@
   |   ObjectArray()
   }
   
  +/**
  + *   Supports the Pluggable Directives
  + *     #foo( arg+ )
  + */
   SimpleNode Directive() : 
   {
       Token t;
       Directive d;
   }
   {
  +    /*
  +     *  Get the directive identifier and check to see if this is a directive.
  +     *   Note that because '#' is a <MORE> token, the identifier is preceeded by 
the '#'
  +     */
       t = <WORD>
       {
           d = (Directive) directives.get(t.image.substring(1));
  @@ -940,11 +953,19 @@
           }            
       }
   
  +    /*
  +     *  if this is indeed a token, match the #foo ( arg ) pattern
  +     */
  +
       <LPAREN> (DirectiveArg())+ <RPAREN>
       {
           if (d.getType() == Directive.LINE)
               return jjtThis;
       }
  +
  +    /*
  +     *  and the following block if the PD needs it
  +     */
       
       ( Statement() )+ #Block 
       <END>
  @@ -984,7 +1005,6 @@
   
   void Reference() : {}
   { 
  -
       // This should be changed to Indentifier() now. Make
       // it easier to walk the AST.
       [<LCURLY>]
  @@ -1027,11 +1047,11 @@
   
   }
   
  -// -----------------------------------------------------------------------
  -// 
  -// Directive Syntax
  -// 
  -// -----------------------------------------------------------------------
  +/* -----------------------------------------------------------------------
  + * 
  + *  Defined Directive Syntax
  + * 
  + * ----------------------------------------------------------------------*/
   
   void IfStatement() : {}
   {
  @@ -1078,7 +1098,7 @@
    * This method corresponds to the #stop
    * directive which just simulates and EOF
    * so that parsing stops. The #stop directive
  - * is really only useful for debugging
  + * is useful for end-user debugging
    * purposes.
    */
   void StopStatement() #void: {}
  @@ -1086,11 +1106,11 @@
       <STOP_DIRECTIVE>
   }
   
  -// -----------------------------------------------------------------------
  -// 
  -// Expression Syntax
  -// 
  -// -----------------------------------------------------------------------
  +/* -----------------------------------------------------------------------
  + * 
  + *  Expression Syntax
  + * 
  + * ----------------------------------------------------------------------*/
   
   void Expression() : {}
   {
  @@ -1171,3 +1191,39 @@
   |   False()
   |   <LPAREN> Expression() <RPAREN>
   }
  +
  +
  +/* ======================================================================
  + *
  + *  Background
  + *  ----------
  + *
  + *  VTL == Velocity Template Language
  + *
  + *  The problem with parsing VTL is that an input stream consists generally of 
little
  + *  bits of VTL mixed in with 'other stuff' (hereafter referred to as 'schmoo').  
Unlike
  + *  other languages, like C or Java, where the parser can punt whenever it 
encounters 
  + *  input that doesn't conform to the grammar, the VTL parser can't do that.  
  + *
  + *  There are a few things that we do here :
  + *    - define a set of parser states (DEFAULT, DIRECTIVE, REFERENCE, etc)
  + *    - define for each parser state a set of tokens for each state
  + *    - define the VTL grammar, expressed (mostly) in the productions such as 
Text(), SetStatement(), etc.
  + *  
  + *  It is clear that this expression of the VTL grammer (the contents of this .jjt 
file) is maturing and
  + *  evolving as we learn more about how to parse VTL ( and as I learn about 
parsing...), so in the event 
  + *  this documentation is in disagreement w/ the source, the source takes 
precedence.
  + *
  + *  Parser States
  + *  -------------
  + *  DEFAULT :  This is the base or starting state, and strangely enough, the 
default state.
  + *
  + *  DIRECTIVE : This state is triggered by the '#' character, and is used when 
processing both
  + *     'defined' directives such as #if() #else #elseif() #end #set #foreach() as 
well as the 
  + *     so-called 'pluggable' directives (PDs), which include #foreach(), #macro() 
etc.  The
  + *     PDs are able to be implemented entirely outside of the parser.
  + *      - with the exception of #set, #else and #else, the 'shape' of a directive 
is  
  + *           #foo( optional args )
  + *      - 
  + */
  + 
  \ No newline at end of file
  
  
  

Reply via email to