Syntactic Specifications
Note
Here is the grammar of the Tiger language for user inputs.
Do not forget that our compiler uses meta-variables internally and must therefore handle the Additional Syntactic Specifications.
We use
Extended BNF,
with [
and ]
for zero or once, and {
and }
for any number
of repetition including zero.
- Native Tiger rules
program = exp | chunks ; (* === Expressions. === *) exps = [ exp { ";" exp } ] ; exp = (* Literals. *) "nil" | integer | string (* Array and record creations. *) | type-id "[" exp "]" "of" exp | type-id "{" [ id "=" exp { "," id "=" exp } ] "}" (* Variables, fields, elements of an array. *) | lvalue (* Function call. *) | id "(" [ exp { "," exp }] ")" (* Operations. *) | "-" exp | exp op exp | "(" exps ")" (* Assignment. *) | lvalue ":=" exp (* Control structures. *) | "if" exp "then" exp ["else" exp] | "while" exp "do" exp | "for" id ":=" exp "to" exp "do" exp | "break" | "let" chunks "in" exps "end" ; lvalue = id (* Record field access. *) | lvalue "." id (* Array subscript. *) | lvalue "[" exp "]" ; op = "+" | "-" | "*" | "/" | "=" | "<>" | ">" | "<" | ">=" | "<=" | "&" | "|" ; (* === Chunks of declarations. === *) chunks = { chunk } ; chunk = { tydec } (* tychunk *) | { fundec } (* funchunk *) | vardec (* varchunk *) (* Importing a set of declarations. *) | "import" string ; (* Variable declaration. *) vardec = "var" id [ ":" type-id ] ":=" exp ; (* Type declaration. *) tydec = "type" id "=" ty ; (* Function declaration. *) fundec = "function" id "(" tyfields ")" [ ":" type-id ] "=" exp | "primitive" id "(" tyfields ")" [ ":" type-id ] ; (* === Types. === *) ty = (* Type alias. *) type-id (* Record type definition. *) | "{" tyfields "}" (* Array type definition. *) | "array" "of" type-id ; tyfields = [ id ":" type-id { "," id ":" type-id } ] ; type-id = id ;
Precedence of the
op
operators from high to low:* / + - >= <= = <> < > & |
Comparison operators (
<
,<=
,=
,<>
,>
and>=
) are not associative. All the remaining operators are left-associative.Warning
If you use the
exp op exp
andop
rules as such, Bison will not be able to solve shift/reduce conflicts between operators using their precedences.This is fixed by making the rule
exp op exp
explicit for each operator. For example with+
,-
,*
and/
, the grammar could look like the following:exp = (* Previous rules ... *) (* Operations. *) | "-" exp | exp "+" exp | exp "-" exp | exp "*" exp | exp "/" exp | "(" exps ")" (* Next rules ... *)
- Object additional rules
Tiger’s object-oriented syntax implies additional rules as described below.
exp = (* Object creation. *) "new" type-id (* Method call. *) | lvalue "." id "(" [ exp { "," exp }] ")" ; (* Class definition (alternative form). *) tydec = "class" id [ "extends" type-id ] "{" classfields "}" ; (* Class definition (canonical form). *) ty = "class" [ "extends" type-id ] "{" classfields "}" ; (* Class fields. *) classfields = { classfield } ; classfield = (* Attribute declaration (varchunk). *) vardec (* Method declaration (methchunk). *) | { "method" id "(" tyfields ")" [ ":" type-id ] "=" exp } ;