diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-05-27 08:28:13 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-05-27 08:28:13 +0100 |
commit | ce694ae11854a806031db98c51c068253f927519 (patch) | |
tree | 2996ecd85ff9aa57b6f208e83d42dd03a7370d1e /crates/ra_parser/src/lib.rs | |
parent | 4f4e50db908ba44f113faeb356ae2b3d0788d308 (diff) | |
parent | 90764fc54b2be1e0fc5d6ac9c9e960d7bb059b14 (diff) |
Merge #1328
1328: Change TokenSource to iteration based r=matklad a=edwin0cheng
This PR change the `TokenSource` trait from random access to be an iteration based trait:
```rust
/// `TokenSource` abstracts the source of the tokens parser operates one.
///
/// Hopefully this will allow us to treat text and token trees in the same way!
pub trait TokenSource {
fn current(&self) -> Token;
/// Lookahead n token
fn lookahead_nth(&self, n: usize) -> Token;
/// bump cursor to next token
fn bump(&mut self);
/// Is the current token a specified keyword?
fn is_keyword(&self, kw: &str) -> bool;
}
/// `TokenCursor` abstracts the cursor of `TokenSource` operates one.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct Token {
/// What is the current token?
pub kind: SyntaxKind,
/// Is the current token joined to the next one (`> >` vs `>>`).
pub is_jointed_to_next: bool,
}
```
Note that the refactoring based on this new trait will be separated to incoming PRs
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_parser/src/lib.rs')
-rw-r--r-- | crates/ra_parser/src/lib.rs | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs index 697d1b794..3d88be642 100644 --- a/crates/ra_parser/src/lib.rs +++ b/crates/ra_parser/src/lib.rs | |||
@@ -31,12 +31,26 @@ pub struct ParseError(pub String); | |||
31 | /// | 31 | /// |
32 | /// Hopefully this will allow us to treat text and token trees in the same way! | 32 | /// Hopefully this will allow us to treat text and token trees in the same way! |
33 | pub trait TokenSource { | 33 | pub trait TokenSource { |
34 | fn current(&self) -> Token; | ||
35 | |||
36 | /// Lookahead n token | ||
37 | fn lookahead_nth(&self, n: usize) -> Token; | ||
38 | |||
39 | /// bump cursor to next token | ||
40 | fn bump(&mut self); | ||
41 | |||
42 | /// Is the current token a specified keyword? | ||
43 | fn is_keyword(&self, kw: &str) -> bool; | ||
44 | } | ||
45 | |||
46 | /// `TokenCursor` abstracts the cursor of `TokenSource` operates one. | ||
47 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] | ||
48 | pub struct Token { | ||
34 | /// What is the current token? | 49 | /// What is the current token? |
35 | fn token_kind(&self, pos: usize) -> SyntaxKind; | 50 | pub kind: SyntaxKind, |
51 | |||
36 | /// Is the current token joined to the next one (`> >` vs `>>`). | 52 | /// Is the current token joined to the next one (`> >` vs `>>`). |
37 | fn is_token_joint_to_next(&self, pos: usize) -> bool; | 53 | pub is_jointed_to_next: bool, |
38 | /// Is the current token a specified keyword? | ||
39 | fn is_keyword(&self, pos: usize, kw: &str) -> bool; | ||
40 | } | 54 | } |
41 | 55 | ||
42 | /// `TreeSink` abstracts details of a particular syntax tree implementation. | 56 | /// `TreeSink` abstracts details of a particular syntax tree implementation. |
@@ -54,7 +68,7 @@ pub trait TreeSink { | |||
54 | fn error(&mut self, error: ParseError); | 68 | fn error(&mut self, error: ParseError); |
55 | } | 69 | } |
56 | 70 | ||
57 | fn parse_from_tokens<F>(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink, f: F) | 71 | fn parse_from_tokens<F>(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink, f: F) |
58 | where | 72 | where |
59 | F: FnOnce(&mut parser::Parser), | 73 | F: FnOnce(&mut parser::Parser), |
60 | { | 74 | { |
@@ -65,61 +79,65 @@ where | |||
65 | } | 79 | } |
66 | 80 | ||
67 | /// Parse given tokens into the given sink as a rust file. | 81 | /// Parse given tokens into the given sink as a rust file. |
68 | pub fn parse(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 82 | pub fn parse(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
69 | parse_from_tokens(token_source, tree_sink, grammar::root); | 83 | parse_from_tokens(token_source, tree_sink, grammar::root); |
70 | } | 84 | } |
71 | 85 | ||
72 | /// Parse given tokens into the given sink as a path | 86 | /// Parse given tokens into the given sink as a path |
73 | pub fn parse_path(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 87 | pub fn parse_path(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
74 | parse_from_tokens(token_source, tree_sink, grammar::path); | 88 | parse_from_tokens(token_source, tree_sink, grammar::path); |
75 | } | 89 | } |
76 | 90 | ||
77 | /// Parse given tokens into the given sink as a expression | 91 | /// Parse given tokens into the given sink as a expression |
78 | pub fn parse_expr(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 92 | pub fn parse_expr(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
79 | parse_from_tokens(token_source, tree_sink, grammar::expr); | 93 | parse_from_tokens(token_source, tree_sink, grammar::expr); |
80 | } | 94 | } |
81 | 95 | ||
82 | /// Parse given tokens into the given sink as a ty | 96 | /// Parse given tokens into the given sink as a ty |
83 | pub fn parse_ty(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 97 | pub fn parse_ty(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
84 | parse_from_tokens(token_source, tree_sink, grammar::type_); | 98 | parse_from_tokens(token_source, tree_sink, grammar::type_); |
85 | } | 99 | } |
86 | 100 | ||
87 | /// Parse given tokens into the given sink as a pattern | 101 | /// Parse given tokens into the given sink as a pattern |
88 | pub fn parse_pat(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 102 | pub fn parse_pat(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
89 | parse_from_tokens(token_source, tree_sink, grammar::pattern); | 103 | parse_from_tokens(token_source, tree_sink, grammar::pattern); |
90 | } | 104 | } |
91 | 105 | ||
92 | /// Parse given tokens into the given sink as a statement | 106 | /// Parse given tokens into the given sink as a statement |
93 | pub fn parse_stmt(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink, with_semi: bool) { | 107 | pub fn parse_stmt( |
108 | token_source: &mut dyn TokenSource, | ||
109 | tree_sink: &mut dyn TreeSink, | ||
110 | with_semi: bool, | ||
111 | ) { | ||
94 | parse_from_tokens(token_source, tree_sink, |p| grammar::stmt(p, with_semi)); | 112 | parse_from_tokens(token_source, tree_sink, |p| grammar::stmt(p, with_semi)); |
95 | } | 113 | } |
96 | 114 | ||
97 | /// Parse given tokens into the given sink as a block | 115 | /// Parse given tokens into the given sink as a block |
98 | pub fn parse_block(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 116 | pub fn parse_block(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
99 | parse_from_tokens(token_source, tree_sink, grammar::block); | 117 | parse_from_tokens(token_source, tree_sink, grammar::block); |
100 | } | 118 | } |
101 | 119 | ||
102 | pub fn parse_meta(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 120 | pub fn parse_meta(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
103 | parse_from_tokens(token_source, tree_sink, grammar::meta_item); | 121 | parse_from_tokens(token_source, tree_sink, grammar::meta_item); |
104 | } | 122 | } |
105 | 123 | ||
106 | /// Parse given tokens into the given sink as an item | 124 | /// Parse given tokens into the given sink as an item |
107 | pub fn parse_item(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 125 | pub fn parse_item(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
108 | parse_from_tokens(token_source, tree_sink, grammar::item); | 126 | parse_from_tokens(token_source, tree_sink, grammar::item); |
109 | } | 127 | } |
110 | 128 | ||
111 | /// Parse given tokens into the given sink as an visibility qualifier | 129 | /// Parse given tokens into the given sink as an visibility qualifier |
112 | pub fn parse_vis(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 130 | pub fn parse_vis(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
113 | parse_from_tokens(token_source, tree_sink, |p| { | 131 | parse_from_tokens(token_source, tree_sink, |p| { |
114 | grammar::opt_visibility(p); | 132 | grammar::opt_visibility(p); |
115 | }); | 133 | }); |
116 | } | 134 | } |
117 | 135 | ||
118 | pub fn parse_macro_items(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 136 | pub fn parse_macro_items(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
119 | parse_from_tokens(token_source, tree_sink, grammar::macro_items); | 137 | parse_from_tokens(token_source, tree_sink, grammar::macro_items); |
120 | } | 138 | } |
121 | 139 | ||
122 | pub fn parse_macro_stmts(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 140 | pub fn parse_macro_stmts(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
123 | parse_from_tokens(token_source, tree_sink, grammar::macro_stmts); | 141 | parse_from_tokens(token_source, tree_sink, grammar::macro_stmts); |
124 | } | 142 | } |
125 | 143 | ||
@@ -140,7 +158,7 @@ impl Reparser { | |||
140 | /// | 158 | /// |
141 | /// Tokens must start with `{`, end with `}` and form a valid brace | 159 | /// Tokens must start with `{`, end with `}` and form a valid brace |
142 | /// sequence. | 160 | /// sequence. |
143 | pub fn parse(self, token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 161 | pub fn parse(self, token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { |
144 | let Reparser(r) = self; | 162 | let Reparser(r) = self; |
145 | let mut p = parser::Parser::new(token_source); | 163 | let mut p = parser::Parser::new(token_source); |
146 | r(&mut p); | 164 | r(&mut p); |