From ab0a6fd48422681ce904ea596ba8bba663c9329b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Dobrovoljc?= Date: Tue, 3 Jun 2025 17:26:46 +0200 Subject: [PATCH] Make + operator bind more strongly than multiplication operators --- src/pins25/phase/SynAn.java | 88 +++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 38 deletions(-) diff --git a/src/pins25/phase/SynAn.java b/src/pins25/phase/SynAn.java index e4f2304..68c7a36 100644 --- a/src/pins25/phase/SynAn.java +++ b/src/pins25/phase/SynAn.java @@ -5,6 +5,7 @@ import pins25.common.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Objects; /** * Sintaksni analizator. @@ -466,7 +467,7 @@ public class SynAn implements AutoCloseable { checkExpression(); // cmpexpr -> addexpr restcmp - AST.Expr left = parseAdditionExpression(); + AST.Expr left = parseSubstractionExpression(); return parseRestComparisons(left); } @@ -476,7 +477,7 @@ public class SynAn implements AutoCloseable { case EQU: { // restcmp -> EQU addexpr check(Token.Symbol.EQU); - AST.Expr right = parseAdditionExpression(); + AST.Expr right = parseSubstractionExpression(); AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.EQU, left, right); attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); return binExpr; @@ -484,7 +485,7 @@ public class SynAn implements AutoCloseable { case NEQ: { // restcmp -> NEQ addexpr check(Token.Symbol.NEQ); - AST.Expr right = parseAdditionExpression(); + AST.Expr right = parseSubstractionExpression(); AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.NEQ, left, right); attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); return binExpr; @@ -492,7 +493,7 @@ public class SynAn implements AutoCloseable { case LTH: { // restcmp -> LTH addexpr check(Token.Symbol.LTH); - AST.Expr right = parseAdditionExpression(); + AST.Expr right = parseSubstractionExpression(); AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.LTH, left, right); attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); return binExpr; @@ -500,7 +501,7 @@ public class SynAn implements AutoCloseable { case GTH: { // restcmp -> GTH addexpr check(Token.Symbol.GTH); - AST.Expr right = parseAdditionExpression(); + AST.Expr right = parseSubstractionExpression(); AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.GTH, left, right); attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); return binExpr; @@ -508,7 +509,7 @@ public class SynAn implements AutoCloseable { case LEQ: { // restcmp -> LEQ addexpr check(Token.Symbol.LEQ); - AST.Expr right = parseAdditionExpression(); + AST.Expr right = parseSubstractionExpression(); AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.LEQ, left, right); attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); return binExpr; @@ -516,7 +517,7 @@ public class SynAn implements AutoCloseable { case GEQ: { // restcmp -> GEQ addexpr check(Token.Symbol.GEQ); - AST.Expr right = parseAdditionExpression(); + AST.Expr right = parseSubstractionExpression(); AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.GEQ, left, right); attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); return binExpr; @@ -528,38 +529,27 @@ public class SynAn implements AutoCloseable { } } - private AST.Expr parseAdditionExpression() { + + private AST.Expr parseSubstractionExpression() { checkExpression(); - // addexpr -> multexpr restadd + // subexpr -> multexpr restsub AST.Expr left = parseMultiplicationExpression(); - return parseRestAdditionExpressions(left); + return parseRestSubtractionExpressions(left); } - private AST.Expr parseRestAdditionExpressions(AST.Expr left) { + private AST.Expr parseRestSubtractionExpressions(AST.Expr left) { Token token = lexAn.peekToken(); - switch (token.symbol()) { - case ADD: { - // restadd -> ADD multexpr restadd - check(Token.Symbol.ADD); - AST.Expr right = parseMultiplicationExpression(); - AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.ADD, left, right); - attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); - return parseRestAdditionExpressions(binExpr); - } - case SUB: { - // restadd -> SUB multexpr restadd - check(Token.Symbol.SUB); - AST.Expr right = parseMultiplicationExpression(); - AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.SUB, left, right); - attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); - return parseRestAdditionExpressions(binExpr); - } - - default: - // restadd -> ε - return left; + if (Objects.requireNonNull(token.symbol()) == Token.Symbol.SUB) { + // restsub -> SUB multexpr restsub + check(Token.Symbol.SUB); + AST.Expr right = parseMultiplicationExpression(); + AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.SUB, left, right); + attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); + return parseRestSubtractionExpressions(binExpr); } + // restsub -> ε + return left; } private AST.Expr parseMultiplicationExpression() { @@ -574,25 +564,25 @@ public class SynAn implements AutoCloseable { Token token = lexAn.peekToken(); switch (token.symbol()) { case MUL: { - // restmult -> MUL prefixexpr restmult + // restmult -> MUL addexpr restmult check(Token.Symbol.MUL); - AST.Expr right = parsePrefixExpression(); + AST.Expr right = parseAdditionExpression(); AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.MUL, left, right); attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); return parseRestMultiplicationExpressions(binExpr); } case DIV: { - // restmult -> DIV prefixexpr restmult + // restmult -> DIV addexpr restmult check(Token.Symbol.DIV); - AST.Expr right = parsePrefixExpression(); + AST.Expr right = parseAdditionExpression(); AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.DIV, left, right); attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); return parseRestMultiplicationExpressions(binExpr); } case MOD: { - // restmult -> MOD prefixexpr restmult + // restmult -> MOD addexpr restmult check(Token.Symbol.MOD); - AST.Expr right = parsePrefixExpression(); + AST.Expr right = parseAdditionExpression(); AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.MOD, left, right); attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); return parseRestMultiplicationExpressions(binExpr); @@ -604,6 +594,28 @@ public class SynAn implements AutoCloseable { } } + private AST.Expr parseAdditionExpression() { + checkExpression(); + + // addexpr -> prefexpr restadd + AST.Expr left = parsePrefixExpression(); + return parseRestAdditionExpressions(left); + } + + private AST.Expr parseRestAdditionExpressions(AST.Expr left) { + Token token = lexAn.peekToken(); + if (Objects.requireNonNull(token.symbol()) == Token.Symbol.ADD) { + // restadd -> ADD multexpr restadd + check(Token.Symbol.ADD); + AST.Expr right = parsePrefixExpression(); + AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.ADD, left, right); + attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right))); + return parseRestAdditionExpressions(binExpr); + } + // restadd -> ε + return left; + } + private AST.Expr parsePrefixExpression() { checkExpression();