@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 | 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 { EuqalTo | NotEqualTo | LessThan | GreaterThan | LessThanOrEqual | GreaterThanOrEqual } @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] "'" } EuqalTo { "==" } NotEqualTo { "!=" } LessThan { "<" } GreaterThan { ">" } LessThanOrEqual { "<=" } GreaterThanOrEqual { ">=" } Equal { "=" } Whitespace { $[\t\n\r]+ } }