From 03f165cc89bcd5dc8fe0d3803d3b3a8921cdafb7 Mon Sep 17 00:00:00 2001 From: Timur Muratshin Date: Sun, 10 Aug 2025 23:02:54 +0300 Subject: [PATCH 1/2] Change + - * / // % operators' associativity to left-to-right --- src/expression_parser.cpp | 107 ++++++++++++++++++++------------------ test/expressions_test.cpp | 4 ++ 2 files changed, 59 insertions(+), 52 deletions(-) diff --git a/src/expression_parser.cpp b/src/expression_parser.cpp index 3567d966..f1fee50d 100644 --- a/src/expression_parser.cpp +++ b/src/expression_parser.cpp @@ -196,64 +196,67 @@ ExpressionParser::ParseResult> ExpressionPars ExpressionParser::ParseResult> ExpressionParser::ParseMathPlusMinus(LexScanner& lexer) { - auto left = ParseMathMulDiv(lexer); - if (!left) - return left; - - auto tok = lexer.NextToken(); - BinaryExpression::Operation operation; - switch (tok.type) - { - case '+': - operation = BinaryExpression::Plus; - break; - case '-': - operation = BinaryExpression::Minus; - break; - default: - lexer.ReturnToken(); - return left; + auto res = ParseMathMulDiv(lexer); + if (!res) + return res; + + while (true) { + auto tok = lexer.NextToken(); + BinaryExpression::Operation operation; + switch (tok.type) + { + case '+': + operation = BinaryExpression::Plus; + break; + case '-': + operation = BinaryExpression::Minus; + break; + default: + lexer.ReturnToken(); + return res; + } + auto right = ParseMathMulDiv(lexer); + if (!right) + return res; + res = std::make_shared(operation, *res, *right); } - - auto right = ParseMathPlusMinus(lexer); - if (!right) - return right; - - return std::make_shared(operation, *left, *right); + return res; } ExpressionParser::ParseResult> ExpressionParser::ParseMathMulDiv(LexScanner& lexer) { - auto left = ParseUnaryPlusMinus(lexer); - if (!left) - return left; - - auto tok = lexer.NextToken(); - BinaryExpression::Operation operation; - switch (tok.type) - { - case '*': - operation = BinaryExpression::Mul; - break; - case '/': - operation = BinaryExpression::Div; - break; - case Token::DivDiv: - operation = BinaryExpression::DivInteger; - break; - case '%': - operation = BinaryExpression::DivRemainder; - break; - default: - lexer.ReturnToken(); - return left; + auto res = ParseUnaryPlusMinus(lexer); + if (!res) + return res; + + while (true) { + auto tok = lexer.NextToken(); + BinaryExpression::Operation operation; + switch (tok.type) + { + case '*': + operation = BinaryExpression::Mul; + break; + case '/': + operation = BinaryExpression::Div; + break; + case Token::DivDiv: + operation = BinaryExpression::DivInteger; + break; + case '%': + operation = BinaryExpression::DivRemainder; + break; + default: + lexer.ReturnToken(); + return res; + } + auto right = ParseUnaryPlusMinus(lexer); + if (!right) + return res; + res = std::make_shared(operation, *res, *right); } - - auto right = ParseMathMulDiv(lexer); - if (!right) - return right; - - return std::make_shared(operation, *left, *right); + + return res; } ExpressionParser::ParseResult> ExpressionParser::ParseUnaryPlusMinus(LexScanner& lexer) diff --git a/test/expressions_test.cpp b/test/expressions_test.cpp index 462f50bd..cb694338 100644 --- a/test/expressions_test.cpp +++ b/test/expressions_test.cpp @@ -24,6 +24,8 @@ R"( {{ 3 ** 4 }} {{ 10 ** -2 }} {{ 10/10 + 2*5 }} +{{ 10 - 2 - 4 }} +{{ 200 / 2 / 2 }} {{ ([1, 2] + [3, 4]) | pprint }} {{ 'Hello' + " " + 'World ' + stringValue }} {{ 'Hello' + " " + 'World ' + wstringValue }} @@ -53,6 +55,8 @@ R"( 81 0.01 11 +4 +50 [1, 2, 3, 4] Hello World rain Hello World rain From a6472804047f63f9cda40460a867f091a4304e82 Mon Sep 17 00:00:00 2001 From: Timur Muratshin Date: Sun, 10 Aug 2025 23:45:01 +0300 Subject: [PATCH 2/2] Minor fix (now '2+' is error) --- src/expression_parser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/expression_parser.cpp b/src/expression_parser.cpp index f1fee50d..ccc9fd5a 100644 --- a/src/expression_parser.cpp +++ b/src/expression_parser.cpp @@ -217,7 +217,7 @@ ExpressionParser::ParseResult> ExpressionPars } auto right = ParseMathMulDiv(lexer); if (!right) - return res; + return right; res = std::make_shared(operation, *res, *right); } return res; @@ -252,7 +252,7 @@ ExpressionParser::ParseResult> ExpressionPars } auto right = ParseUnaryPlusMinus(lexer); if (!right) - return res; + return right; res = std::make_shared(operation, *res, *right); }