From 63bad5ddfee3c0f2e1ceb5677ffc0f10f6a74bb3 Mon Sep 17 00:00:00 2001 From: Daniel Pfister <80419299+0x2a-42@users.noreply.github.com> Date: Thu, 2 Jan 2025 17:43:17 +0100 Subject: [PATCH] Improve code completion Top level identifiers are no longer parsed as rules, which improves suggestions, as the following rules are now parsed correctly. --- src/frontend/generated.rs | 6 +++++- src/frontend/lelwel.llw | 2 +- src/frontend/parser.rs | 7 ++++++- tests/frontend.rs | 11 +++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/frontend/generated.rs b/src/frontend/generated.rs index 53658ea..a3fefaa 100644 --- a/src/frontend/generated.rs +++ b/src/frontend/generated.rs @@ -419,7 +419,7 @@ impl<'a> Parser<'a> { Token::Token => { self.r#token_list(diags); } - Token::Id => { + Token::Id if self.predicate_decl_1() => { self.r#rule_decl(diags); } Token::Start => { @@ -431,6 +431,9 @@ impl<'a> Parser<'a> { Token::Skip => { self.r#skip_decl(diags); } + Token::Id => { + self.advance_with_error(diags, err![self.span(),]); + } _ => { self.error( diags, @@ -878,4 +881,5 @@ trait PredicatesAndActions { /// Called when a new syntax tree node is created #[allow(clippy::ptr_arg)] fn build(&mut self, _rule: Rule, _node: NodeRef, _diags: &mut Vec) {} + fn predicate_decl_1(&self) -> bool; } diff --git a/src/frontend/lelwel.llw b/src/frontend/lelwel.llw index 61eba52..4f9380e 100644 --- a/src/frontend/lelwel.llw +++ b/src/frontend/lelwel.llw @@ -15,7 +15,7 @@ skip Comment DocComment Whitespace; file: decl*; decl^: token_list -| rule_decl +| ?1 rule_decl | start_decl | right_decl | skip_decl diff --git a/src/frontend/parser.rs b/src/frontend/parser.rs index 6002b0c..2e05c39 100644 --- a/src/frontend/parser.rs +++ b/src/frontend/parser.rs @@ -188,4 +188,9 @@ pub fn tokenize( include!("./generated.rs"); -impl PredicatesAndActions for Parser<'_> {} +impl PredicatesAndActions for Parser<'_> { + fn predicate_decl_1(&self) -> bool { + let peek = self.peek(1); + peek == Token::Colon || (peek == Token::Hat && self.peek(2) == Token::Colon) + } +} diff --git a/tests/frontend.rs b/tests/frontend.rs index 2c359f4..afd3ea6 100644 --- a/tests/frontend.rs +++ b/tests/frontend.rs @@ -285,6 +285,17 @@ fn syntax_error() { assert_eq!(lines.next(), None); } +#[test] +#[rustfmt::skip] +fn top_level_ident() { + let diags = gen_diags("tests/frontend/top_level_ident.llw"); + let mut lines = diags.lines(); + + assert_eq!(lines.next().unwrap(), "tests/frontend/top_level_ident.llw:3:1: error: invalid syntax"); + assert_eq!(lines.next().unwrap(), "tests/frontend/top_level_ident.llw:5:1: warning[W005]: empty rule"); + assert_eq!(lines.next(), None); +} + #[test] #[rustfmt::skip] fn undefined() {