diff options
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r-- | crates/ra_syntax/src/parsing.rs | 50 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/builder.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/parser_impl.rs | 40 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/parser_impl/input.rs | 32 |
4 files changed, 59 insertions, 65 deletions
diff --git a/crates/ra_syntax/src/parsing.rs b/crates/ra_syntax/src/parsing.rs index 761accd7b..6c2c5f78b 100644 --- a/crates/ra_syntax/src/parsing.rs +++ b/crates/ra_syntax/src/parsing.rs | |||
@@ -8,7 +8,7 @@ mod grammar; | |||
8 | mod reparsing; | 8 | mod reparsing; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | SyntaxError, | 11 | SyntaxError, SyntaxKind, SmolStr, |
12 | parsing::builder::GreenBuilder, | 12 | parsing::builder::GreenBuilder, |
13 | syntax_node::GreenNode, | 13 | syntax_node::GreenNode, |
14 | }; | 14 | }; |
@@ -23,3 +23,51 @@ pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) { | |||
23 | parser_impl::parse_with(GreenBuilder::new(), text, &tokens, grammar::root); | 23 | parser_impl::parse_with(GreenBuilder::new(), text, &tokens, grammar::root); |
24 | (green, errors) | 24 | (green, errors) |
25 | } | 25 | } |
26 | |||
27 | /// `TreeSink` abstracts details of a particular syntax tree implementation. | ||
28 | trait TreeSink { | ||
29 | type Tree; | ||
30 | |||
31 | /// Adds new leaf to the current branch. | ||
32 | fn leaf(&mut self, kind: SyntaxKind, text: SmolStr); | ||
33 | |||
34 | /// Start new branch and make it current. | ||
35 | fn start_branch(&mut self, kind: SyntaxKind); | ||
36 | |||
37 | /// Finish current branch and restore previous | ||
38 | /// branch as current. | ||
39 | fn finish_branch(&mut self); | ||
40 | |||
41 | fn error(&mut self, error: SyntaxError); | ||
42 | |||
43 | /// Complete tree building. Make sure that | ||
44 | /// `start_branch` and `finish_branch` calls | ||
45 | /// are paired! | ||
46 | fn finish(self) -> Self::Tree; | ||
47 | } | ||
48 | |||
49 | /// `TokenSource` abstracts the source of the tokens parser operates one. | ||
50 | /// | ||
51 | /// Hopefully this will allow us to treat text and token trees in the same way! | ||
52 | trait TokenSource { | ||
53 | fn token_kind(&self, pos: TokenPos) -> SyntaxKind; | ||
54 | fn is_token_joint_to_next(&self, pos: TokenPos) -> bool; | ||
55 | fn is_keyword(&self, pos: TokenPos, kw: &str) -> bool; | ||
56 | } | ||
57 | |||
58 | #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Default)] | ||
59 | pub(crate) struct TokenPos(pub u32); | ||
60 | |||
61 | impl std::ops::Add<u32> for TokenPos { | ||
62 | type Output = TokenPos; | ||
63 | |||
64 | fn add(self, rhs: u32) -> TokenPos { | ||
65 | TokenPos(self.0 + rhs) | ||
66 | } | ||
67 | } | ||
68 | |||
69 | impl std::ops::AddAssign<u32> for TokenPos { | ||
70 | fn add_assign(&mut self, rhs: u32) { | ||
71 | self.0 += rhs | ||
72 | } | ||
73 | } | ||
diff --git a/crates/ra_syntax/src/parsing/builder.rs b/crates/ra_syntax/src/parsing/builder.rs index 118f43b2c..a05e7f84b 100644 --- a/crates/ra_syntax/src/parsing/builder.rs +++ b/crates/ra_syntax/src/parsing/builder.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use crate::{ | 1 | use crate::{ |
2 | parsing::parser_impl::TreeSink, | 2 | parsing::TreeSink, |
3 | syntax_node::{GreenNode, RaTypes}, | 3 | syntax_node::{GreenNode, RaTypes}, |
4 | SmolStr, SyntaxKind, SyntaxError, | 4 | SmolStr, SyntaxKind, SyntaxError, |
5 | }; | 5 | }; |
diff --git a/crates/ra_syntax/src/parsing/parser_impl.rs b/crates/ra_syntax/src/parsing/parser_impl.rs index 96de32fc2..89439e074 100644 --- a/crates/ra_syntax/src/parsing/parser_impl.rs +++ b/crates/ra_syntax/src/parsing/parser_impl.rs | |||
@@ -4,47 +4,17 @@ pub(crate) mod input; | |||
4 | use std::cell::Cell; | 4 | use std::cell::Cell; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | SmolStr, | 7 | syntax_error::ParseError, |
8 | syntax_error::{ParseError, SyntaxError}, | ||
9 | parsing::{ | 8 | parsing::{ |
9 | TreeSink, TokenSource, TokenPos, | ||
10 | lexer::Token, | 10 | lexer::Token, |
11 | parser_api::Parser, | 11 | parser_api::Parser, |
12 | parser_impl::{ | 12 | parser_impl::event::{Event, EventProcessor}, |
13 | event::{Event, EventProcessor}, | ||
14 | input::InputPosition, | ||
15 | }, | ||
16 | }, | 13 | }, |
17 | }; | 14 | }; |
18 | 15 | ||
19 | use crate::SyntaxKind::{self, EOF, TOMBSTONE}; | 16 | use crate::SyntaxKind::{self, EOF, TOMBSTONE}; |
20 | 17 | ||
21 | pub(super) trait TreeSink { | ||
22 | type Tree; | ||
23 | |||
24 | /// Adds new leaf to the current branch. | ||
25 | fn leaf(&mut self, kind: SyntaxKind, text: SmolStr); | ||
26 | |||
27 | /// Start new branch and make it current. | ||
28 | fn start_branch(&mut self, kind: SyntaxKind); | ||
29 | |||
30 | /// Finish current branch and restore previous | ||
31 | /// branch as current. | ||
32 | fn finish_branch(&mut self); | ||
33 | |||
34 | fn error(&mut self, error: SyntaxError); | ||
35 | |||
36 | /// Complete tree building. Make sure that | ||
37 | /// `start_branch` and `finish_branch` calls | ||
38 | /// are paired! | ||
39 | fn finish(self) -> Self::Tree; | ||
40 | } | ||
41 | |||
42 | pub(super) trait TokenSource { | ||
43 | fn token_kind(&self, pos: InputPosition) -> SyntaxKind; | ||
44 | fn is_token_joint_to_next(&self, pos: InputPosition) -> bool; | ||
45 | fn is_keyword(&self, pos: InputPosition, kw: &str) -> bool; | ||
46 | } | ||
47 | |||
48 | /// Parse a sequence of tokens into the representative node tree | 18 | /// Parse a sequence of tokens into the representative node tree |
49 | pub(super) fn parse_with<S: TreeSink>( | 19 | pub(super) fn parse_with<S: TreeSink>( |
50 | sink: S, | 20 | sink: S, |
@@ -67,7 +37,7 @@ pub(super) fn parse_with<S: TreeSink>( | |||
67 | /// the public API of the `Parser`. | 37 | /// the public API of the `Parser`. |
68 | pub(super) struct ParserImpl<'a> { | 38 | pub(super) struct ParserImpl<'a> { |
69 | token_source: &'a dyn TokenSource, | 39 | token_source: &'a dyn TokenSource, |
70 | pos: InputPosition, | 40 | pos: TokenPos, |
71 | events: Vec<Event>, | 41 | events: Vec<Event>, |
72 | steps: Cell<u32>, | 42 | steps: Cell<u32>, |
73 | } | 43 | } |
@@ -76,7 +46,7 @@ impl<'a> ParserImpl<'a> { | |||
76 | fn new(token_source: &'a dyn TokenSource) -> ParserImpl<'a> { | 46 | fn new(token_source: &'a dyn TokenSource) -> ParserImpl<'a> { |
77 | ParserImpl { | 47 | ParserImpl { |
78 | token_source, | 48 | token_source, |
79 | pos: InputPosition::new(), | 49 | pos: TokenPos::default(), |
80 | events: Vec::new(), | 50 | events: Vec::new(), |
81 | steps: Cell::new(0), | 51 | steps: Cell::new(0), |
82 | } | 52 | } |
diff --git a/crates/ra_syntax/src/parsing/parser_impl/input.rs b/crates/ra_syntax/src/parsing/parser_impl/input.rs index 8ebbd3825..e9735e526 100644 --- a/crates/ra_syntax/src/parsing/parser_impl/input.rs +++ b/crates/ra_syntax/src/parsing/parser_impl/input.rs | |||
@@ -1,22 +1,21 @@ | |||
1 | use crate::{ | 1 | use crate::{ |
2 | SyntaxKind, SyntaxKind::EOF, TextRange, TextUnit, | 2 | SyntaxKind, SyntaxKind::EOF, TextRange, TextUnit, |
3 | parsing::{ | 3 | parsing::{ |
4 | TokenPos, | ||
4 | parser_impl::TokenSource, | 5 | parser_impl::TokenSource, |
5 | lexer::Token, | 6 | lexer::Token, |
6 | }, | 7 | }, |
7 | }; | 8 | }; |
8 | 9 | ||
9 | use std::ops::{Add, AddAssign}; | ||
10 | |||
11 | impl<'t> TokenSource for ParserInput<'t> { | 10 | impl<'t> TokenSource for ParserInput<'t> { |
12 | fn token_kind(&self, pos: InputPosition) -> SyntaxKind { | 11 | fn token_kind(&self, pos: TokenPos) -> SyntaxKind { |
13 | let idx = pos.0 as usize; | 12 | let idx = pos.0 as usize; |
14 | if !(idx < self.tokens.len()) { | 13 | if !(idx < self.tokens.len()) { |
15 | return EOF; | 14 | return EOF; |
16 | } | 15 | } |
17 | self.tokens[idx].kind | 16 | self.tokens[idx].kind |
18 | } | 17 | } |
19 | fn is_token_joint_to_next(&self, pos: InputPosition) -> bool { | 18 | fn is_token_joint_to_next(&self, pos: TokenPos) -> bool { |
20 | let idx_curr = pos.0 as usize; | 19 | let idx_curr = pos.0 as usize; |
21 | let idx_next = pos.0 as usize; | 20 | let idx_next = pos.0 as usize; |
22 | if !(idx_next < self.tokens.len()) { | 21 | if !(idx_next < self.tokens.len()) { |
@@ -24,7 +23,7 @@ impl<'t> TokenSource for ParserInput<'t> { | |||
24 | } | 23 | } |
25 | self.start_offsets[idx_curr] + self.tokens[idx_curr].len == self.start_offsets[idx_next] | 24 | self.start_offsets[idx_curr] + self.tokens[idx_curr].len == self.start_offsets[idx_next] |
26 | } | 25 | } |
27 | fn is_keyword(&self, pos: InputPosition, kw: &str) -> bool { | 26 | fn is_keyword(&self, pos: TokenPos, kw: &str) -> bool { |
28 | let idx = pos.0 as usize; | 27 | let idx = pos.0 as usize; |
29 | if !(idx < self.tokens.len()) { | 28 | if !(idx < self.tokens.len()) { |
30 | return false; | 29 | return false; |
@@ -72,26 +71,3 @@ impl<'t> ParserInput<'t> { | |||
72 | ParserInput { text, start_offsets, tokens } | 71 | ParserInput { text, start_offsets, tokens } |
73 | } | 72 | } |
74 | } | 73 | } |
75 | |||
76 | #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] | ||
77 | pub(crate) struct InputPosition(u32); | ||
78 | |||
79 | impl InputPosition { | ||
80 | pub fn new() -> Self { | ||
81 | InputPosition(0) | ||
82 | } | ||
83 | } | ||
84 | |||
85 | impl Add<u32> for InputPosition { | ||
86 | type Output = InputPosition; | ||
87 | |||
88 | fn add(self, rhs: u32) -> InputPosition { | ||
89 | InputPosition(self.0 + rhs) | ||
90 | } | ||
91 | } | ||
92 | |||
93 | impl AddAssign<u32> for InputPosition { | ||
94 | fn add_assign(&mut self, rhs: u32) { | ||
95 | self.0 += rhs | ||
96 | } | ||
97 | } | ||