From d122827a30de9b0bb5c0cdcfe7f338eb036145db Mon Sep 17 00:00:00 2001 From: JT <547158+jntrnr@users.noreply.github.com> Date: Fri, 25 Mar 2022 16:23:08 +1300 Subject: [PATCH] Fix operator precedence parser (#4947) --- crates/nu-command/tests/commands/math/mod.rs | 24 ++++++++++++++++++++ crates/nu-parser/src/parser.rs | 10 +++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/crates/nu-command/tests/commands/math/mod.rs b/crates/nu-command/tests/commands/math/mod.rs index 01a60556a..d8e810974 100644 --- a/crates/nu-command/tests/commands/math/mod.rs +++ b/crates/nu-command/tests/commands/math/mod.rs @@ -67,6 +67,30 @@ fn precedence_of_operators2() { assert_eq!(actual.out, "6"); } +#[test] +fn precedence_of_operators3() { + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + r#" + 5 - 5 * 10 + 5 + "# + )); + + assert_eq!(actual.out, "-40"); +} + +#[test] +fn precedence_of_operators4() { + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + r#" + 5 - (5 * 10) + 5 + "# + )); + + assert_eq!(actual.out, "-40"); +} + #[test] fn division_of_ints() { let actual = nu!( diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 2ea697d9c..97e9cbf95 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -4019,7 +4019,7 @@ pub fn parse_math_expression( ); error = error.or(err); - if op_prec <= last_prec && expr_stack.len() > 1 { + while op_prec <= last_prec && expr_stack.len() > 1 { // Collapse the right associated operations first // so that we can get back to a stack with a lower precedence let mut rhs = expr_stack @@ -4029,6 +4029,14 @@ pub fn parse_math_expression( .pop() .expect("internal error: expression stack empty"); + last_prec = op.precedence(); + + if last_prec < op_prec { + expr_stack.push(op); + expr_stack.push(rhs); + break; + } + let mut lhs = expr_stack .pop() .expect("internal error: expression stack empty");