diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-24 10:15:43 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-24 10:15:43 +0000 |
commit | f6f160391db945a0dcc2f73b38926d6919f7c566 (patch) | |
tree | 060450b70c09357615f261d8acd032a647615dd7 /crates/ra_syntax/src/parsing | |
parent | c5e74cebdcbade069c0e1e81e298ab7d729e4cd5 (diff) | |
parent | 81bca78349afb9e15994f46401da0cfabfba04a1 (diff) |
Merge #885
885: Parse token trees directy r=matklad a=matklad
This takes advantage of the recent macro refactoring to directly parse token stream into a syntax tree.
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_syntax/src/parsing')
-rw-r--r-- | crates/ra_syntax/src/parsing/reparsing.rs | 8 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/text_token_source.rs (renamed from crates/ra_syntax/src/parsing/input.rs) | 10 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/text_tree_sink.rs (renamed from crates/ra_syntax/src/parsing/builder.rs) | 40 |
3 files changed, 27 insertions, 31 deletions
diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index 19d8adcfb..ba77a3b6c 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs | |||
@@ -14,8 +14,8 @@ use crate::{ | |||
14 | algo, | 14 | algo, |
15 | syntax_node::{GreenNode, SyntaxNode}, | 15 | syntax_node::{GreenNode, SyntaxNode}, |
16 | parsing::{ | 16 | parsing::{ |
17 | input::ParserInput, | 17 | text_token_source::TextTokenSource, |
18 | builder::TreeBuilder, | 18 | text_tree_sink::TextTreeSink, |
19 | lexer::{tokenize, Token}, | 19 | lexer::{tokenize, Token}, |
20 | } | 20 | } |
21 | }; | 21 | }; |
@@ -68,8 +68,8 @@ fn reparse_block<'node>( | |||
68 | if !is_balanced(&tokens) { | 68 | if !is_balanced(&tokens) { |
69 | return None; | 69 | return None; |
70 | } | 70 | } |
71 | let token_source = ParserInput::new(&text, &tokens); | 71 | let token_source = TextTokenSource::new(&text, &tokens); |
72 | let mut tree_sink = TreeBuilder::new(&text, &tokens); | 72 | let mut tree_sink = TextTreeSink::new(&text, &tokens); |
73 | reparser.parse(&token_source, &mut tree_sink); | 73 | reparser.parse(&token_source, &mut tree_sink); |
74 | let (green, new_errors) = tree_sink.finish(); | 74 | let (green, new_errors) = tree_sink.finish(); |
75 | Some((node, green, new_errors)) | 75 | Some((node, green, new_errors)) |
diff --git a/crates/ra_syntax/src/parsing/input.rs b/crates/ra_syntax/src/parsing/text_token_source.rs index 31c6a3b9b..a6277f66f 100644 --- a/crates/ra_syntax/src/parsing/input.rs +++ b/crates/ra_syntax/src/parsing/text_token_source.rs | |||
@@ -5,7 +5,7 @@ use crate::{ | |||
5 | parsing::lexer::Token, | 5 | parsing::lexer::Token, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | pub(crate) struct ParserInput<'t> { | 8 | pub(crate) struct TextTokenSource<'t> { |
9 | text: &'t str, | 9 | text: &'t str, |
10 | /// start position of each token(expect whitespace and comment) | 10 | /// start position of each token(expect whitespace and comment) |
11 | /// ```non-rust | 11 | /// ```non-rust |
@@ -25,7 +25,7 @@ pub(crate) struct ParserInput<'t> { | |||
25 | tokens: Vec<Token>, | 25 | tokens: Vec<Token>, |
26 | } | 26 | } |
27 | 27 | ||
28 | impl<'t> TokenSource for ParserInput<'t> { | 28 | impl<'t> TokenSource for TextTokenSource<'t> { |
29 | fn token_kind(&self, pos: usize) -> SyntaxKind { | 29 | fn token_kind(&self, pos: usize) -> SyntaxKind { |
30 | if !(pos < self.tokens.len()) { | 30 | if !(pos < self.tokens.len()) { |
31 | return EOF; | 31 | return EOF; |
@@ -48,9 +48,9 @@ impl<'t> TokenSource for ParserInput<'t> { | |||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | impl<'t> ParserInput<'t> { | 51 | impl<'t> TextTokenSource<'t> { |
52 | /// Generate input from tokens(expect comment and whitespace). | 52 | /// Generate input from tokens(expect comment and whitespace). |
53 | pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> ParserInput<'t> { | 53 | pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> TextTokenSource<'t> { |
54 | let mut tokens = Vec::new(); | 54 | let mut tokens = Vec::new(); |
55 | let mut start_offsets = Vec::new(); | 55 | let mut start_offsets = Vec::new(); |
56 | let mut len = 0.into(); | 56 | let mut len = 0.into(); |
@@ -62,6 +62,6 @@ impl<'t> ParserInput<'t> { | |||
62 | len += token.len; | 62 | len += token.len; |
63 | } | 63 | } |
64 | 64 | ||
65 | ParserInput { text, start_offsets, tokens } | 65 | TextTokenSource { text, start_offsets, tokens } |
66 | } | 66 | } |
67 | } | 67 | } |
diff --git a/crates/ra_syntax/src/parsing/builder.rs b/crates/ra_syntax/src/parsing/text_tree_sink.rs index cfe3139b8..961a91d41 100644 --- a/crates/ra_syntax/src/parsing/builder.rs +++ b/crates/ra_syntax/src/parsing/text_tree_sink.rs | |||
@@ -1,26 +1,24 @@ | |||
1 | use std::mem; | 1 | use std::mem; |
2 | 2 | ||
3 | use ra_parser::{TreeSink, ParseError}; | 3 | use ra_parser::{TreeSink, ParseError}; |
4 | use rowan::GreenNodeBuilder; | ||
5 | 4 | ||
6 | use crate::{ | 5 | use crate::{ |
7 | SmolStr, SyntaxError, SyntaxErrorKind, TextUnit, TextRange, | 6 | SmolStr, SyntaxError, TextUnit, TextRange, SyntaxTreeBuilder, |
8 | SyntaxKind::{self, *}, | 7 | SyntaxKind::{self, *}, |
9 | parsing::Token, | 8 | parsing::Token, |
10 | syntax_node::{GreenNode, RaTypes}, | 9 | syntax_node::GreenNode, |
11 | }; | 10 | }; |
12 | 11 | ||
13 | /// Bridges the parser with our specific syntax tree representation. | 12 | /// Bridges the parser with our specific syntax tree representation. |
14 | /// | 13 | /// |
15 | /// `TreeBuilder` also handles attachment of trivia (whitespace) to nodes. | 14 | /// `TextTreeSink` also handles attachment of trivia (whitespace) to nodes. |
16 | pub(crate) struct TreeBuilder<'a> { | 15 | pub(crate) struct TextTreeSink<'a> { |
17 | text: &'a str, | 16 | text: &'a str, |
18 | tokens: &'a [Token], | 17 | tokens: &'a [Token], |
19 | text_pos: TextUnit, | 18 | text_pos: TextUnit, |
20 | token_pos: usize, | 19 | token_pos: usize, |
21 | state: State, | 20 | state: State, |
22 | errors: Vec<SyntaxError>, | 21 | inner: SyntaxTreeBuilder, |
23 | inner: GreenNodeBuilder<RaTypes>, | ||
24 | } | 22 | } |
25 | 23 | ||
26 | enum State { | 24 | enum State { |
@@ -29,11 +27,11 @@ enum State { | |||
29 | PendingFinish, | 27 | PendingFinish, |
30 | } | 28 | } |
31 | 29 | ||
32 | impl<'a> TreeSink for TreeBuilder<'a> { | 30 | impl<'a> TreeSink for TextTreeSink<'a> { |
33 | fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8) { | 31 | fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8) { |
34 | match mem::replace(&mut self.state, State::Normal) { | 32 | match mem::replace(&mut self.state, State::Normal) { |
35 | State::PendingStart => unreachable!(), | 33 | State::PendingStart => unreachable!(), |
36 | State::PendingFinish => self.inner.finish_internal(), | 34 | State::PendingFinish => self.inner.finish_branch(), |
37 | State::Normal => (), | 35 | State::Normal => (), |
38 | } | 36 | } |
39 | self.eat_trivias(); | 37 | self.eat_trivias(); |
@@ -48,12 +46,12 @@ impl<'a> TreeSink for TreeBuilder<'a> { | |||
48 | fn start_branch(&mut self, kind: SyntaxKind) { | 46 | fn start_branch(&mut self, kind: SyntaxKind) { |
49 | match mem::replace(&mut self.state, State::Normal) { | 47 | match mem::replace(&mut self.state, State::Normal) { |
50 | State::PendingStart => { | 48 | State::PendingStart => { |
51 | self.inner.start_internal(kind); | 49 | self.inner.start_branch(kind); |
52 | // No need to attach trivias to previous node: there is no | 50 | // No need to attach trivias to previous node: there is no |
53 | // previous node. | 51 | // previous node. |
54 | return; | 52 | return; |
55 | } | 53 | } |
56 | State::PendingFinish => self.inner.finish_internal(), | 54 | State::PendingFinish => self.inner.finish_branch(), |
57 | State::Normal => (), | 55 | State::Normal => (), |
58 | } | 56 | } |
59 | 57 | ||
@@ -73,34 +71,32 @@ impl<'a> TreeSink for TreeBuilder<'a> { | |||
73 | n_attached_trivias(kind, leading_trivias) | 71 | n_attached_trivias(kind, leading_trivias) |
74 | }; | 72 | }; |
75 | self.eat_n_trivias(n_trivias - n_attached_trivias); | 73 | self.eat_n_trivias(n_trivias - n_attached_trivias); |
76 | self.inner.start_internal(kind); | 74 | self.inner.start_branch(kind); |
77 | self.eat_n_trivias(n_attached_trivias); | 75 | self.eat_n_trivias(n_attached_trivias); |
78 | } | 76 | } |
79 | 77 | ||
80 | fn finish_branch(&mut self) { | 78 | fn finish_branch(&mut self) { |
81 | match mem::replace(&mut self.state, State::PendingFinish) { | 79 | match mem::replace(&mut self.state, State::PendingFinish) { |
82 | State::PendingStart => unreachable!(), | 80 | State::PendingStart => unreachable!(), |
83 | State::PendingFinish => self.inner.finish_internal(), | 81 | State::PendingFinish => self.inner.finish_branch(), |
84 | State::Normal => (), | 82 | State::Normal => (), |
85 | } | 83 | } |
86 | } | 84 | } |
87 | 85 | ||
88 | fn error(&mut self, error: ParseError) { | 86 | fn error(&mut self, error: ParseError) { |
89 | let error = SyntaxError::new(SyntaxErrorKind::ParseError(error), self.text_pos); | 87 | self.inner.error(error, self.text_pos) |
90 | self.errors.push(error) | ||
91 | } | 88 | } |
92 | } | 89 | } |
93 | 90 | ||
94 | impl<'a> TreeBuilder<'a> { | 91 | impl<'a> TextTreeSink<'a> { |
95 | pub(super) fn new(text: &'a str, tokens: &'a [Token]) -> TreeBuilder<'a> { | 92 | pub(super) fn new(text: &'a str, tokens: &'a [Token]) -> TextTreeSink<'a> { |
96 | TreeBuilder { | 93 | TextTreeSink { |
97 | text, | 94 | text, |
98 | tokens, | 95 | tokens, |
99 | text_pos: 0.into(), | 96 | text_pos: 0.into(), |
100 | token_pos: 0, | 97 | token_pos: 0, |
101 | state: State::PendingStart, | 98 | state: State::PendingStart, |
102 | errors: Vec::new(), | 99 | inner: SyntaxTreeBuilder::default(), |
103 | inner: GreenNodeBuilder::new(), | ||
104 | } | 100 | } |
105 | } | 101 | } |
106 | 102 | ||
@@ -108,12 +104,12 @@ impl<'a> TreeBuilder<'a> { | |||
108 | match mem::replace(&mut self.state, State::Normal) { | 104 | match mem::replace(&mut self.state, State::Normal) { |
109 | State::PendingFinish => { | 105 | State::PendingFinish => { |
110 | self.eat_trivias(); | 106 | self.eat_trivias(); |
111 | self.inner.finish_internal() | 107 | self.inner.finish_branch() |
112 | } | 108 | } |
113 | State::PendingStart | State::Normal => unreachable!(), | 109 | State::PendingStart | State::Normal => unreachable!(), |
114 | } | 110 | } |
115 | 111 | ||
116 | (self.inner.finish(), self.errors) | 112 | self.inner.finish_raw() |
117 | } | 113 | } |
118 | 114 | ||
119 | fn eat_trivias(&mut self) { | 115 | fn eat_trivias(&mut self) { |