From abc658aad04db9bbe1727218df110abc8e126ec7 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 27 Dec 2021 15:17:48 +0300 Subject: [PATCH] internal: add prefix entry points --- crates/parser/src/grammar.rs | 12 ++++++++++++ crates/parser/src/lib.rs | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs index 25178ddd77..86dce61da2 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 841d2aa4e9..f0b93c4511 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`. 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