diff options
Diffstat (limited to 'src/parser')
-rw-r--r-- | src/parser/event.rs | 33 | ||||
-rw-r--r-- | src/parser/grammar/mod.rs | 13 | ||||
-rw-r--r-- | src/parser/input.rs | 10 | ||||
-rw-r--r-- | src/parser/mod.rs | 26 | ||||
-rw-r--r-- | src/parser/parser/imp.rs | 3 | ||||
-rw-r--r-- | src/parser/parser/mod.rs | 3 |
6 files changed, 51 insertions, 37 deletions
diff --git a/src/parser/event.rs b/src/parser/event.rs index 83039c664..a8d503b3d 100644 --- a/src/parser/event.rs +++ b/src/parser/event.rs | |||
@@ -1,8 +1,29 @@ | |||
1 | //! This module provides a way to construct a `File`. | ||
2 | //! It is intended to be completely decoupled from the | ||
3 | //! parser, so as to allow to evolve the tree representation | ||
4 | //! and the parser algorithm independently. | ||
5 | //! | ||
6 | //! The `Sink` trait is the bridge between the parser and the | ||
7 | //! tree builder: the parser produces a stream of events like | ||
8 | //! `start node`, `finish node`, and `FileBuilder` converts | ||
9 | //! this stream to a real tree. | ||
1 | use { | 10 | use { |
2 | Sink, SyntaxKind, Token, | 11 | TextUnit, |
3 | syntax_kinds::TOMBSTONE, | 12 | SyntaxKind::{self, TOMBSTONE}, |
13 | lexer::Token, | ||
4 | }; | 14 | }; |
5 | use super::is_insignificant; | 15 | |
16 | pub(crate) trait Sink { | ||
17 | type Tree; | ||
18 | |||
19 | fn new(text: String) -> Self; | ||
20 | |||
21 | fn leaf(&mut self, kind: SyntaxKind, len: TextUnit); | ||
22 | fn start_internal(&mut self, kind: SyntaxKind); | ||
23 | fn finish_internal(&mut self); | ||
24 | fn error(&mut self, err: String); | ||
25 | fn finish(self) -> Self::Tree; | ||
26 | } | ||
6 | 27 | ||
7 | /// `Parser` produces a flat list of `Event`s. | 28 | /// `Parser` produces a flat list of `Event`s. |
8 | /// They are converted to a tree-structure in | 29 | /// They are converted to a tree-structure in |
@@ -67,7 +88,7 @@ pub(crate) enum Event { | |||
67 | }, | 88 | }, |
68 | } | 89 | } |
69 | 90 | ||
70 | pub(super) fn process(builder: &mut Sink, tokens: &[Token], events: Vec<Event>) { | 91 | pub(super) fn process(builder: &mut impl Sink, tokens: &[Token], events: Vec<Event>) { |
71 | let mut idx = 0; | 92 | let mut idx = 0; |
72 | 93 | ||
73 | let mut holes = Vec::new(); | 94 | let mut holes = Vec::new(); |
@@ -111,7 +132,7 @@ pub(super) fn process(builder: &mut Sink, tokens: &[Token], events: Vec<Event>) | |||
111 | &Event::Finish => { | 132 | &Event::Finish => { |
112 | while idx < tokens.len() { | 133 | while idx < tokens.len() { |
113 | let token = tokens[idx]; | 134 | let token = tokens[idx]; |
114 | if is_insignificant(token.kind) { | 135 | if token.kind.is_trivia() { |
115 | idx += 1; | 136 | idx += 1; |
116 | builder.leaf(token.kind, token.len); | 137 | builder.leaf(token.kind, token.len); |
117 | } else { | 138 | } else { |
@@ -128,7 +149,7 @@ pub(super) fn process(builder: &mut Sink, tokens: &[Token], events: Vec<Event>) | |||
128 | // this should be done in a sensible manner instead | 149 | // this should be done in a sensible manner instead |
129 | loop { | 150 | loop { |
130 | let token = tokens[idx]; | 151 | let token = tokens[idx]; |
131 | if !is_insignificant(token.kind) { | 152 | if !token.kind.is_trivia() { |
132 | break; | 153 | break; |
133 | } | 154 | } |
134 | builder.leaf(token.kind, token.len); | 155 | builder.leaf(token.kind, token.len); |
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs index 23216452f..085e62d56 100644 --- a/src/parser/grammar/mod.rs +++ b/src/parser/grammar/mod.rs | |||
@@ -21,11 +21,6 @@ | |||
21 | //! After adding a new inline-test, run `cargo collect-tests` to extract | 21 | //! After adding a new inline-test, run `cargo collect-tests` to extract |
22 | //! it as a standalone text-fixture into `tests/data/parser/inline`, and | 22 | //! it as a standalone text-fixture into `tests/data/parser/inline`, and |
23 | //! run `cargo test` once to create the "gold" value. | 23 | //! run `cargo test` once to create the "gold" value. |
24 | use parser::parser::Parser; | ||
25 | use parser::token_set::TokenSet; | ||
26 | use SyntaxKind; | ||
27 | use syntax_kinds::*; | ||
28 | |||
29 | mod items; | 24 | mod items; |
30 | mod attributes; | 25 | mod attributes; |
31 | mod expressions; | 26 | mod expressions; |
@@ -34,6 +29,14 @@ mod patterns; | |||
34 | mod paths; | 29 | mod paths; |
35 | mod type_params; | 30 | mod type_params; |
36 | 31 | ||
32 | use { | ||
33 | SyntaxKind::{self, *}, | ||
34 | parser::{ | ||
35 | parser::Parser, | ||
36 | token_set::TokenSet | ||
37 | } | ||
38 | }; | ||
39 | |||
37 | pub(crate) fn file(p: &mut Parser) { | 40 | pub(crate) fn file(p: &mut Parser) { |
38 | let file = p.start(); | 41 | let file = p.start(); |
39 | p.eat(SHEBANG); | 42 | p.eat(SHEBANG); |
diff --git a/src/parser/input.rs b/src/parser/input.rs index 9b400b959..052981fbc 100644 --- a/src/parser/input.rs +++ b/src/parser/input.rs | |||
@@ -1,6 +1,8 @@ | |||
1 | use {SyntaxKind, TextRange, TextUnit, Token}; | 1 | use { |
2 | use syntax_kinds::EOF; | 2 | SyntaxKind, TextRange, TextUnit, |
3 | use super::is_insignificant; | 3 | SyntaxKind::EOF, |
4 | lexer::Token, | ||
5 | }; | ||
4 | 6 | ||
5 | use std::ops::{Add, AddAssign}; | 7 | use std::ops::{Add, AddAssign}; |
6 | 8 | ||
@@ -16,7 +18,7 @@ impl<'t> ParserInput<'t> { | |||
16 | let mut start_offsets = Vec::new(); | 18 | let mut start_offsets = Vec::new(); |
17 | let mut len = 0.into(); | 19 | let mut len = 0.into(); |
18 | for &token in raw_tokens.iter() { | 20 | for &token in raw_tokens.iter() { |
19 | if !is_insignificant(token.kind) { | 21 | if !token.kind.is_trivia() { |
20 | tokens.push(token); | 22 | tokens.push(token); |
21 | start_offsets.push(len); | 23 | start_offsets.push(len); |
22 | } | 24 | } |
diff --git a/src/parser/mod.rs b/src/parser/mod.rs index b7d5e5832..e72ab05af 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs | |||
@@ -5,18 +5,16 @@ mod input; | |||
5 | mod event; | 5 | mod event; |
6 | mod grammar; | 6 | mod grammar; |
7 | 7 | ||
8 | use std::sync::Arc; | ||
9 | use { | 8 | use { |
10 | Token, | 9 | lexer::Token, |
11 | yellow::SyntaxNode, | 10 | parser::event::{process} |
12 | syntax_kinds::* | ||
13 | }; | 11 | }; |
14 | use GreenBuilder; | 12 | |
15 | use parser::event::process; | 13 | pub(crate) use self::event::Sink; |
16 | 14 | ||
17 | 15 | ||
18 | /// Parse a sequence of tokens into the representative node tree | 16 | /// Parse a sequence of tokens into the representative node tree |
19 | pub fn parse_green(text: String, tokens: &[Token]) -> SyntaxNode { | 17 | pub(crate) fn parse<S: Sink>(text: String, tokens: &[Token]) -> S::Tree { |
20 | let events = { | 18 | let events = { |
21 | let input = input::ParserInput::new(&text, tokens); | 19 | let input = input::ParserInput::new(&text, tokens); |
22 | let parser_impl = parser::imp::ParserImpl::new(&input); | 20 | let parser_impl = parser::imp::ParserImpl::new(&input); |
@@ -24,15 +22,7 @@ pub fn parse_green(text: String, tokens: &[Token]) -> SyntaxNode { | |||
24 | grammar::file(&mut parser); | 22 | grammar::file(&mut parser); |
25 | parser.0.into_events() | 23 | parser.0.into_events() |
26 | }; | 24 | }; |
27 | let mut builder = GreenBuilder::new(text); | 25 | let mut sink = S::new(text); |
28 | process(&mut builder, tokens, events); | 26 | process(&mut sink, tokens, events); |
29 | let (green, errors) = builder.finish(); | 27 | sink.finish() |
30 | SyntaxNode::new(Arc::new(green), errors) | ||
31 | } | ||
32 | |||
33 | fn is_insignificant(kind: SyntaxKind) -> bool { | ||
34 | match kind { | ||
35 | WHITESPACE | COMMENT => true, | ||
36 | _ => false, | ||
37 | } | ||
38 | } | 28 | } |
diff --git a/src/parser/parser/imp.rs b/src/parser/parser/imp.rs index f2641c388..38237ac06 100644 --- a/src/parser/parser/imp.rs +++ b/src/parser/parser/imp.rs | |||
@@ -1,8 +1,7 @@ | |||
1 | use parser::input::{InputPosition, ParserInput}; | 1 | use parser::input::{InputPosition, ParserInput}; |
2 | use parser::event::Event; | 2 | use parser::event::Event; |
3 | 3 | ||
4 | use SyntaxKind; | 4 | use SyntaxKind::{self, EOF, TOMBSTONE}; |
5 | use syntax_kinds::{EOF, TOMBSTONE}; | ||
6 | 5 | ||
7 | /// Implementation details of `Parser`, extracted | 6 | /// Implementation details of `Parser`, extracted |
8 | /// to a separate struct in order not to pollute | 7 | /// to a separate struct in order not to pollute |
diff --git a/src/parser/parser/mod.rs b/src/parser/parser/mod.rs index 58f820738..0930ff9e4 100644 --- a/src/parser/parser/mod.rs +++ b/src/parser/parser/mod.rs | |||
@@ -1,5 +1,4 @@ | |||
1 | use SyntaxKind; | 1 | use SyntaxKind::{self, ERROR}; |
2 | use syntax_kinds::ERROR; | ||
3 | 2 | ||
4 | pub(super) mod imp; | 3 | pub(super) mod imp; |
5 | use self::imp::ParserImpl; | 4 | use self::imp::ParserImpl; |