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