geirm       00/11/04 21:46:18

  Modified:    src/java/org/apache/velocity/runtime/parser Parser.jjt
  Log:
  Symmetrized DIRECTIVE making it similar to REFERENCE by creating a PRE_DIRECTIVE 
state.
  Through it, we easily limit the token set when trying to match a DD or PD.  
Strangely, it happened to fix a few subtle bugs on my list as well...
  
  Revision  Changes    Path
  1.20      +71 -29    
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.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- Parser.jjt        2000/11/05 03:16:37     1.19
  +++ Parser.jjt        2000/11/05 05:46:18     1.20
  @@ -127,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.19 2000/11/05 03:16:37 geirm Exp $ 
  + * @version $Id: Parser.jjt,v 1.20 2000/11/05 05:46:18 geirm Exp $ 
   */
   public class Parser
   {
  @@ -178,8 +178,8 @@
          // try {
          //     n = process();
          // } catch (Exception e ) { System.out.println( e ); }   
  -       // 
  -       //  return n;
  +       //  
  +       // return n;
       }        
   
       public void setDirectives(Hashtable directives)
  @@ -608,9 +608,10 @@
                   System.out.print("# :  going to " + DIRECTIVE );
               
               stateStackPush();
  -            SwitchTo(DIRECTIVE);
  +            SwitchTo(PRE_DIRECTIVE);
           }
       } 
  +
   }   
   
   TOKEN :
  @@ -746,7 +747,7 @@
   |   <EQUALS: "=" >
   }
   
  -<DIRECTIVE> 
  +<PRE_DIRECTIVE> 
   TOKEN :
   {
       <END: "end" ( "\n" | "\r" | "\r\n" )?> 
  @@ -758,11 +759,18 @@
   |   <INCLUDE_DIRECTIVE: "include"> 
       { 
           incMode = true; 
  +        SwitchTo(DIRECTIVE);
       }
   
   |   <IF_DIRECTIVE: "if">
  +    {
  +        SwitchTo(DIRECTIVE);
  +    }
   
   |   <ELSEIF_DIRECTIVE: "elseif">
  +    {
  +        SwitchTo(DIRECTIVE);
  +    }
   
   |   <ELSE_DIRECTIVE: "else"> 
        { 
  @@ -771,15 +779,22 @@
       } 
   
   |   <SET_DIRECTIVE: "set" >
  -    { inSet = true; }
  +    { 
  +        inSet = true; 
  +        SwitchTo(DIRECTIVE);
  +    }
   
   |   <STOP_DIRECTIVE: "stop">
       {
           matchedToken.kind = EOF;
           fileDepth = 0;
       }
  +}
   
  -|   <#DIGIT: [ "0"-"9" ] >
  +<PRE_DIRECTIVE,DIRECTIVE>
  +TOKEN:
  +{
  +   <#DIGIT: [ "0"-"9" ] >
   |   <NUMBER_LITERAL: (<DIGIT>)+ >
       {
           /*
  @@ -871,6 +886,20 @@
       }
   }
   
  +<PRE_DIRECTIVE> 
  +SPECIAL_TOKEN :
  +{
  +    <DIRECTIVE_TERMINATOR: ~[] >
  +    {
  +        if ( bDebugPrint_ )
  +            System.out.print("DIRECTIVE_TERM :");
  + 
  +        input_stream.backup(1); 
  +        inDirective = false;
  +        stateStackPop();       
  +    }
  +}
  +
   /**
    * This method is what starts the whole parsing
    * process. After the parsing is complete and
  @@ -990,6 +1019,8 @@
                   return jjtThis;
               }
           }            
  +
  +        token_source.SwitchTo( DIRECTIVE );
       }
   
       /*
  @@ -1097,7 +1128,7 @@
   
   void IfStatement() : {}
   {
  -     <IF_DIRECTIVE> <LPAREN> Expression() <RPAREN>
  +    <IF_DIRECTIVE> <LPAREN> Expression() <RPAREN>
       ( Statement() )+ #Block
       [ LOOKAHEAD(1) ( ElseIfStatement() )+ ]
       [ LOOKAHEAD(1) ElseStatement() ]
  @@ -1237,36 +1268,47 @@
   
   /* ======================================================================
    
  -   Background
  -   ----------
  +   Notes
  +   -----
    
  -   VTL == Velocity Template Language
  +    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 explicitly 
w/in this grammar
  +    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' (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.  
  +    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 :
  +    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.
  +    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.
  +    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 )
  -       - 
  +    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.
  +
  +    REFMODIFIER : Triggered by .<alpha> when in REFERENCE.
  +
  +    REFMOD2 : Triggered by ( when in REFMODIFIER
    
       (cont)
   
  
  
  

Reply via email to