diff options
Diffstat (limited to 'crates/ra_syntax/src/parsing.rs')
-rw-r--r-- | crates/ra_syntax/src/parsing.rs | 72 |
1 files changed, 11 insertions, 61 deletions
diff --git a/crates/ra_syntax/src/parsing.rs b/crates/ra_syntax/src/parsing.rs index 138d1394a..cf573801c 100644 --- a/crates/ra_syntax/src/parsing.rs +++ b/crates/ra_syntax/src/parsing.rs | |||
@@ -1,78 +1,28 @@ | |||
1 | #[macro_use] | 1 | //! Lexing, bridging to ra_parser (which does the actual parsing) and |
2 | mod token_set; | 2 | //! incremental reparsing. |
3 | mod builder; | 3 | |
4 | mod lexer; | 4 | mod lexer; |
5 | mod event; | ||
6 | mod input; | 5 | mod input; |
7 | mod parser; | 6 | mod builder; |
8 | mod grammar; | ||
9 | mod reparsing; | 7 | mod reparsing; |
10 | 8 | ||
11 | use crate::{ | 9 | use crate::{ |
12 | SyntaxKind, SmolStr, SyntaxError, | 10 | SyntaxError, |
11 | syntax_node::GreenNode, | ||
13 | parsing::{ | 12 | parsing::{ |
14 | builder::GreenBuilder, | 13 | builder::TreeBuilder, |
15 | input::ParserInput, | 14 | input::ParserInput, |
16 | event::EventProcessor, | ||
17 | parser::Parser, | ||
18 | }, | 15 | }, |
19 | syntax_node::GreenNode, | ||
20 | }; | 16 | }; |
21 | 17 | ||
22 | pub use self::lexer::{tokenize, Token}; | 18 | pub use self::lexer::{tokenize, Token}; |
23 | 19 | ||
24 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
25 | pub struct ParseError(pub String); | ||
26 | |||
27 | pub(crate) use self::reparsing::incremental_reparse; | 20 | pub(crate) use self::reparsing::incremental_reparse; |
28 | 21 | ||
29 | pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) { | 22 | pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) { |
30 | let tokens = tokenize(&text); | 23 | let tokens = tokenize(&text); |
31 | parse_with(GreenBuilder::default(), text, &tokens, grammar::root) | 24 | let token_source = ParserInput::new(text, &tokens); |
32 | } | 25 | let mut tree_sink = TreeBuilder::new(text, &tokens); |
33 | 26 | ra_parser::parse(&token_source, &mut tree_sink); | |
34 | fn parse_with<S: TreeSink>( | 27 | tree_sink.finish() |
35 | tree_sink: S, | ||
36 | text: &str, | ||
37 | tokens: &[Token], | ||
38 | f: fn(&mut Parser), | ||
39 | ) -> S::Tree { | ||
40 | let mut events = { | ||
41 | let input = ParserInput::new(text, &tokens); | ||
42 | let mut p = Parser::new(&input); | ||
43 | f(&mut p); | ||
44 | p.finish() | ||
45 | }; | ||
46 | EventProcessor::new(tree_sink, text, tokens, &mut events).process().finish() | ||
47 | } | ||
48 | |||
49 | /// `TreeSink` abstracts details of a particular syntax tree implementation. | ||
50 | trait TreeSink { | ||
51 | type Tree; | ||
52 | |||
53 | /// Adds new leaf to the current branch. | ||
54 | fn leaf(&mut self, kind: SyntaxKind, text: SmolStr); | ||
55 | |||
56 | /// Start new branch and make it current. | ||
57 | fn start_branch(&mut self, kind: SyntaxKind); | ||
58 | |||
59 | /// Finish current branch and restore previous | ||
60 | /// branch as current. | ||
61 | fn finish_branch(&mut self); | ||
62 | |||
63 | fn error(&mut self, error: ParseError); | ||
64 | |||
65 | /// Complete tree building. Make sure that | ||
66 | /// `start_branch` and `finish_branch` calls | ||
67 | /// are paired! | ||
68 | fn finish(self) -> Self::Tree; | ||
69 | } | ||
70 | |||
71 | /// `TokenSource` abstracts the source of the tokens parser operates one. | ||
72 | /// | ||
73 | /// Hopefully this will allow us to treat text and token trees in the same way! | ||
74 | trait TokenSource { | ||
75 | fn token_kind(&self, pos: usize) -> SyntaxKind; | ||
76 | fn is_token_joint_to_next(&self, pos: usize) -> bool; | ||
77 | fn is_keyword(&self, pos: usize, kw: &str) -> bool; | ||
78 | } | 28 | } |