@Algorithm(lalr, 1) // The parser catches a forgotten precedence annotation. Start: Statements Statements: Statement ; Statements | Statement | Statement: RETURN Expr | GLOBAL ID | BREAK | CONTINUE | IfStm | WhileStm | ForStm | FunctionStm | Expr AssignOp Expr | Expr IfStm: IF Expr THEN Statements ElseBranch? END ElseBranch: ELSE Statements WhileStm: WHILE Expr DO Statements END ForStm: FOR ID IN Expr DO Statements END FunctionStm: FN ID ( FunctionArgs ) Statements END FunctionArgs: ID , FunctionArgs | ID | Expr: Expr LogicOp Expr | Expr EqualOp Expr | Expr ComparisonOp Expr | Expr TermOp Expr | Expr FactorOp Expr | Expr ^ Expr | Expr % Expr | Expr [ Expr ] | Expr ( Args ) | Expr . ID | NOT Expr | - Expr | Constant | INT | FLOAT | STRING | ID | ( Expr ) | FN ( FunctionArgs ) Statements END | { TableFields } Constant: TRUE | FALSE | NIL AssignOp: = | += | -= | *= | /= LogicOp: AND | OR | XOR EqualOp: == | != ComparisonOp: < | > | <= | >= TermOp: + | - FactorOp: * | / TableFields: TableField , TableFields | TableField | TableField: ID = Expr // WHOOPS: we forgot to specify a precedence for the right-hand side of '%' ! // AND OR XOR @precedence(Expr, 0, left = 1, right = 2) // == != @precedence(Expr, 1, left = 3, right = 4) // < > <= >= @precedence(Expr, 2, left = 5, right = 6) // + - @precedence(Expr, 3, left = 7, right = 8) // * / @precedence(Expr, 4, left = 9, right = 10) // ^ @precedence(Expr, 5, left = 11, right = 12) // % // THE ERROR IS HERE ! @precedence(Expr, 6, left = 13) // [] () . @precedence(Expr, 7, left = 15) @precedence(Expr, 8, left = 15) @precedence(Expr, 9, left = 15) // NOT - @precedence(Expr, 10, right = 16) @precedence(Expr, 11, right = 16)