⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.jj

📁 velocity官方工具包 包括各种JAR包 示例 文档等
💻 JJ
📖 第 1 页 / 共 5 页
字号:
|   <#ALPHANUM_CHAR: [ "a"-"z", "A"-"Z", "0"-"9" ] >
|   <#IDENTIFIER_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "-", "_" ] >
|   <IDENTIFIER:  ( <ALPHA_CHAR> | ["_"]) (<IDENTIFIER_CHAR>)* >
|   <DOT: "." <ALPHA_CHAR>>
    {
        /*
         * push the alpha char back into the stream so the following identifier
         * is complete
         */

        input_stream.backup(1);

        /*
         * and munge the <DOT> so we just get a . when we have normal text that
         * looks like a ref.ident
         */

        matchedToken.image = ".";

        if ( debugPrint )
            System.out.print("DOT : switching to " + REFMODIFIER);
        SwitchTo(REFMODIFIER);

    }
}


<REFERENCE,REFMODIFIER>
TOKEN :
{
    <LCURLY: "{">
|   <RCURLY: "}">
    {
        stateStackPop();
    }
}

<REFERENCE,REFMODIFIER,REFMOD2>
SPECIAL_TOKEN :
{
    <REFERENCE_TERMINATOR: ~[] >
    {
        /*
         * push every terminator character back into the stream
         */

        input_stream.backup(1);

        inReference = false;

        if ( debugPrint )
            System.out.print("REF_TERM :");

        stateStackPop();
    }
}

