Option[content] ::=
content@value <Some>
<None>;
NonEmptyList[content, separation] ::=
content@head <Nil>
content@head separation NonEmptyList[content, separation]@tail <Cons>;
List[content, separation] ::=
Option[NonEmptyList[content, separation]]@value <>;
Empty ::=
<>;
"a file"
@File ::=
List[INCLUDE, Empty] List[FunctionDeclaration, Empty]@decls <>;
"a function declaration"
FunctionDeclaration ::=
Type@rettype IDENT.0@name LPAR List[TypedParam, COMMA]@args RPAR Block@block <>;
"a type"
Type ::=
VOID <Void>
INTTY <Int>
BOOL <Bool>
Type@pointed ASTERISK <Pointer>;
"a parameter"
TypedParam ::=
Type@type IDENT.0@name <>;
"an integer"
Int ::=
INT.0@value <Int>
CHAR.0@value <Char>;
"a boolean"
Bool ::=
TRUE <True>
FALSE <False>;
"an expression"
Expr ::=
Int@value <Int>
Bool@value <Bool>
NULL <Null>
LPAR Expr@this RPAR <Through>
EXCLAM Expr@value <Not>
PLUSPLUS Expr@value <Incrl>
Expr@value PLUSPLUS <Incrr>
MINUSMINUS Expr@value <Decrl>
Expr@value MINUSMINUS <Decrr>
AMPERSAND Expr@value <Borrow>
ASTERISK Expr@value <Deref>
PLUS Expr@value <Plus>
MINUS Expr@value <Minus>
IDENT.0@value <Ident>
SIZEOF LPAR Type@type RPAR <Sizeof>
IDENT.0@name LPAR List[Expr, COMMA]@args RPAR <Call>
Expr@array LBRACKET Expr@index RBRACKET <
Deref
value: Expr {
BinOp
op: AddSubOp { Add }
left: array
right: index
}
>
(left-assoc) Expr@left MulDivModOp@op Expr@right <BinOp>
(left-assoc) Expr@left AddSubOp@op Expr@right <BinOp>
(left-assoc) Expr@left CmpOp@op Expr@right <BinOp>
(left-assoc) Expr@left EqOp@op Expr@right <BinOp>
(left-assoc) Expr@left AndOp@op Expr@right <BinOp>
(left-assoc) Expr@left OrOp@op Expr@right <BinOp>
(right-assoc) Expr@key EQUAL Expr@value <Assign>;
"an operator"
MulDivModOp ::=
ASTERISK <Mul>
SLASH <Div>
PERCENT <Mod>;
"an operator"
AddSubOp ::=
PLUS <Add>
MINUS <Sub>;
"an operator"
CmpOp ::=
LT <Lt>
GT <Gt>
GEQ <Geq>
LEQ <Leq>;
"an operator"
EqOp ::=
EQ <Equal>
NEQ <NotEqual>;
"an operator"
AndOp ::=
AND <And>;
"an operator"
OrOp ::=
OR <Or>;
"a statement"
Statement ::=
SEMICOLON <None>
Expr@stmt SEMICOLON <Regular>
IF LPAR Expr@condition RPAR Statement@then Option[Else]@else <If>
WHILE LPAR Expr@condition RPAR Statement@body <While>
FOR
LPAR
Option[VariableDeclaration]@init SEMICOLON
Option[Expr]@test SEMICOLON
List[Expr, COMMA]@step
RPAR
Statement@body <For>
Block@stmts <Block>
RETURN Option[Expr]@value SEMICOLON <Return>
BREAK SEMICOLON <Break>
CONTINUE SEMICOLON <Continue>;
Else ::=
ELSE Statement@else <>;
"a block"
Block ::=
LBRACE List[DeclStatement, Empty]@stmts RBRACE <>;
DeclStatement ::=
FunctionDeclaration@declaration <Function>
VariableDeclaration@declaration SEMICOLON <Declaration>
Statement@stmt <Statement>;
"a variable declaration"
VariableDeclaration ::=
Type@type IDENT.0@name Option[Definition]@value <>;
Definition ::=
EQUAL Expr@value <>;