@top Program { StatementList } StatementList { Statement* } @skip { Whitespace } IfStatement { If LParen ConditionalExpression RParen PartIfStatement Else Statement | If LParen ConditionalExpression RParen Statement } PartIfStatement { If LParen ConditionalExpression RParen PartIfStatement Else PartIfStatement | NoIfStatement } ConditionalExpression { Expression Operator Expression | Expression } Expression { Term (AddLike Term)* } Statement { IfStatement | NoIfStatement } NoIfStatement { AssignmentStatement Semicolon | VariableDefinition Semicolon | LBrace Statement* RBrace | ConstantDefinition Semicolon } AssignmentStatement { Identifier Equal Expression } Term { Factor (MultiplyLike Factor)* } VariableDefinition { Type (Identifier | Identifier Equal Expression)+ } ConstantDefinition { Const VariableDefinition } Type { Int | Char } Factor { Identifier | Number | Character | LParen Expression RParen } AddLike { Plus | Minus } MultiplyLike { Multiply | Divide | Modulo } Number { UnsignedNumber | Minus UnsignedNumber | Plus UnsignedNumber } @tokens { If { "!if" } Else { "!else" } Int {"!int"} Char {"!char"} Const { "!const" } Plus { "+" } Minus { "-" } Multiply { "*" } Modulo { "%" } Divide { "/" } LParen { "(" } RParen { ")" } LBrace { "{" } RBrace { "}" } Semicolon { ";" } Identifier { $[a-zA-Z_]$[a-zA-Z0-9_]* } UnsignedNumber { $[0-9]+ } String { "\"" $[\x00-\x7F]* "\"" } Character { "'" $[\x00-\x7F] "'" } Operator { "==" | "!=" | "<=" | ">=" | "<" | ">" } Equal { "=" } Whitespace { $[\t\n\r]+ } }