📄 parser.jj
字号:
else
{
directiveType = d.getType();
}
/*
* now, switch us out of PRE_DIRECTIVE
*/
token_source.SwitchTo(DIRECTIVE);
argPos = 0;
}
/*
* if this is indeed a token, match the #foo ( arg ) pattern
*/
[<WHITESPACE>] <LPAREN> ( LOOKAHEAD(2) [<WHITESPACE>] [<COMMA> [<WHITESPACE>]]
argType = DirectiveArg()
{
if (argType == ParserTreeConstants.JJTWORD)
{
if (doItNow && argPos == 0)
{
/* if a VM and it's the 0th arg... ok */
;
}
else if( (t.image.equals("#foreach") || t.image.equals("#{foreach}") ) && argPos == 1)
{
/* if a foreach and it's the 2nd arg ok */
;
}
else
{
throw new MacroParseException("Invalid arg #"
+ argPos + " in "
+ (isVM ? "VM " : "directive " )
+ t.image, currentTemplateName, t);
}
}
else
{
if (doItNow && argPos == 0)
{
/* if a VM and it's the 0th arg, not ok */
throw new MacroParseException("Invalid first arg"
+ " in #macro() directive - must be a"
+ " word token (no \' or \" surrounding)", currentTemplateName, t);
}
}
argPos++;
}
)* [<WHITESPACE>] <RPAREN>
{
if (directiveType == Directive.LINE)
{
return jjtn000;
}
}/*@bgen(jjtree) Block */
{
ASTBlock jjtn001 = new ASTBlock(this, JJTBLOCK);
boolean jjtc001 = true;
jjtree.openNodeScope(jjtn001);
}
try {
/*@egen*/
/*
* and the following block if the PD needs it
*/
( Statement() )+/*@bgen(jjtree)*/
} catch (Throwable jjte001) {
if (jjtc001) {
jjtree.clearNodeScope(jjtn001);
jjtc001 = false;
} else {
jjtree.popNode();
}
if (jjte001 instanceof RuntimeException) {
throw (RuntimeException)jjte001;
}
if (jjte001 instanceof ParseException) {
throw (ParseException)jjte001;
}
throw (Error)jjte001;
} finally {
if (jjtc001) {
jjtree.closeNodeScope(jjtn001, true);
}
}
/*@egen*/
<END>/*@bgen(jjtree)*/
{
jjtree.closeNodeScope(jjtn000, true);
jjtc000 = false;
}
/*@egen*/
{
/*
* 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)
{
Macro.processAndRegister(rsvc, t, jjtn000, currentTemplateName);
}
/*
* VM : end
*/
return jjtn000;
}/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
/**
* for creating a map in a #set
*
* #set($foo = {$foo : $bar, $blargh : $thingy})
*/
void Map() : {/*@bgen(jjtree) Map */
ASTMap jjtn000 = new ASTMap(this, JJTMAP);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Map */
try {
/*@egen*/
<LEFT_CURLEY>
(
LOOKAHEAD(2) Parameter() <COLON> Parameter() (<COMMA> Parameter() <COLON> Parameter() )*
|
[ <WHITESPACE> ]
)
<RIGHT_CURLEY>/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
void ObjectArray() : {/*@bgen(jjtree) ObjectArray */
ASTObjectArray jjtn000 = new ASTObjectArray(this, JJTOBJECTARRAY);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) ObjectArray */
try {
/*@egen*/
<LBRACKET> [ Parameter() ( <COMMA> Parameter() )* ] <RBRACKET>/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
/**
* supports the [n..m] vector generator for use in
* the #foreach() to generate measured ranges w/o
* needing explicit support from the app/servlet
*/
void IntegerRange() : {/*@bgen(jjtree) IntegerRange */
ASTIntegerRange jjtn000 = new ASTIntegerRange(this, JJTINTEGERRANGE);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) IntegerRange */
try {
/*@egen*/
<LBRACKET> [<WHITESPACE>]
( Reference() | IntegerLiteral())
[<WHITESPACE>] <DOUBLEDOT> [<WHITESPACE>]
(Reference() | IntegerLiteral())
[<WHITESPACE>] <RBRACKET>/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
/**
* This method has yet to be fully implemented
* but will allow arbitrarily nested method
* calls
*/
void Parameter() : {}
{
[<WHITESPACE>]
(
StringLiteral()
| IntegerLiteral()
| LOOKAHEAD( <LBRACKET> [<WHITESPACE>] ( Reference() | IntegerLiteral()) [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()
| Map()
| ObjectArray()
| True()
| False()
| Reference()
| FloatingPointLiteral()
)
[ <WHITESPACE>]
}
/**
* This method has yet to be fully implemented
* but will allow arbitrarily nested method
* calls
*/
void Method() : {/*@bgen(jjtree) Method */
ASTMethod jjtn000 = new ASTMethod(this, JJTMETHOD);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Method */
try {
/*@egen*/
Identifier() <LPAREN> [ Parameter() ( <COMMA> Parameter() )* ] <REFMOD2_RPAREN>/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
void Reference() : {/*@bgen(jjtree) Reference */
ASTReference jjtn000 = new ASTReference(this, JJTREFERENCE);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Reference */
try {
/*@egen*/
/*
* A reference is either ${<FOO>} or $<FOO>
*/
(
<IDENTIFIER>
(LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ))*
)
|
(
<LCURLY>
<IDENTIFIER>
(LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ))*
<RCURLY>
)/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
void True() : {/*@bgen(jjtree) True */
ASTTrue jjtn000 = new ASTTrue(this, JJTTRUE);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) True */
try {
/*@egen*/
<TRUE>/*@bgen(jjtree)*/
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
void False() : {/*@bgen(jjtree) False */
ASTFalse jjtn000 = new ASTFalse(this, JJTFALSE);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) False */
try {
/*@egen*/
<FALSE>/*@bgen(jjtree)*/
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
/**
* This method is responsible for allowing
* all non-grammar text to pass through
* unscathed.
*/
void Text() : {/*@bgen(jjtree) Text */
ASTText jjtn000 = new ASTText(this, JJTTEXT);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Text */
try {
/*@egen*/
<TEXT>
| <DOT>
| <RPAREN>
| <LPAREN>
| <INTEGER_LITERAL>
| <FLOATING_POINT_LITERAL>
| <STRING_LITERAL>
| <ESCAPE>
| <LCURLY>
| <RCURLY>/*@bgen(jjtree)*/
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
}
}
/*@egen*/
}
/* -----------------------------------------------------------------------
*
* Defined Directive Syntax
*
* ----------------------------------------------------------------------*/
void IfStatement() : {/*@bgen(jjtree) IfStatement */
ASTIfStatement jjtn000 = new ASTIfStatement(this, JJTIFSTATEMENT);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) IfStatement */
try {
/*@egen*/
<IF_DIRECTIVE> [<WHITESPACE>] <LPAREN> Expression() <RPAREN>/*@bgen(jjtree) Block */
{
ASTBlock jjtn001 = new ASTBlock(this, JJTBLOCK);
boolean jjtc001 = true;
jjtree.openNodeScope(jjtn001);
}
try {
/*@egen*/
( Statement() )*/*@bgen(jjtree)*/
} catch (Throwable jjte001) {
if (jjtc001) {
jjtree.clearNodeScope(jjtn001);
jjtc001 = false;
} else {
jjtree.popNode();
}
if (jjte001 instanceof RuntimeException) {
throw (RuntimeException)jjte001;
}
if (jjte001 instanceof ParseException) {
throw (ParseException)jjte001;
}
throw (Error)jjte001;
} finally {
if (jjtc001) {
jjtree.closeNodeScope(jjtn001, true);
}
}
/*@egen*/
[ LOOKAHEAD(1) ( ElseIfStatement() )+ ]
[ LOOKAHEAD(1) ElseStatement() ]
<END>/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -