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

📄 parser.jj

📁 velocity官方工具包 包括各种JAR包 示例 文档等
💻 JJ
📖 第 1 页 / 共 5 页
字号:
    {
       RPARENHandler();
    }
}


<REFMOD2>
TOKEN:
{
    /*
     * in REFMOD2, we don't want to bind the whitespace and \n like we
     * do when closing a directive.
     */
    <REFMOD2_RPAREN: ")">
    {
        /*
         * need to simply switch back to REFERENCE, not drop down the stack
         * because we can (infinitely) chain, ala
         * $foo.bar().blargh().woogie().doogie()
         */

        SwitchTo( REFERENCE );
    }
}

/*----------------------------------------------
 *
 *  escape "\\" handling for the built-in directives
 *
 *--------------------------------------------- */
TOKEN:
{
    /*
     *  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.
     *
     *  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_DIRECTIVE :  (<DOUBLE_ESCAPE>)* "\\#" <WORD> >
}


/*
 * needed because #set is so wacky in it's desired behavior.  We want set
 * to eat any preceeding whitespace so it is invisible in formatting.
 * (As it should be.)  If this works well, I am going to chuck the whole MORE:
 * token abomination.
 */
TOKEN:
{
  <SET_DIRECTIVE: (" "|"\t")*  ("#set" | "#{set}")  (" ")* "(">
    {
        if (! inComment)
        {
            inDirective = true;

            if ( debugPrint )
                System.out.print("#set :  going to " + DIRECTIVE );

            stateStackPush();
            inSet = true;
            SwitchTo(DIRECTIVE);
        }

        /*
         *  need the LPAREN action
         */

        if (!inComment)
        {
            lparen++;

            /*
             * If in REFERENCE and we have seen the dot, then move
             * to REFMOD2 -> Modifier()
             */

            if (curLexState == REFMODIFIER )
                SwitchTo( REFMOD2 );
        }
   }
}

<*>
MORE :
{
    /*
     *   Note : DOLLARBANG is a duplicate of DOLLAR.  They must be identical.
     */

    <DOLLAR: ("\\")* "$">
    {
        if (! inComment)
        {
            /*
             * if we find ourselves in REFERENCE, we need to pop down
             * to end the previous ref
             */

            if (curLexState == REFERENCE)
            {
                inReference = false;
                stateStackPop();
            }

            inReference = true;

            if ( debugPrint )
                System.out.print( "$  : going to " + REFERENCE );

            stateStackPush();
            SwitchTo(REFERENCE);
        }
    }

|   <DOLLARBANG: ("\\")* "$" ("\\")* "!">
    {
        if (! inComment)
        {
            /*
             * if we find ourselves in REFERENCE, we need to pop down
             * to end the previous ref
             */

            if (curLexState == REFERENCE)
            {
                inReference = false;
                stateStackPop();
            }

            inReference = true;

            if ( debugPrint )
                System.out.print( "$!  : going to " + REFERENCE );

            stateStackPush();
            SwitchTo(REFERENCE);
        }
    }

|   <"#**" ~["#"]>
    {
        input_stream.backup(1);
        inComment = true;
        stateStackPush();
        SwitchTo( IN_FORMAL_COMMENT);
    }

|   "#*"
    {
        inComment=true;
        stateStackPush();
        SwitchTo( IN_MULTI_LINE_COMMENT );
    }

|   <HASH : "#" >
    {
        if (! inComment)
        {
            /*
             * We can have the situation where #if($foo)$foo#end.
             * We need to transition out of REFERENCE before going to DIRECTIVE.
             * I don't really like this, but I can't think of a legal way
             * you are going into DIRECTIVE while in REFERENCE.  -gmj
             */

            if (curLexState == REFERENCE || curLexState == REFMODIFIER )
            {
                inReference = false;
                stateStackPop();
            }

            inDirective = true;

            if ( debugPrint )
                System.out.print("# :  going to " + DIRECTIVE );

            stateStackPush();
            SwitchTo(PRE_DIRECTIVE);
        }
    }
}


// treat the single line comment case separately
// to avoid ##<EOF> errors
<*>
TOKEN :
{
   <SINGLE_LINE_COMMENT_START: "##">
   {
        if (!inComment)
        {
            if (curLexState == REFERENCE)
            {
                inReference = false;
                stateStackPop();
            }

            inComment = true;
            stateStackPush();
            SwitchTo(IN_SINGLE_LINE_COMMENT);
        }
     }
}

TOKEN :
{
    <DOUBLE_ESCAPE : "\\\\">
|   <ESCAPE: "\\" >
|   <TEXT: (~["$", "#", "\\"])+ >
}

/* -----------------------------------------------------------------------
 *
 *   *_COMMENT Lexical tokens
 *
 *-----------------------------------------------------------------------*/
<IN_SINGLE_LINE_COMMENT>
TOKEN :
{
  <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n">
  {
     inComment = false;
     stateStackPop();
  }

}

<IN_FORMAL_COMMENT>
TOKEN :
{
  <FORMAL_COMMENT: "*#" >
  {
    inComment = false;
    stateStackPop();
  }
}

<IN_MULTI_LINE_COMMENT>
TOKEN :
{
  <MULTI_LINE_COMMENT: "*#" >
  {
    inComment = false;
    stateStackPop();
  }
}

<IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
SKIP :
{
  < ~[] >
}

/* -----------------------------------------------------------------------
 *
 *  DIRECTIVE Lexical State (some of it, anyway)
 *
 * ---------------------------------------------------------------------- */

<DIRECTIVE,REFMOD2>
TOKEN:
{
    <WHITESPACE : ([" ","\t", "\n", "\r"])+ >
}

<DIRECTIVE,REFMOD2>
TOKEN :
{
//   <STRING_LITERAL: ( "\"" ( ~["\"","\n","\r"] )* "\"" ) | ( "'" ( ~["'","\n","\r"] )* "'" ) >
  < STRING_LITERAL:
      ("\""
        (   (~["\"","\\"])
          | ("\\"
              ( ["n","t","b","r","f","\\","'","\""]
              | ["0"-"7"] ( ["0"-"7"] )?
              | ["0"-"3"] ["0"-"7"] ["0"-"7"]
              )
            )
          | ( "\\" (" ")* "\n")
        )*
        "\""
      )
    |
    ("\'"
        (   (~["\'"])
          | ( "\\" (" ")* "\n")
        )*
        "\'"
      )
  >

    {
        /*
         *  - if we are in DIRECTIVE and haven't seen ( yet, then also drop out.
         *      don't forget to account for the beloved yet wierd #set
         *  - finally, if we are in REFMOD2 (remember : $foo.bar( ) then " is ok!
         */

         if( curLexState == DIRECTIVE && !inSet && lparen == 0)
            stateStackPop();
    }
}

<REFERENCE,DIRECTIVE,REFMODIFIER,REFMOD2>
TOKEN:
{
   <TRUE: "true">
|   <FALSE: "false">
}

<DIRECTIVE>
TOKEN :
{
    <NEWLINE: "\n" | "\r" | "\r\n" >
    {
        if ( debugPrint )
            System.out.println(" NEWLINE :");

        stateStackPop();

        if (inSet)
            inSet = false;

        if (inDirective)
            inDirective = false;
    }
}


<DIRECTIVE>
TOKEN :
{
    <MINUS: "-">
|   <PLUS: "+">
|   <MULTIPLY: "*">
|   <DIVIDE: "/">
|   <MODULUS: "%">
|   <LOGICAL_AND: "&&" | "and" >
|   <LOGICAL_OR: "||" | "or" >
|   <LOGICAL_LT: "<" | "lt" >
|   <LOGICAL_LE: "<=" | "le" >
|   <LOGICAL_GT: ">" | "gt" >
|   <LOGICAL_GE: ">=" | "ge" >
|   <LOGICAL_EQUALS: "==" | "eq" >
|   <LOGICAL_NOT_EQUALS: "!=" | "ne" >
|   <LOGICAL_NOT: "!" | "not" >
|   <EQUALS: "=" >
}

<PRE_DIRECTIVE>
TOKEN :
{
    <END: ( "end" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )? )
          | ("{end}" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )? ) >
    {
        inDirective = false;
        stateStackPop();
    }

