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