From 87d8f4f3165d72e1935770e77eeb6eaf7fa333c9 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 13 Feb 2022 11:59:01 +0530 Subject: [PATCH 1/3] handle operator associavity port of @oberblastmeister's changes from #35 --- src/parser.rs | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 52bb631..9e21107 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -666,7 +666,7 @@ where self.parse_fn() } } - fn handle_operation( + fn handle_operation_left( &mut self, once: bool, next: fn(&mut Self) -> Checkpoint, @@ -684,17 +684,36 @@ where } checkpoint } + fn handle_operation_right( + &mut self, + once: bool, + next: fn(&mut Self) -> Checkpoint, + ops: &[SyntaxKind], + ) -> Checkpoint { + let checkpoint = next(self); + if self.peek().map(|t| ops.contains(&t)).unwrap_or(false) { + self.start_node_at(checkpoint, NODE_BIN_OP); + self.bump(); + if once { + next(self); + } else { + self.handle_operation_right(once, next, ops); + } + self.finish_node(); + } + checkpoint + } fn parse_isset(&mut self) -> Checkpoint { - self.handle_operation(false, Self::parse_negate, &[TOKEN_QUESTION]) + self.handle_operation_left(false, Self::parse_negate, &[TOKEN_QUESTION]) } fn parse_concat(&mut self) -> Checkpoint { - self.handle_operation(false, Self::parse_isset, &[TOKEN_CONCAT]) + self.handle_operation_right(false, Self::parse_isset, &[TOKEN_CONCAT]) } fn parse_mul(&mut self) -> Checkpoint { - self.handle_operation(false, Self::parse_concat, &[TOKEN_MUL, TOKEN_DIV]) + self.handle_operation_left(false, Self::parse_concat, &[TOKEN_MUL, TOKEN_DIV]) } fn parse_add(&mut self) -> Checkpoint { - self.handle_operation(false, Self::parse_mul, &[TOKEN_ADD, TOKEN_SUB]) + self.handle_operation_left(false, Self::parse_mul, &[TOKEN_ADD, TOKEN_SUB]) } fn parse_invert(&mut self) -> Checkpoint { if self.peek() == Some(TOKEN_INVERT) { @@ -709,26 +728,26 @@ where } } fn parse_merge(&mut self) -> Checkpoint { - self.handle_operation(false, Self::parse_invert, &[TOKEN_UPDATE]) + self.handle_operation_right(false, Self::parse_invert, &[TOKEN_UPDATE]) } fn parse_compare(&mut self) -> Checkpoint { - self.handle_operation( + self.handle_operation_left( true, Self::parse_merge, &[TOKEN_LESS, TOKEN_LESS_OR_EQ, TOKEN_MORE, TOKEN_MORE_OR_EQ], ) } fn parse_equal(&mut self) -> Checkpoint { - self.handle_operation(true, Self::parse_compare, &[TOKEN_EQUAL, TOKEN_NOT_EQUAL]) + self.handle_operation_left(true, Self::parse_compare, &[TOKEN_EQUAL, TOKEN_NOT_EQUAL]) } fn parse_and(&mut self) -> Checkpoint { - self.handle_operation(false, Self::parse_equal, &[TOKEN_AND]) + self.handle_operation_left(false, Self::parse_equal, &[TOKEN_AND]) } fn parse_or(&mut self) -> Checkpoint { - self.handle_operation(false, Self::parse_and, &[TOKEN_OR]) + self.handle_operation_left(false, Self::parse_and, &[TOKEN_OR]) } fn parse_implication(&mut self) -> Checkpoint { - self.handle_operation(false, Self::parse_or, &[TOKEN_IMPLICATION]) + self.handle_operation_right(false, Self::parse_or, &[TOKEN_IMPLICATION]) } #[inline(always)] fn parse_math(&mut self) -> Checkpoint { From 4e1b9ac6aa735691bd3bbc0e28544917049168b5 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 13 Feb 2022 12:11:31 +0530 Subject: [PATCH 2/3] update tests --- test_data/general/lists.expect | 38 +++++----- test_data/general/operators.expect | 111 +++++++++++++++++++++++++++++ test_data/general/operators.nix | 6 ++ test_data/parser/list/2.expect | 30 ++++---- 4 files changed, 151 insertions(+), 34 deletions(-) create mode 100644 test_data/general/operators.expect create mode 100644 test_data/general/operators.nix diff --git a/test_data/general/lists.expect b/test_data/general/lists.expect index 5cd475e..2ed5ddb 100644 --- a/test_data/general/lists.expect +++ b/test_data/general/lists.expect @@ -55,17 +55,17 @@ NODE_ROOT 0..62 { TOKEN_ASSIGN("=") 38..39 TOKEN_WHITESPACE(" ") 39..40 NODE_BIN_OP 40..59 { - NODE_BIN_OP 40..52 { - NODE_LIST 40..43 { - TOKEN_SQUARE_B_OPEN("[") 40..41 - NODE_LITERAL 41..42 { - TOKEN_INTEGER("1") 41..42 - } - TOKEN_SQUARE_B_CLOSE("]") 42..43 + NODE_LIST 40..43 { + TOKEN_SQUARE_B_OPEN("[") 40..41 + NODE_LITERAL 41..42 { + TOKEN_INTEGER("1") 41..42 } - TOKEN_WHITESPACE(" ") 43..44 - TOKEN_CONCAT("++") 44..46 - TOKEN_WHITESPACE(" ") 46..47 + TOKEN_SQUARE_B_CLOSE("]") 42..43 + } + TOKEN_WHITESPACE(" ") 43..44 + TOKEN_CONCAT("++") 44..46 + TOKEN_WHITESPACE(" ") 46..47 + NODE_BIN_OP 47..59 { NODE_LIST 47..52 { TOKEN_SQUARE_B_OPEN("[") 47..48 NODE_LITERAL 48..49 { @@ -77,16 +77,16 @@ NODE_ROOT 0..62 { } TOKEN_SQUARE_B_CLOSE("]") 51..52 } - } - TOKEN_WHITESPACE(" ") 52..53 - TOKEN_CONCAT("++") 53..55 - TOKEN_WHITESPACE(" ") 55..56 - NODE_LIST 56..59 { - TOKEN_SQUARE_B_OPEN("[") 56..57 - NODE_LITERAL 57..58 { - TOKEN_INTEGER("4") 57..58 + TOKEN_WHITESPACE(" ") 52..53 + TOKEN_CONCAT("++") 53..55 + TOKEN_WHITESPACE(" ") 55..56 + NODE_LIST 56..59 { + TOKEN_SQUARE_B_OPEN("[") 56..57 + NODE_LITERAL 57..58 { + TOKEN_INTEGER("4") 57..58 + } + TOKEN_SQUARE_B_CLOSE("]") 58..59 } - TOKEN_SQUARE_B_CLOSE("]") 58..59 } } TOKEN_SEMICOLON(";") 59..60 diff --git a/test_data/general/operators.expect b/test_data/general/operators.expect new file mode 100644 index 0000000..34854a4 --- /dev/null +++ b/test_data/general/operators.expect @@ -0,0 +1,111 @@ +NODE_ROOT 0..71 { + NODE_LIST 0..71 { + TOKEN_SQUARE_B_OPEN("[") 0..1 + TOKEN_WHITESPACE("\n ") 1..4 + NODE_PAREN 4..17 { + TOKEN_PAREN_OPEN("(") 4..5 + NODE_BIN_OP 5..16 { + NODE_IDENT 5..6 { + TOKEN_IDENT("a") 5..6 + } + TOKEN_WHITESPACE(" ") 6..7 + TOKEN_IMPLICATION("->") 7..9 + TOKEN_WHITESPACE(" ") 9..10 + NODE_BIN_OP 10..16 { + NODE_IDENT 10..11 { + TOKEN_IDENT("b") 10..11 + } + TOKEN_WHITESPACE(" ") 11..12 + TOKEN_IMPLICATION("->") 12..14 + TOKEN_WHITESPACE(" ") 14..15 + NODE_IDENT 15..16 { + TOKEN_IDENT("c") 15..16 + } + } + } + TOKEN_PAREN_CLOSE(")") 16..17 + } + TOKEN_WHITESPACE("\n ") 17..20 + NODE_PAREN 20..33 { + TOKEN_PAREN_OPEN("(") 20..21 + NODE_BIN_OP 21..32 { + NODE_IDENT 21..22 { + TOKEN_IDENT("a") 21..22 + } + TOKEN_WHITESPACE(" ") 22..23 + TOKEN_CONCAT("++") 23..25 + TOKEN_WHITESPACE(" ") 25..26 + NODE_BIN_OP 26..32 { + NODE_IDENT 26..27 { + TOKEN_IDENT("b") 26..27 + } + TOKEN_WHITESPACE(" ") 27..28 + TOKEN_CONCAT("++") 28..30 + TOKEN_WHITESPACE(" ") 30..31 + NODE_IDENT 31..32 { + TOKEN_IDENT("c") 31..32 + } + } + } + TOKEN_PAREN_CLOSE(")") 32..33 + } + TOKEN_WHITESPACE("\n ") 33..36 + NODE_PAREN 36..49 { + TOKEN_PAREN_OPEN("(") 36..37 + NODE_BIN_OP 37..48 { + NODE_IDENT 37..38 { + TOKEN_IDENT("a") 37..38 + } + TOKEN_WHITESPACE(" ") 38..39 + TOKEN_UPDATE("//") 39..41 + TOKEN_WHITESPACE(" ") 41..42 + NODE_BIN_OP 42..48 { + NODE_IDENT 42..43 { + TOKEN_IDENT("b") 42..43 + } + TOKEN_WHITESPACE(" ") 43..44 + TOKEN_UPDATE("//") 44..46 + TOKEN_WHITESPACE(" ") 46..47 + NODE_IDENT 47..48 { + TOKEN_IDENT("c") 47..48 + } + } + } + TOKEN_PAREN_CLOSE(")") 48..49 + } + TOKEN_WHITESPACE("\n ") 49..52 + NODE_PAREN 52..69 { + TOKEN_PAREN_OPEN("(") 52..53 + NODE_BIN_OP 53..68 { + NODE_BIN_OP 53..63 { + NODE_BIN_OP 53..58 { + NODE_IDENT 53..54 { + TOKEN_IDENT("a") 53..54 + } + TOKEN_WHITESPACE(" ") 54..55 + TOKEN_ADD("+") 55..56 + TOKEN_WHITESPACE(" ") 56..57 + NODE_IDENT 57..58 { + TOKEN_IDENT("b") 57..58 + } + } + TOKEN_WHITESPACE(" ") 58..59 + TOKEN_UPDATE("//") 59..61 + TOKEN_WHITESPACE(" ") 61..62 + NODE_IDENT 62..63 { + TOKEN_IDENT("c") 62..63 + } + } + TOKEN_WHITESPACE(" ") 63..64 + TOKEN_IMPLICATION("->") 64..66 + TOKEN_WHITESPACE(" ") 66..67 + NODE_IDENT 67..68 { + TOKEN_IDENT("d") 67..68 + } + } + TOKEN_PAREN_CLOSE(")") 68..69 + } + TOKEN_WHITESPACE("\n") 69..70 + TOKEN_SQUARE_B_CLOSE("]") 70..71 + } +} diff --git a/test_data/general/operators.nix b/test_data/general/operators.nix new file mode 100644 index 0000000..3fd18ff --- /dev/null +++ b/test_data/general/operators.nix @@ -0,0 +1,6 @@ +[ + (a -> b -> c) + (a ++ b ++ c) + (a // b // c) + (a + b // c -> d) +] diff --git a/test_data/parser/list/2.expect b/test_data/parser/list/2.expect index b9bf094..820be2b 100644 --- a/test_data/parser/list/2.expect +++ b/test_data/parser/list/2.expect @@ -1,14 +1,14 @@ NODE_ROOT 0..15 { NODE_BIN_OP 0..15 { - NODE_BIN_OP 0..10 { - NODE_LIST 0..3 { - TOKEN_SQUARE_B_OPEN("[") 0..1 - NODE_LITERAL 1..2 { - TOKEN_INTEGER("1") 1..2 - } - TOKEN_SQUARE_B_CLOSE("]") 2..3 + NODE_LIST 0..3 { + TOKEN_SQUARE_B_OPEN("[") 0..1 + NODE_LITERAL 1..2 { + TOKEN_INTEGER("1") 1..2 } - TOKEN_CONCAT("++") 3..5 + TOKEN_SQUARE_B_CLOSE("]") 2..3 + } + TOKEN_CONCAT("++") 3..5 + NODE_BIN_OP 5..15 { NODE_LIST 5..10 { TOKEN_SQUARE_B_OPEN("[") 5..6 NODE_IDENT 6..9 { @@ -16,14 +16,14 @@ NODE_ROOT 0..15 { } TOKEN_SQUARE_B_CLOSE("]") 9..10 } - } - TOKEN_CONCAT("++") 10..12 - NODE_LIST 12..15 { - TOKEN_SQUARE_B_OPEN("[") 12..13 - NODE_LITERAL 13..14 { - TOKEN_INTEGER("3") 13..14 + TOKEN_CONCAT("++") 10..12 + NODE_LIST 12..15 { + TOKEN_SQUARE_B_OPEN("[") 12..13 + NODE_LITERAL 13..14 { + TOKEN_INTEGER("3") 13..14 + } + TOKEN_SQUARE_B_CLOSE("]") 14..15 } - TOKEN_SQUARE_B_CLOSE("]") 14..15 } } } From f6873361f30a9b5c7aa1ae6dbacac14a63f25100 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 10 Jul 2022 19:55:58 +0530 Subject: [PATCH 3/3] remove `once` from `handle_operation_right` --- src/parser.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 9e21107..adb4a4d 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -686,7 +686,6 @@ where } fn handle_operation_right( &mut self, - once: bool, next: fn(&mut Self) -> Checkpoint, ops: &[SyntaxKind], ) -> Checkpoint { @@ -694,11 +693,7 @@ where if self.peek().map(|t| ops.contains(&t)).unwrap_or(false) { self.start_node_at(checkpoint, NODE_BIN_OP); self.bump(); - if once { - next(self); - } else { - self.handle_operation_right(once, next, ops); - } + self.handle_operation_right(next, ops); self.finish_node(); } checkpoint @@ -707,7 +702,7 @@ where self.handle_operation_left(false, Self::parse_negate, &[TOKEN_QUESTION]) } fn parse_concat(&mut self) -> Checkpoint { - self.handle_operation_right(false, Self::parse_isset, &[TOKEN_CONCAT]) + self.handle_operation_right(Self::parse_isset, &[TOKEN_CONCAT]) } fn parse_mul(&mut self) -> Checkpoint { self.handle_operation_left(false, Self::parse_concat, &[TOKEN_MUL, TOKEN_DIV]) @@ -728,7 +723,7 @@ where } } fn parse_merge(&mut self) -> Checkpoint { - self.handle_operation_right(false, Self::parse_invert, &[TOKEN_UPDATE]) + self.handle_operation_right(Self::parse_invert, &[TOKEN_UPDATE]) } fn parse_compare(&mut self) -> Checkpoint { self.handle_operation_left( @@ -747,7 +742,7 @@ where self.handle_operation_left(false, Self::parse_and, &[TOKEN_OR]) } fn parse_implication(&mut self) -> Checkpoint { - self.handle_operation_right(false, Self::parse_or, &[TOKEN_IMPLICATION]) + self.handle_operation_right(Self::parse_or, &[TOKEN_IMPLICATION]) } #[inline(always)] fn parse_math(&mut self) -> Checkpoint {