|   <IF_DIRECTIVE: "if" | "{if}">
    {
        SwitchTo(DIRECTIVE);
    }

|   <ELSEIF_DIRECTIVE: "elseif" | "{elseif}">
    {
        SwitchTo(DIRECTIVE);
    }

|   <ELSE_DIRECTIVE:
          ( "else" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )? )
        | ( "{else}" ( ( " " | "\t" )* ( "\n" | "\r" | "\r\n" ) )? )  >
     {
        inDirective = false;
        stateStackPop();
    }

|   <STOP_DIRECTIVE: "stop" | "{stop}" >
    {
        inDirective = false;
        stateStackPop();
    }
}

<PRE_DIRECTIVE,DIRECTIVE,REFMOD2>
TOKEN:
{
   <#DIGIT: [ "0"-"9" ] >

    /*
     * treat FLOATING_POINT_LITERAL and INTEGER_LITERAL differently as a range can only handle integers.
     */

    /**
     * Note -- we also define an integer as ending with a double period,
     * in order to avoid 1..3 being defined as floating point (1.) then a period, then a integer
    */
|   <INTEGER_LITERAL: ("-")? (<DIGIT>)+ ("..")? >
    {

        /*
         * Remove the double period if it is there
         */
        if (matchedToken.image.endsWith("..")) {
            input_stream.backup(2);
            matchedToken.image = matchedToken.image.substring(0,matchedToken.image.length()-2);
        }

        /*
         * 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 && curLexState != REFMOD2)
        {
            stateStackPop();
        }
    }

|    <FLOATING_POINT_LITERAL:
        ("-")? (<DIGIT>)+ "." (<DIGIT>)* (<EXPONENT>)?
      | ("-")? "." (<DIGIT>)+ (<EXPONENT>)?
      | ("-")? (<DIGIT>)+ <EXPONENT>
    >
    {
        /*
         * 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 && curLexState != REFMOD2)
        {
            stateStackPop();
    }
}
|
    <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >

}

<PRE_DIRECTIVE,DIRECTIVE>
TOKEN:
{
    <#LETTER: [ "a"-"z", "A" - "Z" ] >
|   <#DIRECTIVE_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "_" ] >
|   <WORD:  ( <LETTER> | ["_"]) (<DIRECTIVE_CHAR>)* >
|   <BRACKETED_WORD:  "{" ( <LETTER> | ["_"]) (<DIRECTIVE_CHAR>)* "}" >

}




/* -----------------------------------------------------------------------
 *
 *  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 can be 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 :
{
    <#ALPHA_CHAR: ["a"-"z", "A"-"Z"] >

⌨️ 快捷键说明

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