geirm 00/11/07 13:29:42
Modified: src/java/org/apache/velocity/runtime/parser Parser.jjt
Log:
Changes to support what I hope is the final and correct version of escape handling.
Revision Changes Path
1.25 +72 -21
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.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- Parser.jjt 2000/11/06 04:12:42 1.24
+++ Parser.jjt 2000/11/07 21:29:37 1.25
@@ -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.24 2000/11/06 04:12:42 geirm Exp $
+ * @version $Id: Parser.jjt,v 1.25 2000/11/07 21:29:37 geirm Exp $
*/
public class Parser
{
@@ -349,6 +349,14 @@
return;
}
+ /**
+ * Produces a processed output for an escaped control directive
+ */
+ private String escapedDirective( String strImage, String strDirective )
+ {
+ int iLast = strImage.lastIndexOf("\\");
+ return ( strImage.substring(0,iLast/2) + strDirective);
+ }
/**
* handles the dropdown logic when encountering a RPAREN
@@ -487,25 +495,44 @@
/*
* 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.
- * And we don't want to try an and deal with this w/in the AST.
+ *
+ * We need to touch the ASTs for these, because we want an even # of \'s
+ * to render properly in front of the block
*
* This is really simplistic. I actually would prefer to find them in
* grammatical context, but I am neither smart nor rested, a receipe
* for disaster, another long night with Mr. Parser, or both.
*/
+
+ <ESCAPE_SET_DIRECTIVE : ("\\\\")* "\\#set">
+ {
+ matchedToken.image = escapedDirective( matchedToken.image, "#set");
+ }
+
+| <ESCAPE_IF_DIRECTIVE : ("\\\\")* "\\#if">
+ {
+ matchedToken.image = escapedDirective( matchedToken.image, "#if");
+ }
+
+| <ESCAPE_END_DIRECTIVE : ("\\\\")* "\\#end">
+ {
+ matchedToken.image = escapedDirective( matchedToken.image, "#end");
+ }
+
+| <ESCAPE_ELSEIF_DIRECTIVE: ("\\\\")* "\\#elseif">
+ {
+ matchedToken.image = escapedDirective( matchedToken.image, "#elseif");
+ }
+
+| <ESCAPE_ELSE_DIRECTIVE: ("\\\\")* "\\#else">
+ {
+ matchedToken.image = escapedDirective( matchedToken.image, "#else");
+ }
- <ESCAPE_SET_DIRECTIVE : "\\#set">
- { matchedToken.image = "#set"; }
-| <ESCAPE_IF_DIRECTIVE : "\\#if">
- { matchedToken.image = "#if"; }
-| <ESCAPE_END_DIRECTIVE : "\\#end">
- { matchedToken.image = "#end"; }
-| <ESCAPE_ELSEIF_DIRECTIVE: "\\#elseif">
- { matchedToken.image = "#elseif"; }
-| <ESCAPE_ELSE_DIRECTIVE: "\\#else">
- { matchedToken.image = "#else"; }
-| <ESCAPE_STOP_DIRECTIVE: "\\#stop">
- { matchedToken.image = "#stop"; }
+| <ESCAPE_STOP_DIRECTIVE: ("\\\\")* "\\#stop">
+ {
+ matchedToken.image = escapedDirective( matchedToken.image, "#stop");
+ }
}
@@ -517,7 +544,7 @@
*/
TOKEN:
{
- <SET_DIRECTIVE: (" "|"\t")* "#set" >
+ <SET_DIRECTIVE: (" "|"\t")* ("\\\\")* "#set" >
{
if (! inComment)
{
@@ -540,7 +567,7 @@
* Note : DOLLARBANG is a duplicate of DOLLAR. They must be identical.
*/
- <DOLLAR: ("\\")? "$">
+ <DOLLAR: ("\\")* "$">
{
if (! inComment)
{
@@ -581,7 +608,6 @@
inComment = true;
stateStackPush();
SwitchTo( IN_FORMAL_COMMENT);
- // was : IN_FORMAL_COMMENT
}
| "#*"
@@ -591,7 +617,7 @@
SwitchTo( IN_MULTI_LINE_COMMENT );
}
-| <HASH : ("\\")? "#">
+| <HASH : ("\\")* "#" >
{
if (! inComment)
{
@@ -975,7 +1001,17 @@
t = <WORD>
{
- if( t.image.startsWith("\\"))
+ /*
+ * We need to count the preceeding \'s. If t starts with an odd number of
\'s...
+ */
+
+ int i = 0;
+ int iLen = t.image.length();
+
+ while( i < iLen && t.image.charAt(i) == '\\' )
+ i++;
+
+ if( t.image.startsWith("\\") && (i % 2) != 0 )
{
token_source.stateStackPop();
token_source.inDirective = false;
@@ -983,7 +1019,7 @@
}
else
{
- d = (Directive) directives.get(t.image.substring(1));
+ d = (Directive) directives.get(t.image.substring(i+1));
if (d == null)
{
@@ -1011,7 +1047,7 @@
*/
( Statement() )+ #Block
- <END>
+ EndStatement()
{
return jjtThis;
}
@@ -1105,6 +1141,11 @@
( Statement() )+ #Block
[ LOOKAHEAD(1) ( ElseIfStatement() )+ ]
[ LOOKAHEAD(1) ElseStatement() ]
+ EndStatement()
+}
+
+void EndStatement() : {}
+{
<END>
}
@@ -1276,6 +1317,10 @@
----------------
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
pluggable directive,
@@ -1291,6 +1336,12 @@
would output
$foo $bar \$woogie
+
+ 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