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