Input | ::= | Expression <EOF> |
Expression | ::= | OrExpression |
OrExpression | ::= | AndExpression ( ( <OR> | <OR2> ) AndExpression )* |
AndExpression | ::= | EqualityExpression ( ( <AND> | <AND2> ) EqualityExpression )* |
EqualityExpression | ::= | RelationalExpression ( ( <EQUALS> | <DOUBLE_EQUALS> | <NOT_EQUALS> ) RelationalExpression )? |
RelationalExpression | ::= | RangeExpression ( ( <GT> | <GTE> | <LT> | <LTE> | <ALT_GT> | <ALT_GTE> | <ALT_LTE> | <ALT_LT> ) RangeExpression )? |
RangeExpression | ::= | AdditiveExpression ( <DOT_DOT> ( AdditiveExpression )? )? |
AdditiveExpression | ::= | MultiplicativeExpression ( ( <PLUS> | <MINUS> ) MultiplicativeExpression )* |
MultiplicativeExpression | ::= | UnaryExpression ( ( <TIMES> | <DIVIDE> | <PERCENT> ) UnaryExpression )* |
UnaryExpression | ::= | UnaryPlusMinusExpression | NotExpression | DefaultToExpression |
UnaryPlusMinusExpression | ::= | ( <PLUS> | <MINUS> ) DefaultToExpression |
NotExpression | ::= | <EXCLAM> DefaultToExpression |
BuiltinVariable | ::= | <DOT> <IDENTIFIER> |
DefaultToExpression | ::= | PrimaryExpression ( <EXCLAM> PrimaryExpression )* ( <EXCLAM> )? |
PrimaryExpression | ::= | BaseExpression ( ( DotKey | DynamicKey | MethodInvoke | BuiltIn | Exists ))* |
BaseExpression | ::= | <IDENTIFIER> | NumberLiteral | HashLiteral | StringLiteral | BooleanLiteral | NullLiteral | ListLiteral | Parenthesis | BuiltinVariable |
DotKey | ::= | <DOT> ( <IDENTIFIER> | <TIMES> ) |
DynamicKey | ::= | <OPEN_BRACKET> Expression <CLOSE_BRACKET> |
MethodInvoke | ::= | <OPEN_PAREN> ( ArgsList )? <CLOSE_PAREN> |
BuiltIn | ::= | <BUILT_IN> <IDENTIFIER> |
Exists | ::= | <EXISTS_OPERATOR> |
ListLiteral | ::= | <OPEN_BRACKET> ( Expression ( ( <COMMA> )? Expression )* )? <CLOSE_BRACKET> |
StringLiteral | ::= | <STRING_LITERAL> | <RAW_STRING> |
HashLiteral | ::= | <OPEN_BRACE> ( Expression <COLON> Expression ( <COMMA> Expression <COLON> Expression )* )? <CLOSE_BRACE> |
NumberLiteral | ::= | <INTEGER> | <DECIMAL> |
BooleanLiteral | ::= | <TRUE> | <FALSE> |
NullLiteral | ::= | <NULL> |
Parenthesis | ::= | <OPEN_PAREN> Expression <CLOSE_PAREN> |
ArgsList | ::= | ( NamedArgsList | PositionalArgsList ) |
NamedArgsList | ::= | <IDENTIFIER> <EQUALS> Expression ( ( <COMMA> )? <IDENTIFIER> <EQUALS> Expression )* |
PositionalArgsList | ::= | Expression ( ( <COMMA> )? Expression )* |
IdentifierOrStringLiteral | ::= | <IDENTIFIER> | StringLiteral |
Interpolation | ::= | <INTERPOLATE> Expression <CLOSE_BRACE> |
NumericalInterpolation | ::= | <NUMERICAL_INTERPOLATE> Expression ( <SEMICOLON> <IDENTIFIER> )? <CLOSE_BRACE> |
Assignment | ::= | <FTL_DIRECTIVE_OPEN> ( <SET> | <ASSIGN> | <LOCAL> | <GLOBAL> ) <BLANK> IdentifierOrStringLiteral ( ( <EQUALS> Expression ( ( <COMMA> )? IdentifierOrStringLiteral <EQUALS> Expression )* ( <IN> Expression )? LooseTagEnd )| ( ( <IN> Expression )? <CLOSE_TAG> Block DirectiveEnd ) ) |
Var | ::= | <FTL_DIRECTIVE_OPEN> <VAR> <BLANK> IdentifierOrStringLiteral ( <EQUALS> Expression )? ( ( <COMMA> )? IdentifierOrStringLiteral ( <EQUALS> Expression )? )* LooseTagEnd |
Setting | ::= | <FTL_DIRECTIVE_OPEN> <SETTING> <BLANK> <IDENTIFIER> ( <EQUALS> Expression )? ( ( <COMMA> )? IdentifierOrStringLiteral ( <EQUALS> Expression )? )* LooseTagEnd |
Attempt | ::= | <FTL_DIRECTIVE_OPEN> <ATTEMPT> <CLOSE_TAG> Block Recover |
Comment | ::= | <FTL_DIRECTIVE_OPEN> <COMMENT> <END_COMMENT> |
NoParse | ::= | <FTL_DIRECTIVE_OPEN> <NOPARSE> <CLOSE_TAG> <NOPARSE_END> |
Trim | ::= | <FTL_DIRECTIVE_OPEN> <TRIM> LooseTagEnd |
NoTrim | ::= | <FTL_DIRECTIVE_OPEN> <NOTRIM> LooseTagEnd |
RightTrim | ::= | <FTL_DIRECTIVE_OPEN> <RTRIM> LooseTagEnd |
LeftTrim | ::= | <FTL_DIRECTIVE_OPEN> <LTRIM> LooseTagEnd |
Break | ::= | <FTL_DIRECTIVE_OPEN> <BREAK> LooseTagEnd |
Flush | ::= | <FTL_DIRECTIVE_OPEN> <FLUSH> LooseTagEnd |
Return | ::= | <FTL_DIRECTIVE_OPEN> <RETURN> ( <BLANK> Expression )? LooseTagEnd |
Stop | ::= | <FTL_DIRECTIVE_OPEN> <STOP> ( <BLANK> Expression )? LooseTagEnd |
Compress | ::= | <FTL_DIRECTIVE_OPEN> <COMPRESS> <CLOSE_TAG> Block DirectiveEnd |
TrimBlock | ::= | <FTL_DIRECTIVE_OPEN> ( <BLOCKTRIM> | <BLOCKTRIML> | <BLOCKTRIMR> | <BLOCKNOTRIM> ) <CLOSE_TAG> Block DirectiveEnd |
NoEscapeBlock | ::= | <FTL_DIRECTIVE_OPEN> <NOESCAPE> <CLOSE_TAG> Block DirectiveEnd |
EscapeBlock | ::= | <FTL_DIRECTIVE_OPEN> <ESCAPE> <BLANK> <IDENTIFIER> <AS> Expression <CLOSE_TAG> Block DirectiveEnd |
Include | ::= | <FTL_DIRECTIVE_OPEN> <_INCLUDE> <BLANK> Expression ( <SEMICOLON> )? ( <IDENTIFIER> <EQUALS> Expression )* LooseTagEnd |
Embed | ::= | <FTL_DIRECTIVE_OPEN> <EMBED> <BLANK> Expression LooseTagEnd |
Import | ::= | <FTL_DIRECTIVE_OPEN> <IMPORT> <BLANK> Expression <AS> <IDENTIFIER> LooseTagEnd |
Visit | ::= | <FTL_DIRECTIVE_OPEN> <VISIT> <BLANK> Expression ( <USING> Expression ( ( <COMMA> )? Expression )* )? LooseTagEnd |
Recurse | ::= | <FTL_DIRECTIVE_OPEN> <RECURSE> ( LooseTagEnd | ( <BLANK> ( Expression )? ( <USING> Expression ( ( <COMMA> )? Expression )* )? LooseTagEnd ) ) |
FallBack | ::= | <FTL_DIRECTIVE_OPEN> <FALLBACK> LooseTagEnd |
If | ::= | <FTL_DIRECTIVE_OPEN> <IF> <BLANK> Expression <CLOSE_TAG> Block ( ElseIf )* ( Else )? DirectiveEnd |
ElseIf | ::= | <FTL_DIRECTIVE_OPEN> <ELSEIF> <BLANK> Expression <CLOSE_TAG> Block |
Else | ::= | <FTL_DIRECTIVE_OPEN> <ELSE> <CLOSE_TAG> Block |
Switch | ::= | <FTL_DIRECTIVE_OPEN> <SWITCH> <BLANK> Expression <CLOSE_TAG> ( <WHITESPACE> )? ( Case )* ( Default )? DirectiveEnd |
Case | ::= | <FTL_DIRECTIVE_OPEN> <CASE> <BLANK> Expression <CLOSE_TAG> Block |
Default | ::= | <FTL_DIRECTIVE_OPEN> <DEFAUL> <CLOSE_TAG> Block |
List | ::= | <FTL_DIRECTIVE_OPEN> <LIST> <BLANK> Expression <AS> <IDENTIFIER> <CLOSE_TAG> Block DirectiveEnd |
ForEach | ::= | <FTL_DIRECTIVE_OPEN> <FOREACH> <BLANK> <IDENTIFIER> <IN> Expression <CLOSE_TAG> Block DirectiveEnd |
Nested | ::= | <FTL_DIRECTIVE_OPEN> <NESTED> ( <BLANK> PositionalArgsList )? LooseTagEnd |
MacroDefinition | ::= | <FTL_DIRECTIVE_OPEN> ( <MACRO> | <FUNCTION> ) <BLANK> IdentifierOrStringLiteral ( <OPEN_PAREN> )? ( ParameterList )? ( <CLOSE_PAREN> )? <CLOSE_TAG> Block DirectiveEnd |
ParameterList | ::= | <IDENTIFIER> ( ( <EQUALS> Expression )| <ELLIPSIS> )? ( ( <COMMA> )? <IDENTIFIER> ( ( <EQUALS> Expression )| <ELLIPSIS> )? )* |
LooseTagEnd | ::= | <CLOSE_TAG> | <CLOSE_EMPTY_TAG> |
DirectiveEnd | ::= | <END_DIRECTIVE> |
Text | ::= | ( ( <PRINTABLE_CHARS> | <WHITESPACE> | <SPECIAL_CHAR> ))+ |
Recover | ::= | <FTL_DIRECTIVE_OPEN> <RECOVER> <CLOSE_TAG> Block DirectiveEnd |
TopLevelDirective | ::= | ( Assignment | Attempt | Comment | Compress | Embed | ForEach | If | List | Include | Import | MacroDefinition | NoParse | Switch | Setting | Var | Break | Return | Stop | Flush | Trim | NoTrim | LeftTrim | RightTrim | TrimBlock | Nested | EscapeBlock | NoEscapeBlock | Visit | Recurse | FallBack ) |
UserDirective | ::= | <USER_DIRECTIVE_OPEN> Expression ( <BLANK> )? ( ArgsList )? ( <SEMICOLON> ( ParameterList )? )? ( <CLOSE_EMPTY_TAG> | ( <CLOSE_TAG> Block EndUserDirective ) ) |
EndUserDirective | ::= | <END_USER_DIRECTIVE> |
Block | ::= | ( ( Text | Interpolation | NumericalInterpolation | UserDirective | TopLevelDirective ))* |
FTLHeader | ::= | <FTL_DIRECTIVE_OPEN> <FTL> ( <BLANK> ( <IDENTIFIER> <EQUALS> Expression )* )? ( <CLOSE_TAG> | <CLOSE_EMPTY_TAG> ) |
Root | ::= | ( ( <WHITESPACE> )? FTLHeader )? Block <EOF> |
<FTL_EXPRESSION> SKIP : { <EXP_WHITE_SPACE: (" " | "\t" | "\n" | "\r")+> } |
<FTL_EXPRESSION> MORE : { "<#--" |"<!--" |"[#--" } |
<EXPRESSION_COMMENT> MORE : { <~[]> } |
<EXPRESSION_COMMENT> SPECIAL_TOKEN : { "-->" |"--]" } |
<FTL_EXPRESSION> TOKEN : { <OPEN_PAREN: "("> |<CLOSE_PAREN: ")"> |<OPEN_BRACKET: "["> |<CLOSE_BRACKET: "]"> |<OPEN_BRACE: "{"> |<CLOSE_BRACE: "}"> |<EQUALS: "="> |<DOT: "."> |<PLUS: "+"> |<MINUS: "-"> |<TIMES: "*"> |<DIVIDE: "/"> |<PERCENT: "%"> |<OR: "|"> |<AND: "&"> |<LT: "<"> |<GT: ">"> |<COMMA: ","> |<COLON: ":"> |<SEMICOLON: ";"> |<EXCLAM: "!"> |<BUILT_IN: "?"> |<DOUBLE_EQUALS: "=="> |<NOT_EQUALS: "!="> |<EXISTS_OPERATOR: "??"> |<LTE: "<="> |<GTE: ">="> |<OR2: "||"> |<AND2: "&&"> |<DOT_DOT: ".."> |<ALT_GT: "gt"> |<ALT_LT: "lt"> |<AS: "as"> |<IN: "in"> |<ALT_GTE: "gte"> |<ALT_LTE: "lte"> |<ELLIPSIS: "..."> |<NULL: "null"> |<TRUE: "true"> |<FALSE: "false"> |<USING: "using"> |<INTEGER: (["0"-"9"])+> |<DECIMAL: <INTEGER> "." <INTEGER>> |<IDENTIFIER: <LETTER> (<LETTER> | <DIGIT>)*> |<STRING_LITERAL: "\"" (~["\\","\""] | "\\" ~[])* "\"" | "\'" (~["\\","\'"] | "\\" ~[])* "\'"> |<RAW_STRING: "r" ("\"" (~["\""])* "\"" | "\'" (~["\'"])* "\'")> } |
<TEMPLATE_TEXT> TOKEN : { <FTL_DIRECTIVE_OPEN: "<#" | "[#"> |<USER_DIRECTIVE_OPEN: "<@" | "[@"> |<INTERPOLATE: "${"> |<NUMERICAL_INTERPOLATE: "#{"> |<WHITESPACE: (["\n","\r","\t"," "])+> |<SPECIAL_CHAR: "$" | "<" | "["> |<PRINTABLE_CHARS: (~["$","<","[","\n","\r","\t"," "])+> |<END_DIRECTIVE: <END_DIRECTIVE1> | <END_DIRECTIVE2>> |<END_USER_DIRECTIVE: <END_USER_DIRECTIVE1> | <END_USER_DIRECTIVE2>> |} |
<FTL_DIRECTIVE> TOKEN : { <TRIM: "t"> |<COMMENT: "--"> |<LTRIM: "lt"> |<RTRIM: "rt"> |<NOTRIM: "nt"> |<IF: "if"> |<FTL: "ftl"> |<SET: "set"> |<VAR: "var"> |<LIST: "list"> |<ELSE: "else"> |<STOP: "stop"> |<CASE: "case"> |<MACRO: "macro"> |<LOCAL: "local"> |<FLUSH: "flush"> |<BREAK: "break"> |<EMBED: "embed"> |<NESTED: "nested"> |<VISIT: "visit"> |<SWITCH: "switch"> |<IMPORT: "import"> |<DEFAUL: "default"> |<RETURN: "return"> |<GLOBAL: "global"> |<ASSIGN: "assign"> |<ELSEIF: "elseif"> |<ESCAPE: "escape"> |<RECURSE: "recurse"> |<FUNCTION: "function"> |<FALLBACK: "fallback"> |<NOESCAPE: "noescape"> |<SETTING: "setting"> |<NOPARSE: "noparse"> |<_INCLUDE: "include"> |<ATTEMPT: "attempt"> |<FOREACH: "foreach"> |<RECOVER: "recover"> |<COMPRESS: "compress"> |<BLOCKTRIM: "t_lines"> |<BLOCKTRIML: "lt_lines"> |<BLOCKTRIMR: "rt_lines"> |<BLOCKNOTRIM: "nt_lines"> |<BLANK: "\n" | "\r" | "\t" | " "> |<CLOSE_TAG: (<BLANK>)* (">" | "]")> } |
<FTL_DIRECTIVE, FTL_EXPRESSION> TOKEN : { <CLOSE_EMPTY_TAG: (<BLANK>)* "/" (">" | "]")> } |
<IN_COMMENT> MORE : { <~[]> } |
<IN_COMMENT> TOKEN : { <END_COMMENT: "-->" | "--]"> } |
<NO_PARSE> MORE : { <~[]> } |
<NO_PARSE> TOKEN : { <NOPARSE_END: "</#noparse" (<BLANK>)* ">" | "[/#noparse" (<BLANK>)* "]"> } |