diff --git a/neon/parser.neon b/neon/parser.neon index 7b0580eca4..cb983f3720 100644 --- a/neon/parser.neon +++ b/neon/parser.neon @@ -1361,14 +1361,14 @@ END FUNCTION /* Operator precedence: * - * ^ exponentiation parseExponentiation - * * / MOD multiplication, division, modulo parseMultiplication - * + - addition, subtraction parseAddition + * ^ exponentiation parseArithmetic + * * / MOD multiplication, division, modulo parseArithmetic + * + - addition, subtraction parseArithmetic * < = > comparison parseComparison * isa type test parseTypeTest * in membership parseMembership - * and conjunction parseConjunction - * or disjunction parseDisjunction + * and conjunction parseLogical + * or disjunction parseLogical * if conditional parseConditional */ @@ -1602,40 +1602,18 @@ FUNCTION Parser.parseAtom(INOUT self: Parser): POINTER TO ParseTreeNode RETURN NIL END FUNCTION -FUNCTION Parser.parseExponentiation(INOUT self: Parser): POINTER TO ParseTreeNode +FUNCTION Parser.parseArithmetic(INOUT self: Parser): POINTER TO ParseTreeNode VAR left: POINTER TO ParseTreeNode := self.parseCompoundExpression() - LOOP - LET tokOp: lexer.Token := self.token - IF tokOp.type = TokenType.exp THEN - self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() - left := NEW ParseTreeNode( - type WITH Type.ExponentiationExpression, - token WITH tokOp, - binaryexpression WITH BinaryExpression( - startColumn WITH getStartColumn(left), - endColumn WITH getEndColumn(right), - left WITH left, - right WITH right - ) - ) - ELSE - RETURN left - END IF - END LOOP -END FUNCTION - -FUNCTION Parser.parseMultiplication(INOUT self: Parser): POINTER TO ParseTreeNode - VAR left: POINTER TO ParseTreeNode := self.parseExponentiation() - LOOP - LET tokOp: lexer.Token := self.token - CASE tokOp.type - WHEN TokenType.times DO + LET tokOp: lexer.Token := self.token + CASE tokOp.type + WHEN TokenType.plus DO + WHILE self.token.type = TokenType.plus DO + LET tokOp2: lexer.Token := self.token self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseExponentiation() + LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() left := NEW ParseTreeNode( - type WITH Type.MultiplicationExpression, - token WITH tokOp, + type WITH Type.AdditionExpression, + token WITH tokOp2, binaryexpression WITH BinaryExpression( startColumn WITH getStartColumn(left), endColumn WITH getEndColumn(right), @@ -1643,12 +1621,14 @@ FUNCTION Parser.parseMultiplication(INOUT self: Parser): POINTER TO ParseTreeNod right WITH right ) ) - WHEN TokenType.divide DO + END WHILE + IF self.token.type = TokenType.minus THEN + LET tokOp2: lexer.Token := self.token self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseExponentiation() + LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() left := NEW ParseTreeNode( - type WITH Type.DivisionExpression, - token WITH tokOp, + type WITH Type.SubtractionExpression, + token WITH tokOp2, binaryexpression WITH BinaryExpression( startColumn WITH getStartColumn(left), endColumn WITH getEndColumn(right), @@ -1656,12 +1636,15 @@ FUNCTION Parser.parseMultiplication(INOUT self: Parser): POINTER TO ParseTreeNod right WITH right ) ) - WHEN TokenType.intdiv DO + END IF + WHEN TokenType.concat DO + WHILE self.token.type = TokenType.concat DO + LET tokOp2: lexer.Token := self.token self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseExponentiation() + LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() left := NEW ParseTreeNode( - type WITH Type.IntegerDivisionExpression, - token WITH tokOp, + type WITH Type.ConcatenationExpression, + token WITH tokOp2, binaryexpression WITH BinaryExpression( startColumn WITH getStartColumn(left), endColumn WITH getEndColumn(right), @@ -1669,12 +1652,15 @@ FUNCTION Parser.parseMultiplication(INOUT self: Parser): POINTER TO ParseTreeNod right WITH right ) ) - WHEN TokenType.mod DO + END WHILE + WHEN TokenType.times DO + WHILE self.token.type = TokenType.times DO + LET tokOp2: lexer.Token := self.token self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseExponentiation() + LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() left := NEW ParseTreeNode( - type WITH Type.ModuloExpression, - token WITH tokOp, + type WITH Type.MultiplicationExpression, + token WITH tokOp2, binaryexpression WITH BinaryExpression( startColumn WITH getStartColumn(left), endColumn WITH getEndColumn(right), @@ -1682,23 +1668,14 @@ FUNCTION Parser.parseMultiplication(INOUT self: Parser): POINTER TO ParseTreeNod right WITH right ) ) - WHEN OTHERS DO - RETURN left - END CASE - END LOOP -END FUNCTION - -FUNCTION Parser.parseAddition(INOUT self: Parser): POINTER TO ParseTreeNode - VAR left: POINTER TO ParseTreeNode := self.parseMultiplication() - LOOP - LET tokOp: lexer.Token := self.token - CASE tokOp.type - WHEN TokenType.plus DO + END WHILE + IF self.token.type = TokenType.divide THEN + LET tokOp2: lexer.Token := self.token self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseMultiplication() + LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() left := NEW ParseTreeNode( - type WITH Type.AdditionExpression, - token WITH tokOp, + type WITH Type.DivisionExpression, + token WITH tokOp2, binaryexpression WITH BinaryExpression( startColumn WITH getStartColumn(left), endColumn WITH getEndColumn(right), @@ -1706,40 +1683,80 @@ FUNCTION Parser.parseAddition(INOUT self: Parser): POINTER TO ParseTreeNode right WITH right ) ) - WHEN TokenType.minus DO - self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseMultiplication() - left := NEW ParseTreeNode( - type WITH Type.SubtractionExpression, - token WITH tokOp, - binaryexpression WITH BinaryExpression( - startColumn WITH getStartColumn(left), - endColumn WITH getEndColumn(right), - left WITH left, - right WITH right - ) + END IF + WHEN TokenType.minus DO + self.nextToken() + LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() + left := NEW ParseTreeNode( + type WITH Type.SubtractionExpression, + token WITH tokOp, + binaryexpression WITH BinaryExpression( + startColumn WITH getStartColumn(left), + endColumn WITH getEndColumn(right), + left WITH left, + right WITH right ) - WHEN TokenType.concat DO - self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseMultiplication() - left := NEW ParseTreeNode( - type WITH Type.ConcatenationExpression, - token WITH tokOp, - binaryexpression WITH BinaryExpression( - startColumn WITH getStartColumn(left), - endColumn WITH getEndColumn(right), - left WITH left, - right WITH right - ) + ) + WHEN TokenType.divide DO + self.nextToken() + LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() + left := NEW ParseTreeNode( + type WITH Type.DivisionExpression, + token WITH tokOp, + binaryexpression WITH BinaryExpression( + startColumn WITH getStartColumn(left), + endColumn WITH getEndColumn(right), + left WITH left, + right WITH right ) - WHEN OTHERS DO - RETURN left - END CASE - END LOOP + ) + WHEN TokenType.intdiv DO + self.nextToken() + LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() + left := NEW ParseTreeNode( + type WITH Type.IntegerDivisionExpression, + token WITH tokOp, + binaryexpression WITH BinaryExpression( + startColumn WITH getStartColumn(left), + endColumn WITH getEndColumn(right), + left WITH left, + right WITH right + ) + ) + WHEN TokenType.mod DO + self.nextToken() + LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() + left := NEW ParseTreeNode( + type WITH Type.ModuloExpression, + token WITH tokOp, + binaryexpression WITH BinaryExpression( + startColumn WITH getStartColumn(left), + endColumn WITH getEndColumn(right), + left WITH left, + right WITH right + ) + ) + WHEN TokenType.exp DO + self.nextToken() + LET right: POINTER TO ParseTreeNode := self.parseCompoundExpression() + left := NEW ParseTreeNode( + type WITH Type.ExponentiationExpression, + token WITH tokOp, + binaryexpression WITH BinaryExpression( + startColumn WITH getStartColumn(left), + endColumn WITH getEndColumn(right), + left WITH left, + right WITH right + ) + ) + WHEN OTHERS DO + RETURN left + END CASE + RETURN left END FUNCTION FUNCTION Parser.parseComparison(INOUT self: Parser): POINTER TO ParseTreeNode - LET left: POINTER TO ParseTreeNode := self.parseAddition() + LET left: POINTER TO ParseTreeNode := self.parseArithmetic() VAR comps: Array := [] VAR tokComp: lexer.Token := lexer.Token() WHILE self.token.type IN [TokenType.equal, TokenType.notequal, TokenType.less, TokenType.greater, TokenType.lesseq, TokenType.greatereq] DO @@ -1749,7 +1766,7 @@ FUNCTION Parser.parseComparison(INOUT self: Parser): POINTER TO ParseTreeNode END IF LET comp: Comparison := comparisonFromToken(tokComp) self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseAddition() + LET right: POINTER TO ParseTreeNode := self.parseArithmetic() comps.append(ChainedComparisonPart(comp WITH comp, right WITH right)) END WHILE IF comps.size() = 0 THEN @@ -1844,50 +1861,45 @@ FUNCTION Parser.parseMembership(INOUT self: Parser): POINTER TO ParseTreeNode END IF END FUNCTION -FUNCTION Parser.parseConjunction(INOUT self: Parser): POINTER TO ParseTreeNode +FUNCTION Parser.parseLogical(INOUT self: Parser): POINTER TO ParseTreeNode VAR left: POINTER TO ParseTreeNode := self.parseMembership() - LOOP - LET tokOp: lexer.Token := self.token - IF self.token.type = TokenType.and THEN - self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseMembership() - left := NEW ParseTreeNode( - type WITH Type.ConjunctionExpression, - token WITH tokOp, - binaryexpression WITH BinaryExpression( - startColumn WITH getStartColumn(left), - endColumn WITH getEndColumn(right), - left WITH left, - right WITH right + CASE self.token.type + WHEN TokenType.and DO + WHILE self.token.type = TokenType.and DO + LET tokOp: lexer.Token := self.token + self.nextToken() + LET right: POINTER TO ParseTreeNode := self.parseMembership() + left := NEW ParseTreeNode( + type WITH Type.ConjunctionExpression, + token WITH tokOp, + binaryexpression WITH BinaryExpression( + startColumn WITH getStartColumn(left), + endColumn WITH getEndColumn(right), + left WITH left, + right WITH right + ) ) - ) - ELSE - RETURN left - END IF - END LOOP -END FUNCTION - -FUNCTION Parser.parseDisjunction(INOUT self: Parser): POINTER TO ParseTreeNode - VAR left: POINTER TO ParseTreeNode := self.parseConjunction() - LOOP - LET tokOp: lexer.Token := self.token - IF self.token.type = TokenType.or THEN - self.nextToken() - LET right: POINTER TO ParseTreeNode := self.parseConjunction() - left := NEW ParseTreeNode( - type WITH Type.DisjunctionExpression, - token WITH tokOp, - binaryexpression WITH BinaryExpression( - startColumn WITH getStartColumn(left), - endColumn WITH getEndColumn(right), - left WITH left, - right WITH right + END WHILE + WHEN TokenType.or DO + WHILE self.token.type = TokenType.or DO + LET tokOp: lexer.Token := self.token + self.nextToken() + LET right: POINTER TO ParseTreeNode := self.parseMembership() + left := NEW ParseTreeNode( + type WITH Type.DisjunctionExpression, + token WITH tokOp, + binaryexpression WITH BinaryExpression( + startColumn WITH getStartColumn(left), + endColumn WITH getEndColumn(right), + left WITH left, + right WITH right + ) ) - ) - ELSE + END WHILE + WHEN OTHERS DO RETURN left - END IF - END LOOP + END CASE + RETURN left END FUNCTION FUNCTION Parser.parseConditional(INOUT self: Parser): POINTER TO ParseTreeNode @@ -1997,7 +2009,7 @@ FUNCTION Parser.parseExpression(INOUT self: Parser): POINTER TO ParseTreeNode IF self.expressionDepth > 100 THEN error(2067, self.token, "exceeded maximum nesting depth") END IF - LET r: POINTER TO ParseTreeNode := self.parseDisjunction() + LET r: POINTER TO ParseTreeNode := self.parseLogical() DEC self.expressionDepth RETURN r END FUNCTION diff --git a/samples/flappy/flappy.neon b/samples/flappy/flappy.neon index 22743eae17..1fc1c308de 100644 --- a/samples/flappy/flappy.neon +++ b/samples/flappy/flappy.neon @@ -38,8 +38,8 @@ BEGIN MAIN player.y := 0 player.dy := 0 FOR i := 0 TO 4 DO - pipes[i].x := 640 + i * 320 - pipes[i].gap := random.uint32() MOD 300 + 100 + pipes[i].x := 640 + (i * 320) + pipes[i].gap := (random.uint32() MOD 300) + 100 END FOR VAR quit: Boolean := FALSE WHILE NOT quit DO @@ -71,7 +71,7 @@ BEGIN MAIN WHILE pipes.size() < 5 DO VAR p: Pipe := Pipe() p.x := pipes[LAST].x + 320 - p.gap := random.uint32() MOD 300 + 100 + p.gap := (random.uint32() MOD 300) + 100 pipes.append(p) END WHILE END WHILE diff --git a/samples/mandelbrot/mandelbrot.neon b/samples/mandelbrot/mandelbrot.neon index 8a500fa087..9f2a6f2895 100644 --- a/samples/mandelbrot/mandelbrot.neon +++ b/samples/mandelbrot/mandelbrot.neon @@ -59,8 +59,8 @@ FUNCTION update() LET re2: Number := z_re * z_re LET im2: Number := z_im * z_im IF re2 + im2 < 4 AND n < MAX_ITERATIONS THEN - z_im := 2 * z_re * z_im + p_im - z_re := re2 - im2 + p_re + z_im := (2 * z_re * z_im) + p_im + z_re := (re2 - im2) + p_re INC n ELSE EXIT LOOP @@ -94,7 +94,7 @@ BEGIN MAIN bmpren := sdl.CreateSoftwareRenderer(bitmap) done := multiarray.makeBoolean2D(480, 640) FOR i := 0 TO MAX_ITERATIONS-1 DO - LET x: Number := i MOD (MAX_ITERATIONS/6) * 255 / (MAX_ITERATIONS/6) + LET x: Number := (i MOD (MAX_ITERATIONS/6)) * 255 / (MAX_ITERATIONS/6) CASE math.floor(i/(MAX_ITERATIONS/6)) WHEN 0 DO palette[i] := Colour(r WITH 0, g WITH x, b WITH 255) WHEN 1 DO palette[i] := Colour(r WITH 0, g WITH 255, b WITH 255-x) diff --git a/samples/spacedebris/spacedebris.neon b/samples/spacedebris/spacedebris.neon index 7d70a588a9..eaff6e7a86 100644 --- a/samples/spacedebris/spacedebris.neon +++ b/samples/spacedebris/spacedebris.neon @@ -56,10 +56,10 @@ FUNCTION handle(e: sdl.Event, INOUT quit: Boolean) player.turn := 0.1 ELSIF e.key.keysym.sym = sdl.SDLK_SPACE THEN VAR shot: Shot := Shot() - shot.x := player.x + 20 * math.cos(player.rot) - shot.y := player.y + 20 * math.sin(player.rot) - shot.dx := player.dx + 2 * math.cos(player.rot) - shot.dy := player.dy + 2 * math.sin(player.rot) + shot.x := player.x + (20 * math.cos(player.rot)) + shot.y := player.y + (20 * math.sin(player.rot)) + shot.dx := player.dx + (2 * math.cos(player.rot)) + shot.dy := player.dy + (2 * math.sin(player.rot)) shot.count := 100 shots.append(shot) ELSIF e.key.keysym.sym = sdl.SDLK_UP THEN @@ -81,18 +81,18 @@ FUNCTION render(ren: sdl.Renderer) sdl.RenderClear(ren) sdl.SetRenderDrawColor(ren, 255, 255, 255, 255) sdl.RenderDrawLines(ren, [ - [player.x+15*math.cos(player.rot), player.y+15*math.sin(player.rot)], - [player.x+10*math.cos(player.rot+2.5), player.y+10*math.sin(player.rot+2.5)], - [player.x+7*math.cos(player.rot+2.7), player.y+7*math.sin(player.rot+2.7)], - [player.x+7*math.cos(player.rot-2.7), player.y+7*math.sin(player.rot-2.7)], - [player.x+10*math.cos(player.rot-2.5), player.y+10*math.sin(player.rot-2.5)], - [player.x+15*math.cos(player.rot), player.y+15*math.sin(player.rot)], + [player.x+(15*math.cos(player.rot)), player.y+(15*math.sin(player.rot))], + [player.x+(10*math.cos(player.rot+2.5)), player.y+(10*math.sin(player.rot+2.5))], + [player.x+(7*math.cos(player.rot+2.7)), player.y+(7*math.sin(player.rot+2.7))], + [player.x+(7*math.cos(player.rot-2.7)), player.y+(7*math.sin(player.rot-2.7))], + [player.x+(10*math.cos(player.rot-2.5)), player.y+(10*math.sin(player.rot-2.5))], + [player.x+(15*math.cos(player.rot)), player.y+(15*math.sin(player.rot))], ]) IF player.thrust THEN sdl.RenderDrawLines(ren, [ - [player.x+8*math.cos(player.rot+2.8), player.y+8*math.sin(player.rot+2.8)], - [player.x+12*math.cos(player.rot+math.Pi), player.y+12*math.sin(player.rot+math.Pi)], - [player.x+8*math.cos(player.rot-2.8), player.y+8*math.sin(player.rot-2.8)], + [player.x+(8*math.cos(player.rot+2.8)), player.y+(8*math.sin(player.rot+2.8))], + [player.x+(12*math.cos(player.rot+math.Pi)), player.y+(12*math.sin(player.rot+math.Pi))], + [player.x+(8*math.cos(player.rot-2.8)), player.y+(8*math.sin(player.rot-2.8))], ]) END IF FOREACH r IN rocks DO @@ -135,8 +135,8 @@ FUNCTION update() player.rot := player.rot + player.turn IF player.thrust THEN IF math.hypot(player.dx, player.dy) < 10 THEN - player.dx := player.dx + 0.05*math.cos(player.rot) - player.dy := player.dy + 0.05*math.sin(player.rot) + player.dx := player.dx + (0.05*math.cos(player.rot)) + player.dy := player.dy + (0.05*math.sin(player.rot)) END IF ELSE player.dx := player.dx * 0.995 @@ -157,8 +157,8 @@ FUNCTION update() VAR rock: Rock := Rock() rock.x := rocks[i].x rock.y := rocks[i].y - rock.dx := random.uint32() MOD 10 / 5 - 1 - rock.dy := random.uint32() MOD 10 / 5 - 1 + rock.dx := ((random.uint32() MOD 10) / 5) - 1 + rock.dy := ((random.uint32() MOD 10) / 5) - 1 rock.size := rocks[i].size - 1 rocks.append(rock) END FOR @@ -203,8 +203,8 @@ BEGIN MAIN VAR rock: Rock := Rock() rock.x := random.uint32() MOD 640 rock.y := random.uint32() MOD 480 - rock.dx := random.uint32() MOD 10 / 5 - 1 - rock.dy := random.uint32() MOD 10 / 5 - 1 + rock.dx := ((random.uint32() MOD 10) / 5) - 1 + rock.dy := ((random.uint32() MOD 10) / 5) - 1 rock.size := 3 rocks.append(rock) END FOR diff --git a/src/parser.cpp b/src/parser.cpp index 9438110f3f..434848536c 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -562,7 +562,7 @@ std::unique_ptr Parser::parseInterpolatedStringExpression() /* * Operator precedence: * - * ^ exponentiation parseExponentiation + * ^ exponentiation parseArithmetic * * / MOD multiplication, division, modulo parseArithmetic * + - addition, subtraction parseArithmetic * < = > comparison parseComparison diff --git a/tools/helium.py b/tools/helium.py index 60eee7c3c4..59f829affe 100644 --- a/tools/helium.py +++ b/tools/helium.py @@ -1993,61 +1993,57 @@ def parse_compound_expression(self): return AssignmentStatement(expr.func.expr, AppendExpression(expr.func.expr, expr.args[0][1])) return expr - def parse_exponentiation(self): + def parse_arithmetic(self): left = self.parse_compound_expression() - while True: - if self.tokens[self.i] is EXP: + if self.tokens[self.i] is PLUS: + while self.tokens[self.i] is PLUS: self.i += 1 right = self.parse_compound_expression() - left = ExponentiationExpression(left, right) - else: - break - return left - - def parse_multiplication(self): - left = self.parse_exponentiation() - while True: - if self.tokens[self.i] is TIMES: - self.i += 1 - right = self.parse_exponentiation() - left = MultiplicationExpression(left, right) - elif self.tokens[self.i] is DIVIDE: - self.i += 1 - right = self.parse_exponentiation() - left = DivisionExpression(left, right) - elif self.tokens[self.i] is INTDIV: - self.i += 1 - right = self.parse_exponentiation() - left = IntegerDivisionExpression(left, right) - elif self.tokens[self.i] is MOD: - self.i += 1 - right = self.parse_exponentiation() - left = ModuloExpression(left, right) - else: - break - return left - - def parse_addition(self): - left = self.parse_multiplication() - while True: - if self.tokens[self.i] is PLUS: - self.i += 1 - right = self.parse_multiplication() left = AdditionExpression(left, right) - elif self.tokens[self.i] is MINUS: + if self.tokens[self.i] is MINUS: self.i += 1 - right = self.parse_multiplication() + right = self.parse_compound_expression() left = SubtractionExpression(left, right) - elif self.tokens[self.i] is CONCAT: + elif self.tokens[self.i] is CONCAT: + while self.tokens[self.i] is CONCAT: self.i += 1 - right = self.parse_multiplication() + right = self.parse_compound_expression() left = ConcatenationExpression(left, right) - else: - break + elif self.tokens[self.i] is TIMES: + while self.tokens[self.i] is TIMES: + self.i += 1 + right = self.parse_compound_expression() + left = MultiplicationExpression(left, right) + if self.tokens[self.i] is DIVIDE: + self.i += 1 + right = self.parse_compound_expression() + left = DivisionExpression(left, right) + elif self.tokens[self.i] is MINUS: + self.i += 1 + right = self.parse_compound_expression() + left = SubtractionExpression(left, right) + elif self.tokens[self.i] is DIVIDE: + self.i += 1 + right = self.parse_compound_expression() + left = DivisionExpression(left, right) + elif self.tokens[self.i] is INTDIV: + self.i += 1 + right = self.parse_compound_expression() + left = IntegerDivisionExpression(left, right) + elif self.tokens[self.i] is MOD: + self.i += 1 + right = self.parse_compound_expression() + left = ModuloExpression(left, right) + elif self.tokens[self.i] is EXP: + self.i += 1 + right = self.parse_compound_expression() + left = ExponentiationExpression(left, right) + else: + return left return left def parse_comparison(self): - left = self.parse_addition() + left = self.parse_arithmetic() comps = [] while (self.tokens[self.i] is EQUAL or self.tokens[self.i] is NOTEQUAL @@ -2057,7 +2053,7 @@ def parse_comparison(self): or self.tokens[self.i] is GREATEREQ): comp = self.tokens[self.i] self.i += 1 - right = self.parse_addition() + right = self.parse_arithmetic() comps.append(ComparisonExpression(left, right, comp)) left = right if not comps: @@ -2091,20 +2087,18 @@ def parse_membership(self): else: return left - def parse_conjunction(self): + def parse_logical(self): left = self.parse_membership() - while self.tokens[self.i] is AND: - self.i += 1 - right = self.parse_membership() - left = ConjunctionExpression(left, right) - return left - - def parse_disjunction(self): - left = self.parse_conjunction() - while self.tokens[self.i] is OR: - self.i += 1 - right = self.parse_conjunction() - left = DisjunctionExpression(left, right) + if self.tokens[self.i] is AND: + while self.tokens[self.i] is AND: + self.i += 1 + right = self.parse_membership() + left = ConjunctionExpression(left, right) + elif self.tokens[self.i] is OR: + while self.tokens[self.i] is OR: + self.i += 1 + right = self.parse_membership() + left = DisjunctionExpression(left, right) return left def parse_conditional(self): @@ -2147,7 +2141,7 @@ def parse_conditional(self): catches.append((exceptions, infoname, g)) return TryExpression(expr, catches) else: - return self.parse_disjunction() + return self.parse_logical() def parse_expression(self): return self.parse_conditional()