<PRE_DIRECTIVE>
SPECIAL_TOKEN :
{
    <DIRECTIVE_TERMINATOR: ~[] >
    {
        if ( debugPrint )
            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
 * the template has been turned into an AST,
 * this method returns the root of AST which
 * can subsequently be traversed by a visitor
 * which implements the ParserVisitor interface
 * which is generated automatically by JavaCC
 */
SimpleNode process() : {/*@bgen(jjtree) process */
  ASTprocess jjtn000 = new ASTprocess(this, JJTPROCESS);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) process */
   try {
/*@egen*/
   ( Statement() )* <EOF>/*@bgen(jjtree)*/
   {
     jjtree.closeNodeScope(jjtn000, true);
     jjtc000 = false;
   }
/*@egen*/
   { 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*/
}

/**
 * These are the types of statements that
 * are acceptable in Velocity templates.
 */
void Statement()       : {}
{
    IfStatement()
|   StopStatement()
|   LOOKAHEAD(2) Reference()
|   Comment()
|   SetDirective()
|   EscapedDirective()
|   Escape()
|   Directive()
|   Text()
}

/**
 *  used to separate the notion of a valid directive that has been
 *  escaped, versus something that looks like a directive and
 *  is just schmoo.  This is important to do as a separate production
 *  that creates a node, because we want this, in either case, to stop
 *  the further parsing of the Directive() tree.
 */
void EscapedDirective() : {/*@bgen(jjtree) EscapedDirective */
  ASTEscapedDirective jjtn000 = new ASTEscapedDirective(this, JJTESCAPEDDIRECTIVE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) EscapedDirective */
    try {
/*@egen*/
    {
        Token t = null;
    }

    t = <ESCAPE_DIRECTIVE>/*@bgen(jjtree)*/
    {
      jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
    }
/*@egen*/
    {
        /*
         *  churn and burn..
         */
        t.image = escapedDirective( t.image );
    }/*@bgen(jjtree)*/
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

/**
 *  Used to catch and process escape sequences in grammatical constructs
 *  as escapes outside of VTL are just characters.  Right now we have both
 *  this and the EscapeDirective() construction because in the EscapeDirective()
 *  case, we want to suck in the #<directive> and here we don't.  We just want
 *  the escapes to render correctly
 */
void Escape() : {/*@bgen(jjtree) Escape */
  ASTEscape jjtn000 = new ASTEscape(this, JJTESCAPE);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Escape */
    try {
/*@egen*/
    {
        Token t = null;
        int count = 0;
        boolean control = false;
    }

   ( LOOKAHEAD(2)  t = <DOUBLE_ESCAPE>
    {
        count++;
    }
   )+/*@bgen(jjtree)*/
    {
      jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
    }
/*@egen*/
    {
        /*
         * first, check to see if we have a control directive
         */
        switch(t.next.kind ) {
            case IF_DIRECTIVE :
            case ELSE_DIRECTIVE :
            case ELSEIF_DIRECTIVE :
            case END :
            case STOP_DIRECTIVE :
                control = true;
                break;
        }

        /*
         * if that failed, lets lookahead to see if we matched a PD or a VM
         */

        if ( isDirective( t.next.image.substring(1)))
            control = true;
        else if ( rsvc.isVelocimacro( t.next.image.substring(1), currentTemplateName))
            control = true;

        jjtn000.val = "";

        for( int i = 0; i < count; i++)
            jjtn000.val += ( control ? "\\" : "\\\\");
    }/*@bgen(jjtree)*/
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/

}

void Comment() : {/*@bgen(jjtree) Comment */
  ASTComment jjtn000 = new ASTComment(this, JJTCOMMENT);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Comment */
        try {
/*@egen*/
	<SINGLE_LINE_COMMENT_START> ( <SINGLE_LINE_COMMENT> ) ?
|   <MULTI_LINE_COMMENT>
|   <FORMAL_COMMENT>/*@bgen(jjtree)*/
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

void FloatingPointLiteral() : {/*@bgen(jjtree) FloatingPointLiteral */
  ASTFloatingPointLiteral jjtn000 = new ASTFloatingPointLiteral(this, JJTFLOATINGPOINTLITERAL);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) FloatingPointLiteral */
    try {
/*@egen*/
    <FLOATING_POINT_LITERAL>/*@bgen(jjtree)*/
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

void IntegerLiteral() : {/*@bgen(jjtree) IntegerLiteral */
  ASTIntegerLiteral jjtn000 = new ASTIntegerLiteral(this, JJTINTEGERLITERAL);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) IntegerLiteral */
     try {
/*@egen*/
     <INTEGER_LITERAL>/*@bgen(jjtree)*/
     } finally {
       if (jjtc000) {
         jjtree.closeNodeScope(jjtn000, true);
       }
     }
/*@egen*/
}

void StringLiteral() : {/*@bgen(jjtree) StringLiteral */
  ASTStringLiteral jjtn000 = new ASTStringLiteral(this, JJTSTRINGLITERAL);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) StringLiteral */
    try {
/*@egen*/
    <STRING_LITERAL>/*@bgen(jjtree)*/
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

/**
 * This method corresponds to variable
 * references in Velocity templates.
 * The following are examples of variable
 * references that may be found in a
 * template:
 *
 * $foo
 * $bar
 *
 */
void Identifier() : {/*@bgen(jjtree) Identifier */
  ASTIdentifier jjtn000 = new ASTIdentifier(this, JJTIDENTIFIER);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Identifier */
    try {
/*@egen*/
    <IDENTIFIER>/*@bgen(jjtree)*/
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

void Word() : {/*@bgen(jjtree) Word */
  ASTWord jjtn000 = new ASTWord(this, JJTWORD);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) Word */
    try {
/*@egen*/
    <WORD>/*@bgen(jjtree)*/
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

/**
 *   Supports the arguments for the Pluggable Directives
 */
int DirectiveArg()       : {}
{
    Reference()
    {
        return ParserTreeConstants.JJTREFERENCE;
    }
|   Word()
    {
        return ParserTreeConstants.JJTWORD;
    }
|   StringLiteral()
    {
        return ParserTreeConstants.JJTSTRINGLITERAL;
    }

|   IntegerLiteral()
    {
        return ParserTreeConstants.JJTINTEGERLITERAL;
    }
    /*
     * Need to put this before the floating point expansion
     */
|   LOOKAHEAD(  <LBRACKET> [<WHITESPACE>] ( Reference() | IntegerLiteral())     [<WHITESPACE>] <DOUBLEDOT> ) IntegerRange()
    {
        return ParserTreeConstants.JJTINTEGERRANGE;
    }
|   FloatingPointLiteral()
    {
        return ParserTreeConstants.JJTFLOATINGPOINTLITERAL;
    }
|   Map()
    {
        return ParserTreeConstants.JJTMAP;
    }
|   ObjectArray()
    {
        return ParserTreeConstants.JJTOBJECTARRAY;
    }
|   True()
    {
        return ParserTreeConstants.JJTTRUE;
    }
|   False()
    {
        return ParserTreeConstants.JJTFALSE;
    }
}

/**
 *   Supports the Pluggable Directives
 *     #foo( arg+ )
 */
SimpleNode Directive() :
{/*@bgen(jjtree) Directive */
    ASTDirective jjtn000 = new ASTDirective(this, JJTDIRECTIVE);
    boolean jjtc000 = true;
    jjtree.openNodeScope(jjtn000);
/*@egen*/
    Token t = null;
    int argType;
    int argPos = 0;
    Directive d;
    int directiveType;
    boolean isVM = false;
    boolean doItNow = false;
}
{/*@bgen(jjtree) Directive */
    try {
/*@egen*/

    /*
     * note that if we were escaped, that is now handled by
     * EscapedDirective()
     */

    ((t = <WORD>) | (t = <BRACKETED_WORD>))
    {
        String directiveName;
        if (t.kind == ParserConstants.BRACKETED_WORD)
	{
            directiveName = t.image.substring(2,t.image.length() - 1);
        }
        else
        {
            directiveName = t.image.substring(1);
        }

        d = (Directive) directives.get(directiveName);

        /*
         *  Velocimacro support : if the directive is macro directive
         *   then set the flag so after the block parsing, we add the VM
         *   right then. (So available if used w/in the current template )
         */

        if (directiveName.equals("macro"))
        {
             doItNow = true;
        }

        /*
         * set the directive name from here.  No reason for the thing to know
         * about parser tokens
         */

        jjtn000.setDirectiveName(directiveName);

        if ( d == null)
        {
            /*
             *  if null, then not a real directive, but maybe a Velocimacro
             */

            isVM = rsvc.isVelocimacro(directiveName, currentTemplateName);

            if (!isVM)
            {
                token_source.stateStackPop();
                token_source.inDirective = false;
                return jjtn000;
            }


            /*
             *  Currently, all VMs are LINE directives
             */

            directiveType = Directive.LINE;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -