about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/parser/src/grammar.rs12
-rw-r--r--crates/parser/src/lib.rs24
2 files changed, 36 insertions, 0 deletions
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index 25178ddd775..86dce61da2d 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -44,6 +44,18 @@ use crate::{
     TokenSet, T,
 };
 
+pub(crate) mod entry {
+    use super::*;
+
+    pub(crate) mod prefix {
+        use super::*;
+
+        pub(crate) fn vis(p: &mut Parser) {
+            let _ = opt_visibility(p, false);
+        }
+    }
+}
+
 pub(crate) mod entry_points {
     use super::*;
 
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index 841d2aa4e94..f0b93c4511a 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -41,6 +41,30 @@ pub use crate::{
     syntax_kind::SyntaxKind,
 };
 
+/// Parse a syntactic construct at the *start* of the input.
+///
+/// This is used by macro-by-example parser to implement things like `$i:item`.
+///
+/// Note that this is generally non-optional -- the result is intentionally not
+/// `Option<Output>`. The way MBE work, by the time we *try* to parse `$e:expr`
+/// we already commit to expression. In other words, this API by design can't be
+/// used to implement "rollback and try another alternative" logic.
+pub enum PrefixEntryPoint {
+    Vis,
+}
+
+impl PrefixEntryPoint {
+    pub fn parse(self, input: &Input) -> Output {
+        let entry_point: fn(&'_ mut parser::Parser) = match self {
+            PrefixEntryPoint::Vis => grammar::entry::prefix::vis,
+        };
+        let mut p = parser::Parser::new(input);
+        entry_point(&mut p);
+        let events = p.finish();
+        event::process(events)
+    }
+}
+
 /// rust-analyzer parser allows you to choose one of the possible entry points.
 ///
 /// The primary consumer of this API are declarative macros, `$x:expr` matchers