Skip to content

Commit 6bcb9b1

Browse files
Change +, -, *, /, //, and % operators' associativity to left-to-right (#280)
* Change + - * / // % operators' associativity to left-to-right * Minor fix (now '2+' is error)
1 parent 37a5409 commit 6bcb9b1

2 files changed

Lines changed: 59 additions & 52 deletions

File tree

src/expression_parser.cpp

Lines changed: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -196,64 +196,67 @@ ExpressionParser::ParseResult<ExpressionEvaluatorPtr<Expression>> ExpressionPars
196196

197197
ExpressionParser::ParseResult<ExpressionEvaluatorPtr<Expression>> ExpressionParser::ParseMathPlusMinus(LexScanner& lexer)
198198
{
199-
auto left = ParseMathMulDiv(lexer);
200-
if (!left)
201-
return left;
202-
203-
auto tok = lexer.NextToken();
204-
BinaryExpression::Operation operation;
205-
switch (tok.type)
206-
{
207-
case '+':
208-
operation = BinaryExpression::Plus;
209-
break;
210-
case '-':
211-
operation = BinaryExpression::Minus;
212-
break;
213-
default:
214-
lexer.ReturnToken();
215-
return left;
199+
auto res = ParseMathMulDiv(lexer);
200+
if (!res)
201+
return res;
202+
203+
while (true) {
204+
auto tok = lexer.NextToken();
205+
BinaryExpression::Operation operation;
206+
switch (tok.type)
207+
{
208+
case '+':
209+
operation = BinaryExpression::Plus;
210+
break;
211+
case '-':
212+
operation = BinaryExpression::Minus;
213+
break;
214+
default:
215+
lexer.ReturnToken();
216+
return res;
217+
}
218+
auto right = ParseMathMulDiv(lexer);
219+
if (!right)
220+
return right;
221+
res = std::make_shared<BinaryExpression>(operation, *res, *right);
216222
}
217-
218-
auto right = ParseMathPlusMinus(lexer);
219-
if (!right)
220-
return right;
221-
222-
return std::make_shared<BinaryExpression>(operation, *left, *right);
223+
return res;
223224
}
224225

225226
ExpressionParser::ParseResult<ExpressionEvaluatorPtr<Expression>> ExpressionParser::ParseMathMulDiv(LexScanner& lexer)
226227
{
227-
auto left = ParseUnaryPlusMinus(lexer);
228-
if (!left)
229-
return left;
230-
231-
auto tok = lexer.NextToken();
232-
BinaryExpression::Operation operation;
233-
switch (tok.type)
234-
{
235-
case '*':
236-
operation = BinaryExpression::Mul;
237-
break;
238-
case '/':
239-
operation = BinaryExpression::Div;
240-
break;
241-
case Token::DivDiv:
242-
operation = BinaryExpression::DivInteger;
243-
break;
244-
case '%':
245-
operation = BinaryExpression::DivRemainder;
246-
break;
247-
default:
248-
lexer.ReturnToken();
249-
return left;
228+
auto res = ParseUnaryPlusMinus(lexer);
229+
if (!res)
230+
return res;
231+
232+
while (true) {
233+
auto tok = lexer.NextToken();
234+
BinaryExpression::Operation operation;
235+
switch (tok.type)
236+
{
237+
case '*':
238+
operation = BinaryExpression::Mul;
239+
break;
240+
case '/':
241+
operation = BinaryExpression::Div;
242+
break;
243+
case Token::DivDiv:
244+
operation = BinaryExpression::DivInteger;
245+
break;
246+
case '%':
247+
operation = BinaryExpression::DivRemainder;
248+
break;
249+
default:
250+
lexer.ReturnToken();
251+
return res;
252+
}
253+
auto right = ParseUnaryPlusMinus(lexer);
254+
if (!right)
255+
return right;
256+
res = std::make_shared<BinaryExpression>(operation, *res, *right);
250257
}
251-
252-
auto right = ParseMathMulDiv(lexer);
253-
if (!right)
254-
return right;
255-
256-
return std::make_shared<BinaryExpression>(operation, *left, *right);
258+
259+
return res;
257260
}
258261

259262
ExpressionParser::ParseResult<ExpressionEvaluatorPtr<Expression>> ExpressionParser::ParseUnaryPlusMinus(LexScanner& lexer)

test/expressions_test.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ R"(
2424
{{ 3 ** 4 }}
2525
{{ 10 ** -2 }}
2626
{{ 10/10 + 2*5 }}
27+
{{ 10 - 2 - 4 }}
28+
{{ 200 / 2 / 2 }}
2729
{{ ([1, 2] + [3, 4]) | pprint }}
2830
{{ 'Hello' + " " + 'World ' + stringValue }}
2931
{{ 'Hello' + " " + 'World ' + wstringValue }}
@@ -53,6 +55,8 @@ R"(
5355
81
5456
0.01
5557
11
58+
4
59+
50
5660
[1, 2, 3, 4]
5761
Hello World rain
5862
Hello World rain

0 commit comments

Comments
 (0)