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

📄 fmparser.jj

📁 freemaker安装软件
💻 JJ
📖 第 1 页 / 共 5 页
字号:
    |
    <ELSE_IF : <START_TAG> "elseif" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <LIST : <START_TAG> "list" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <FOREACH : <START_TAG> "foreach" <BLANK>>  {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <SWITCH : <START_TAG> "switch" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <CASE : <START_TAG> "case" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <ASSIGN : <START_TAG> "assign" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <GLOBALASSIGN : <START_TAG> "global" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <LOCALASSIGN : <START_TAG> "local" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <INCLUDE : <START_TAG> "include" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <IMPORT : <START_TAG> "import" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <FUNCTION : <START_TAG> "function" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <MACRO : <START_TAG> "macro" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <TRANSFORM : <START_TAG> "transform" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <VISIT : <START_TAG> "visit" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <STOP : <START_TAG> "stop" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <RETURN : <START_TAG> "return" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <CALL : <START_TAG> "call" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <SETTING : <START_TAG> "setting" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <COMPRESS : <START_TAG> "compress" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <COMMENT : <START_TAG> "comment" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, NO_PARSE); noparseTag="comment";}
    |
    <TERSE_COMMENT : ("<" | "[") "#--" > {noparseTag = "-->"; strictSyntaxCheck(matchedToken, NO_PARSE); }
    |
    <NOPARSE : <START_TAG> "noparse" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, NO_PARSE); noparseTag="noparse";}
    |
    <END_IF : <END_TAG> "if" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_LIST : <END_TAG> "list" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_RECOVER : <END_TAG> "recover" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_ATTEMPT : <END_TAG> "attempt" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_FOREACH : <END_TAG> "foreach" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_LOCAL : <END_TAG> "local" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_GLOBAL : <END_TAG> "global" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_ASSIGN : <END_TAG> "assign" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_FUNCTION : <END_TAG> "function" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_MACRO : <END_TAG> "macro" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_COMPRESS : <END_TAG> "compress" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_TRANSFORM : <END_TAG> "transform" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_SWITCH : <END_TAG> "switch" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <ELSE : <START_TAG> "else" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <BREAK : <START_TAG> "break" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <SIMPLE_RETURN : <START_TAG> "return" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <HALT : <START_TAG> "stop" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <FLUSH : <START_TAG> "flush" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <TRIM : <START_TAG> "t" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <LTRIM : <START_TAG> "lt" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <RTRIM : <START_TAG> "rt" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <NOTRIM : <START_TAG> "nt" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <DEFAUL : <START_TAG> "default" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <SIMPLE_NESTED : <START_TAG> "nested" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <NESTED : <START_TAG> "nested" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <SIMPLE_RECURSE : <START_TAG> "recurse" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <RECURSE : <START_TAG> "recurse" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <FALLBACK : <START_TAG> "fallback" <CLOSE_TAG2>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <ESCAPE : <START_TAG> "escape" <BLANK>> {strictSyntaxCheck(matchedToken, FM_EXPRESSION);}
    |
    <END_ESCAPE : <END_TAG> "escape" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <NOESCAPE : <START_TAG> "noescape" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <END_NOESCAPE : <END_TAG> "noescape" <CLOSE_TAG1>> {strictSyntaxCheck(matchedToken, DEFAULT);}
    |
    <UNIFIED_CALL : "<@" | "[@" >  {unifiedCall(matchedToken);}
    |
    <UNIFIED_CALL_END : ("<" | "[") "/@" ((<ID>) ("."<ID>)*)? <CLOSE_TAG1>> {unifiedCallEnd(matchedToken);}
    |
    <FTL_HEADER : ("<#ftl" | "[#ftl") <BLANK>> {ftlHeader(matchedToken);}
    |
    <TRIVIAL_FTL_HEADER : ("<#ftl" | "[#ftl") ("/")? (">" | "]")> {ftlHeader(matchedToken);}
    |
    <UNKNOWN_DIRECTIVE : ("[#" | "[/#" | "<#" | "</#") (["a"-"z","A"-"Z", "_"])+>
    {
       if (!directiveSyntaxEstablished) {
           matchedToken.kind = PRINTABLE_CHARS;
       } else {
           char firstChar = matchedToken.image.charAt(0);
           if (firstChar == '<' && altDirectiveSyntax) {
              matchedToken.kind = PRINTABLE_CHARS;
           } else if (firstChar == '[' && !altDirectiveSyntax) {
              matchedToken.kind = PRINTABLE_CHARS;
           }
           else if (strictEscapeSyntax) {
             String s = matchedToken.image;
             int index = s.indexOf('#');
             s = s.substring(index);
             String msg = "Unknown directive: " 
             + s
             + " on line: " + matchedToken.beginLine
             + ", column: " + matchedToken.beginColumn +1
             + ", in template: " + templateName;
             throw new TokenMgrError(msg, TokenMgrError.LEXICAL_ERROR);
           }
       } 
    }
}

