diff options
Diffstat (limited to 'crates/syntax/src/parsing.rs')
-rw-r--r-- | crates/syntax/src/parsing.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/crates/syntax/src/parsing.rs b/crates/syntax/src/parsing.rs new file mode 100644 index 000000000..68a39eb21 --- /dev/null +++ b/crates/syntax/src/parsing.rs | |||
@@ -0,0 +1,59 @@ | |||
1 | //! Lexing, bridging to parser (which does the actual parsing) and | ||
2 | //! incremental reparsing. | ||
3 | |||
4 | mod lexer; | ||
5 | mod text_token_source; | ||
6 | mod text_tree_sink; | ||
7 | mod reparsing; | ||
8 | |||
9 | use crate::{syntax_node::GreenNode, AstNode, SyntaxError, SyntaxNode}; | ||
10 | use text_token_source::TextTokenSource; | ||
11 | use text_tree_sink::TextTreeSink; | ||
12 | |||
13 | pub use lexer::*; | ||
14 | |||
15 | pub(crate) use self::reparsing::incremental_reparse; | ||
16 | use parser::SyntaxKind; | ||
17 | |||
18 | pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) { | ||
19 | let (tokens, lexer_errors) = tokenize(&text); | ||
20 | |||
21 | let mut token_source = TextTokenSource::new(text, &tokens); | ||
22 | let mut tree_sink = TextTreeSink::new(text, &tokens); | ||
23 | |||
24 | parser::parse(&mut token_source, &mut tree_sink); | ||
25 | |||
26 | let (tree, mut parser_errors) = tree_sink.finish(); | ||
27 | parser_errors.extend(lexer_errors); | ||
28 | |||
29 | (tree, parser_errors) | ||
30 | } | ||
31 | |||
32 | /// Returns `text` parsed as a `T` provided there are no parse errors. | ||
33 | pub(crate) fn parse_text_fragment<T: AstNode>( | ||
34 | text: &str, | ||
35 | fragment_kind: parser::FragmentKind, | ||
36 | ) -> Result<T, ()> { | ||
37 | let (tokens, lexer_errors) = tokenize(&text); | ||
38 | if !lexer_errors.is_empty() { | ||
39 | return Err(()); | ||
40 | } | ||
41 | |||
42 | let mut token_source = TextTokenSource::new(text, &tokens); | ||
43 | let mut tree_sink = TextTreeSink::new(text, &tokens); | ||
44 | |||
45 | // TextTreeSink assumes that there's at least some root node to which it can attach errors and | ||
46 | // tokens. We arbitrarily give it a SourceFile. | ||
47 | use parser::TreeSink; | ||
48 | tree_sink.start_node(SyntaxKind::SOURCE_FILE); | ||
49 | parser::parse_fragment(&mut token_source, &mut tree_sink, fragment_kind); | ||
50 | tree_sink.finish_node(); | ||
51 | |||
52 | let (tree, parser_errors) = tree_sink.finish(); | ||
53 | use parser::TokenSource; | ||
54 | if !parser_errors.is_empty() || token_source.current().kind != SyntaxKind::EOF { | ||
55 | return Err(()); | ||
56 | } | ||
57 | |||
58 | SyntaxNode::new_root(tree).first_child().and_then(T::cast).ok_or(()) | ||
59 | } | ||