Skip to content
jappy edited this page Oct 19, 2011 · 1 revision

Previous - Type Conversion | Table of Contents | Next - Tea Architecture

Tea's grammar is designed to resemble Java's, but because semi-colons are optional, some elements have unique appearances in order for the grammar to be more unambiguous. Most notably is the format to define new arrays. Without the leading hash symbols, a new array list can appear to be a parameter list or a simple expression. Unlike Java, new array values are specified within a list delimited by parentheses instead of braces. Use of braces seems inconsistent because they should be used to group statements, not expressions.

Call statements can optionally begin with a "call" keyword to indicate a template call over a function call. Because the function calling form does not begin with this keyword, Tea parsers may require special logic in order to properly parse it.

The current implementation of Tea uses a manually written LL(n) parser. The notation used for the LL grammar follows an EBNF convention. Brackets ("[" and "]") denote optional derivations. Braces ("{" and "}") denote derivations that may expand zero or more times. Key terminals are shown with a fixed width font, and key terminals that are punctuation characters are shown inside double quotes.

Template ::= TemplateDeclaration StatementList   
   
StatementList ::= { Statement }   

TemplateDeclaration ::= "template" Identifier "(" [ FormalParameterList ] ")"    
                        [ SubstitutionParameter ]   

FormalParameterList ::= FormalParameter { "," FormalParameter }   

FormalParameter ::= Type  Variable

Type ::= Name { "[" "]"}

Name ::= Identifier { "." Identifier }

Variable ::= Identifier

SubstitutionParameter ::= "{" "..." "}"

Statement ::= 
    EmptyStatement |
    IfStatement |
    ForeachStatement |
    SubstitutionStatement |
    AssignmentStatement |
    CallStatement |
    ExpressionStatement

EmptyStatement ::= ";" 

IfStatement ::=
    "if" "(" Expression  ")" Block  [ ElseStatement ]

ElseStatement ::=
    "else" Block |
    "else" IfStatement

Block ::= "{" StatementList "}"

ForeachStatement ::=
    "foreach" "(" Variable ["as" Type] "in" Expression [ ..  Expression ] [ "reverse" ]  ")" Block

SubstitutionStatement ::= "..."

AssignmentStatement ::= Variable "=" Expression

CallStatement ::= [ call ]  Name "(" [ List ] ")" [ Block ]

List ::= Expression { "," Expression }

AssociativeList ::= Expression { "=>" Expression }

ExpressionStatement ::= Expression

Expression ::= OrExpression

OrExpression ::= AndExpression { "or" AndExpression }

AndExpression ::= EqualityExpression { "and" EqualityExpression }

EqualityExpression ::=
    RelationalExpression { "==" RelationalExpression } |
    RelationalExpression { "!=" RelationalExpression }

RelationalExpression ::=
    ConcatenateExpression { "<" ConcatenateExpression } |
    ConcatenateExpression { ">" ConcatenateExpression } |
    ConcatenateExpression { "<=" ConcatenateExpression } |
    ConcatenateExpression { ">=" ConcatenateExpression } |
    ConcatenateExpression { "isa" Type }

ConcatenateExpression ::= AdditiveExpression { "&" AdditiveExpression }

AdditiveExpression ::=
    MultiplicativeExpression { "+" MultiplicativeExpression } |
    MultiplicativeExpression { "-" MultiplicativeExpression }

MultiplicativeExpression ::=
    UnaryExpression { "*" UnaryExpression } |
    UnaryExpression { "/" UnaryExpression } |
    UnaryExpression { "%" UnaryExpression }

UnaryExpression ::=
    "not" UnaryExpression |
    "-" UnaryExpression |
    LookupExpression

LookupExpression ::= Factor { Lookup }

Lookup ::=
    "." Identifier |
    "[" Expression "]"

Factor ::=
    NewArrayExpression |
    "(" Expression ")" |
    Literal |
    CallExpression |
    Variable

NewArrayExpression ::=
    "#" "(" [ List ] ")" |
    "##" "(" [ List ] ")" |
    "##" "(" [ AssociativeList ] ")"

CallExpression ::=
    [ "call" ]  Name "(" [ List ] ")" [ Block ]