1#![allow(rustdoc::private_intra_doc_links)]
22#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
23
24#[cfg(not(feature = "in-rust-tree"))]
25extern crate ra_ap_rustc_lexer as rustc_lexer;
26#[cfg(feature = "in-rust-tree")]
27extern crate rustc_driver as _;
28#[cfg(feature = "in-rust-tree")]
29extern crate rustc_lexer;
30
31mod event;
32mod frontmatter;
33mod grammar;
34mod input;
35mod lexed_str;
36mod output;
37mod parser;
38mod shortcuts;
39mod syntax_kind;
40mod token_set;
41
42pub use T_ as T;
43
44#[cfg(test)]
45mod tests;
46
47pub(crate) use token_set::TokenSet;
48
49pub use edition::Edition;
50
51pub use crate::{
52 input::Input,
53 lexed_str::LexedStr,
54 output::{Output, Step},
55 shortcuts::StrStep,
56 syntax_kind::SyntaxKind,
57};
58
59#[derive(Debug)]
81pub enum TopEntryPoint {
82 SourceFile,
83 MacroStmts,
84 MacroItems,
85 Pattern,
86 Type,
87 Expr,
88 MetaItem,
91}
92
93impl TopEntryPoint {
94 pub fn parse(&self, input: &Input) -> Output {
95 let _p = tracing::info_span!("TopEntryPoint::parse", ?self).entered();
96 let entry_point: fn(&'_ mut parser::Parser<'_>) = match self {
97 TopEntryPoint::SourceFile => grammar::entry::top::source_file,
98 TopEntryPoint::MacroStmts => grammar::entry::top::macro_stmts,
99 TopEntryPoint::MacroItems => grammar::entry::top::macro_items,
100 TopEntryPoint::Pattern => grammar::entry::top::pattern,
101 TopEntryPoint::Type => grammar::entry::top::type_,
102 TopEntryPoint::Expr => grammar::entry::top::expr,
103 TopEntryPoint::MetaItem => grammar::entry::top::meta_item,
104 };
105 let mut p = parser::Parser::new(input);
106 entry_point(&mut p);
107 let events = p.finish();
108 let res = event::process(events);
109
110 if cfg!(debug_assertions) {
111 let mut depth = 0;
112 let mut first = true;
113 for step in res.iter() {
114 assert!(depth > 0 || first);
115 first = false;
116 match step {
117 Step::Enter { .. } => depth += 1,
118 Step::Exit => depth -= 1,
119 Step::FloatSplit { ends_in_dot: has_pseudo_dot } => {
120 depth -= 1 + !has_pseudo_dot as usize
121 }
122 Step::Token { .. } | Step::Error { .. } => (),
123 }
124 }
125 assert!(!first, "no tree at all");
126 assert_eq!(depth, 0, "unbalanced tree");
127 }
128
129 res
130 }
131}
132
133#[derive(Debug)]
143pub enum PrefixEntryPoint {
144 Vis,
145 Block,
146 Stmt,
147 Pat,
148 PatTop,
149 Ty,
150 Expr,
151 Path,
152 Item,
153 MetaItem,
154}
155
156impl PrefixEntryPoint {
157 pub fn parse(&self, input: &Input) -> Output {
158 let entry_point: fn(&'_ mut parser::Parser<'_>) = match self {
159 PrefixEntryPoint::Vis => grammar::entry::prefix::vis,
160 PrefixEntryPoint::Block => grammar::entry::prefix::block,
161 PrefixEntryPoint::Stmt => grammar::entry::prefix::stmt,
162 PrefixEntryPoint::Pat => grammar::entry::prefix::pat,
163 PrefixEntryPoint::PatTop => grammar::entry::prefix::pat_top,
164 PrefixEntryPoint::Ty => grammar::entry::prefix::ty,
165 PrefixEntryPoint::Expr => grammar::entry::prefix::expr,
166 PrefixEntryPoint::Path => grammar::entry::prefix::path,
167 PrefixEntryPoint::Item => grammar::entry::prefix::item,
168 PrefixEntryPoint::MetaItem => grammar::entry::prefix::meta_item,
169 };
170 let mut p = parser::Parser::new(input);
171 entry_point(&mut p);
172 let events = p.finish();
173 event::process(events)
174 }
175}
176
177pub struct Reparser(fn(&mut parser::Parser<'_>));
179
180impl Reparser {
181 pub fn for_node(
183 node: SyntaxKind,
184 first_child: Option<SyntaxKind>,
185 parent: Option<SyntaxKind>,
186 ) -> Option<Reparser> {
187 grammar::reparser(node, first_child, parent).map(Reparser)
188 }
189
190 pub fn parse(self, tokens: &Input) -> Output {
195 let Reparser(r) = self;
196 let mut p = parser::Parser::new(tokens);
197 r(&mut p);
198 let events = p.finish();
199 event::process(events)
200 }
201}