TwirlParser
TwirlParser is a recursive descent parser for a modified grammar of the Play2 template language as loosely defined here and more rigorously defined by the original template parser, play.templates.ScalaTemplateCompiler.TemplateParser
. TwirlParser is meant to be a near drop in replacement for play.templates.ScalaTemplateCompiler.TemplateParser
.
The original grammar, as reversed-engineered from play.templates.ScalaTemplateCompiler.TemplateParser
, is defined as follows:
parser : comment? whitespace? ('@' parentheses+)? templateContent
templateContent : (importExpression | localDef | template | mixed)*
templateDeclaration : '@' identifier squareBrackets? parentheses*
localDef : templateDeclaration (' ' | '\t')* '=' (' ' | '\t') scalaBlock
template : templateDeclaration (' ' | '\t')* '=' (' ' | '\t') '{' templateContent '}'
mixed : (comment | scalaBlockDisplayed | caseExpression | matchExpression | forExpression | safeExpression | plain | expression) | ('{' mixed* '}')
scalaBlockDisplayed : scalaBlock
scalaBlockChained : scalaBlock
scalaBlock : '@' brackets
importExpression : '@' 'import ' .* '\r'? '\n'
caseExpression : whitespace? 'case' .+ '=>' block whitespace?
forExpression : '@' "for" parentheses block
matchExpression : '@' (simpleExpr | complexExpr) whitespaceNoBreak 'match' block
simpleExpr : methodCall expressionPart*
complexExpr : parentheses
safeExpression : '@' parentheses
elseCall : whitespaceNoBreak "else" whitespaceNoBreak?
chainedMethods : ('.' methodCall)+
expressionPart : chainedMethods | block | (whitespaceNoBreak scalaBlockChained) | elseCall | parentheses
expression : '@' methodCall expressionPart*
methodCall : identifier squareBrackets? parentheses?
blockArgs : [^'=>' '\n']* '=>'
block : whitespaceNoBreak '{' blockArgs? mixed* '}'
brackets : '{' (brackets | [^'}'])* '}'
comment : '@*' [^'*@']* '*@'
parentheses : '(' (parentheses | [^')'])* ')'
squareBrackets : '[' (squareBrackets | [^']'])* ']'
plain : ('@@' | ([^'@'] [^'{' '}']))+
whitespaceNoBreak : [' ' '\t']+
identifier : javaIdentStart javaIdentPart* // see java docs for what these two rules mean
TwirlParser implements a slightly modified version of the above grammar that removes some back-tracking within the 'mixed' non-terminal. It is defined as follows:
parser : comment? whitespace? ('@' parentheses+)? templateContent
templateContent : (importExpression | localDef | template | mixed)*
templateDeclaration : '@' identifier squareBrackets? parentheses*
localDef : templateDeclaration (' ' | '\t')* '=' (' ' | '\t') scalaBlock
template : templateDeclaration (' ' | '\t')* '=' (' ' | '\t') '{' templateContent '}'
mixed : (comment | scalaBlockDisplayed | forExpression | ifExpression | matchExpOrSafeExpOrExpr | caseExpression | plain) | ('{' mixed* '}')
matchExpOrSafeExpOrExpr : (expression | safeExpression) (whitespaceNoBreak 'match' block)?
scalaBlockDisplayed : scalaBlock
scalaBlockChained : scalaBlock
scalaBlock : '@' brackets
importExpression : '@' 'import ' .* '\r'? '\n'
caseExpression : (whitespace? 'case' .+ '=>' block whitespace?) | whitespace
forExpression : '@' "for" parentheses block
simpleExpr : methodCall expressionPart*
complexExpr : parentheses
safeExpression : '@' parentheses
ifExpression : '@' "if" parentheses expressionPart (elseIfCall)* elseCall?
elseCall : whitespaceNoBreak? "else" expressionPart whitespaceNoBreak?
elseIfCall : whitespaceNoBreak? "else if" parentheses expressionPart whitespaceNoBreak?
chainedMethods : ('.' methodCall)+
expressionPart : chainedMethods | block | (whitespaceNoBreak scalaBlockChained) | parentheses
expression : '@' methodCall expressionPart*
methodCall : identifier squareBrackets? parentheses?
blockArgs : [^'=>' '\n']* '=>'
block : whitespaceNoBreak? '{' blockArgs? mixed* '}'
brackets : '{' (brackets | [^'}'])* '}'
comment : '@*' [^'*@']* '*@'
parentheses : '(' (parentheses | [^')'])* ')'
squareBrackets : '[' (squareBrackets | [^']'])* ']'
plain : ('@@' | '@}' | ([^'@'] [^'{' '}']))+
whitespaceNoBreak : [' ' '\t']+
identifier : javaIdentStart javaIdentPart* // see java docs for what these two rules mean
TwirlParser can detect several type of parse errors and provides line information. In all cases, the parser will continue parsing the best it can after encountering an error. The following errors are what can be detected:
- EOF found when more input was expected.
- Unmatched curly braces
- Missing blocks after case and match statements
- Invalid ("alone") '@' symbols.
Attributes
- Graph
-
- Supertypes
-
class Objecttrait Matchableclass Any