<DEFAULT, NODIRECTIVE> TOKEN :
{
    <WHITESPACE : (["\n", "\r", "\t", " "])+>
    |
    <PRINTABLE_CHARS : (~["$", "<", "#", "[", "{", "\n", "\r", "\t", " "])+>
    |
    <FALSE_ALERT : "$" | "#" | "<" | "[" | "{"> // to handle a lone dollar sign or "<" or "# or <@ with whitespace after"
    |
    <OUTPUT_ESCAPE : "${"> : FM_EXPRESSION
    |
    <NUMERICAL_ESCAPE : "#{"> : FM_EXPRESSION
}

<FM_EXPRESSION, IN_PAREN> SKIP :
{
    < ( " " | "\t" | "\n" | "\r" )+ >
    |
    < ["<", "["] ["#", "!"] "--"> : EXPRESSION_COMMENT
}

<EXPRESSION_COMMENT> SKIP:
{
    < (~["-", ">", "]"])+ >
    |
    < ">">
    |
    < "]">
    |
    < "-">
    |
    < "-->" | "--]"> {if (parenthesisNesting >0) SwitchTo(IN_PAREN); else SwitchTo(FM_EXPRESSION);}
}

<FM_EXPRESSION, IN_PAREN, NO_SPACE_EXPRESSION> TOKEN :
{
  <#ESCAPED_CHAR :  "\\"
           (
             ["n","t","r","f","b","g","l","a","\\","'","\"","$"]
             |
             ("x" ["0"-"9","A"-"F","a"-"f"])
           )
  >
  | 
  <STRING_LITERAL :
      ("\""
        ((~["\"","\\"]) | <ESCAPED_CHAR>)*
      "\"")
      |
      ("'"
        ((~["'","\\"]) | <ESCAPED_CHAR>)*
      "'"
      )
  >
  |
  <RAW_STRING : "r" (("\"" (~["\""])* "\"") | ("'" (~["'"])* "'"))>
  |
  <FALSE : "false">
  |
  <TRUE : "true">
  |
  <INTEGER : (["0"-"9"])+>
  |
  <DECIMAL : <INTEGER> "." <INTEGER>>
  |
  <DOT : ".">
  |
  <DOT_DOT : "..">
  |
  <BUILT_IN : "?">
  |
  <EXISTS : "??">
  |
  <EQUALS : "=">
  |
  <DOUBLE_EQUALS : "==">
  |
  <NOT_EQUALS : "!=">
  |
  <LESS_THAN : "lt" | "\\lt" | "<" | "&lt;">
  |
  <LESS_THAN_EQUALS : "lte" | "\\lte" | "<=" | "&lt;=">
  |
  <ESCAPED_GT: "gt" | "\\gt" |  "&gt;">
  |
  <ESCAPED_GTE : "gte" | "\\gte" | "&gt;=">
  |
  <PLUS : "+">
  |
  <MINUS : "-">
  |
  <TIMES : "*">
  |
  <DOUBLE_STAR : "**">
  |
  <ELLIPSIS : "...">
  |
  <DIVIDE : "/">
  |
  <PERCENT : "%">
  |
  <AND : "&" | "&&" >
  |
  <OR : "|" | "||">
  |
  <EXCLAM : "!">
  |
  <COMMA : ",">
  |
  <SEMICOLON : ";">
  |
  <COLON : ":">
  |
  <OPEN_BRACKET : "["> {++bracketNesting;}
  |
  <CLOSE_BRACKET : "]"> {closeBracket(matchedToken);}
  |
  <OPEN_PAREN : "(">
  {
     ++parenthesisNesting;
     if (parenthesisNesting == 1)
        SwitchTo(IN_PAREN);
  }
  |
  <CLOSE_PAREN : ")">
  {
     --parenthesisNesting;
     if (parenthesisNesting == 0)
        SwitchTo(FM_EXPRESSION);
  }
  |
  <OPEN_BRACE : "{" > {++hashLiteralNesting;}
  |
  <CLOSE_BRACE : "}" >
  {
     if (hashLiteralNesting == 0)
        SwitchTo(DEFAULT);
     else
        --hashLiteralNesting;
  }
  |
  < IN : "in">
  |
  < AS : "as">
  |
  < USING : "using">
  |
  < ID: <LETTER> (<LETTER>|<DIGIT>)* >
  |
  < #LETTER:
      [
       "\u0024",
       "\u0040"-"\u005a",
       "\u005f",
       "\u0061"-"\u007a",
       "\u00c0"-"\u00d6",
       "\u00d8"-"\u00f6",
       "\u00f8"-"\u00ff",
       "\u0100"-"\u1fff",
       "\u3040"-"\u318f",
       "\u3300"-"\u337f",
       "\u3400"-"\u3d2d",
       "\u4e00"-"\u9fff",
       "\uf900"-"\ufaff"
      ]
  >
  |
  < #DIGIT:
      [
       "\u0030"-"\u0039",
       "\u0660"-"\u0669",
       "\u06f0"-"\u06f9",
       "\u0966"-"\u096f",
       "\u09e6"-"\u09ef",
       "\u0a66"-"\u0a6f",
       "\u0ae6"-"\u0aef",
       "\u0b66"-"\u0b6f",
       "\u0be7"-"\u0bef",
       "\u0c66"-"\u0c6f",
       "\u0ce6"-"\u0cef",
       "\u0d66"-"\u0d6f",
       "\u0e50"-"\u0e59",
       "\u0ed0"-"\u0ed9",
       "\u1040"-"\u1049"
      ]
  >
}

<FM_EXPRESSION, NO_SPACE_EXPRESSION> TOKEN :
{
  <DIRECTIVE_END : ">">
    {
        if (inFTLHeader) eatNewline();
        inFTLHeader = false;
        if (altDirectiveSyntax) {
            matchedToken.kind = NATURAL_GT;
        } else {
            SwitchTo(DEFAULT);
        }
    }
  |
  <EMPTY_DIRECTIVE_END : "/>" | "/]"> {if (inFTLHeader) eatNewline(); inFTLHeader = false; SwitchTo(DEFAULT);}
}

<IN_PAREN> TOKEN :
{
  <NATURAL_GT : ">">
  |
  <NATURAL_GTE : ">=">
}

<NO_SPACE_EXPRESSION> TOKEN :
{
    <TERMINATING_WHITESPACE :  (["\n", "\r", "\t", " "])+> : FM_EXPRESSION
}

<NO_PARSE> TOKEN :
{
    <TERSE_COMMENT_END : "-->" | "--]">
    {
        if (noparseTag.equals("-->")) {
	   boolean squareBracket = matchedToken.image.endsWith("]");
	   if ((altDirectiveSyntax && squareBracket) || (!altDirectiveSyntax && !squareBracket))
	      SwitchTo(DEFAULT);
	}
    }
    |
    <MAYBE_END :
        ("<" | "[")
        "/"
        ("#")?
        (["a"-"z", "A"-"Z"])+
        ( " " | "\t" | "\n" | "\r" )*
        (">" | "]")
    >
    {
         StringTokenizer st = new StringTokenizer(image.toString(),
                                                  " \t\n\r<>[]/#",
                                                  false);
         if (st.nextToken().equals(noparseTag)) {
            SwitchTo(DEFAULT);
         }
    }
    |
    <KEEP_GOING : (~["<", "[", "-"])+>
    |
    <LONE_LESS_THAN_OR_DASH : ["<", "[", "-"]>
}

// Now the actual parsing code, starting
// with the productions for FreeMarker's
// expression syntax.

/**
 * This is the same as OrExpression, since
 * the OR is the operator with the lowest
 * precedence.
 */

Expression Expression() :
{
   Expression exp;
}
{
   exp=OrExpression()
   {
      return exp;
   }
}

/**
 * Lowest level expression, a literal, a variable,
 * or a possibly more complex expression bounded
 * by parentheses.
 */
Expression PrimaryExpression() :
{
   Expression exp;
}
{
   (
      exp=NumberLiteral()
      |
      exp=HashLiteral()
      |
      exp=StringLiteral(true)
      |
      exp=BooleanLiteral()
      |
      exp=ListLiteral()
      |
      exp=Identifier()
      |
      exp=Parenthesis()
      |
      exp=BuiltinVariable()
  )
  (
      LOOKAHEAD(<DOT>
                |<OPEN_BRACKET>
                |<OPEN_PAREN>
                |<BUILT_IN>
                |<EXCLAM>
                |<EXISTS>)
      exp=AddSubExpression(exp)
  )*
  {
     return exp;
  }
}

Expression Parenthesis() :
{
   Expression exp, result;
   Token start, end;
}
{
    start=<OPEN_PAREN>
    exp=Expression()
    end=<CLOSE_PAREN>
    {
       result = new ParentheticalExpression(exp);
       result.setLocation(template, start, end);
       return result;
    }
}

/**
 * A primary expression preceded by zero or
 * more unary operators. (The only unary operator we
 * currently have is the NOT.)
 */
Expression UnaryExpression() :
{
   Expression exp, result;

⌨️ 快捷键说明

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