diff options
Diffstat (limited to 'crates/ra_parser/src')
-rw-r--r-- | crates/ra_parser/src/grammar.rs | 145 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/paths.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/types.rs | 2 | ||||
-rw-r--r-- | crates/ra_parser/src/lib.rs | 86 |
5 files changed, 106 insertions, 131 deletions
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index dee3a229d..d0f0dd4ac 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs | |||
@@ -49,98 +49,93 @@ pub(crate) fn root(p: &mut Parser) { | |||
49 | m.complete(p, SOURCE_FILE); | 49 | m.complete(p, SOURCE_FILE); |
50 | } | 50 | } |
51 | 51 | ||
52 | pub(crate) fn macro_items(p: &mut Parser) { | 52 | /// Various pieces of syntax that can be parsed by macros by example |
53 | let m = p.start(); | 53 | pub(crate) mod fragments { |
54 | items::mod_contents(p, false); | 54 | use super::*; |
55 | m.complete(p, MACRO_ITEMS); | ||
56 | } | ||
57 | 55 | ||
58 | pub(crate) fn macro_stmts(p: &mut Parser) { | 56 | pub(crate) use super::{ |
59 | let m = p.start(); | 57 | expressions::block, paths::type_path as path, patterns::pattern, types::type_, |
60 | 58 | }; | |
61 | while !p.at(EOF) { | ||
62 | if p.current() == T![;] { | ||
63 | p.bump(); | ||
64 | continue; | ||
65 | } | ||
66 | 59 | ||
67 | expressions::stmt(p, expressions::StmtWithSemi::Optional); | 60 | pub(crate) fn expr(p: &mut Parser) { |
61 | let _ = expressions::expr(p); | ||
68 | } | 62 | } |
69 | 63 | ||
70 | m.complete(p, MACRO_STMTS); | 64 | pub(crate) fn stmt(p: &mut Parser) { |
71 | } | 65 | expressions::stmt(p, expressions::StmtWithSemi::No) |
72 | 66 | } | |
73 | pub(crate) fn path(p: &mut Parser) { | ||
74 | paths::type_path(p); | ||
75 | } | ||
76 | |||
77 | pub(crate) fn expr(p: &mut Parser) { | ||
78 | expressions::expr(p); | ||
79 | } | ||
80 | 67 | ||
81 | pub(crate) fn type_(p: &mut Parser) { | 68 | pub(crate) fn opt_visibility(p: &mut Parser) { |
82 | types::type_(p) | 69 | let _ = super::opt_visibility(p); |
83 | } | 70 | } |
84 | 71 | ||
85 | pub(crate) fn pattern(p: &mut Parser) { | 72 | // Parse a meta item , which excluded [], e.g : #[ MetaItem ] |
86 | patterns::pattern(p) | 73 | pub(crate) fn meta_item(p: &mut Parser) { |
87 | } | 74 | fn is_delimiter(p: &mut Parser) -> bool { |
75 | match p.current() { | ||
76 | T!['{'] | T!['('] | T!['['] => true, | ||
77 | _ => false, | ||
78 | } | ||
79 | } | ||
88 | 80 | ||
89 | pub(crate) fn stmt(p: &mut Parser, with_semi: bool) { | 81 | if is_delimiter(p) { |
90 | let with_semi = | 82 | items::token_tree(p); |
91 | if with_semi { expressions::StmtWithSemi::Yes } else { expressions::StmtWithSemi::No }; | 83 | return; |
84 | } | ||
92 | 85 | ||
93 | expressions::stmt(p, with_semi) | 86 | let m = p.start(); |
94 | } | 87 | while !p.at(EOF) { |
88 | if is_delimiter(p) { | ||
89 | items::token_tree(p); | ||
90 | break; | ||
91 | } else { | ||
92 | // https://doc.rust-lang.org/reference/attributes.html | ||
93 | // https://doc.rust-lang.org/reference/paths.html#simple-paths | ||
94 | // The start of an meta must be a simple path | ||
95 | match p.current() { | ||
96 | IDENT | T![::] | T![super] | T![self] | T![crate] => p.bump(), | ||
97 | T![=] => { | ||
98 | p.bump(); | ||
99 | match p.current() { | ||
100 | c if c.is_literal() => p.bump(), | ||
101 | T![true] | T![false] => p.bump(), | ||
102 | _ => {} | ||
103 | } | ||
104 | break; | ||
105 | } | ||
106 | _ => break, | ||
107 | } | ||
108 | } | ||
109 | } | ||
95 | 110 | ||
96 | pub(crate) fn block(p: &mut Parser) { | 111 | m.complete(p, TOKEN_TREE); |
97 | expressions::block(p); | 112 | } |
98 | } | ||
99 | 113 | ||
100 | // Parse a meta item , which excluded [], e.g : #[ MetaItem ] | 114 | pub(crate) fn item(p: &mut Parser) { |
101 | pub(crate) fn meta_item(p: &mut Parser) { | 115 | items::item_or_macro(p, true, items::ItemFlavor::Mod) |
102 | fn is_delimiter(p: &mut Parser) -> bool { | ||
103 | match p.current() { | ||
104 | T!['{'] | T!['('] | T!['['] => true, | ||
105 | _ => false, | ||
106 | } | ||
107 | } | 116 | } |
108 | 117 | ||
109 | if is_delimiter(p) { | 118 | pub(crate) fn macro_items(p: &mut Parser) { |
110 | items::token_tree(p); | 119 | let m = p.start(); |
111 | return; | 120 | items::mod_contents(p, false); |
121 | m.complete(p, MACRO_ITEMS); | ||
112 | } | 122 | } |
113 | 123 | ||
114 | let m = p.start(); | 124 | pub(crate) fn macro_stmts(p: &mut Parser) { |
115 | while !p.at(EOF) { | 125 | let m = p.start(); |
116 | if is_delimiter(p) { | 126 | |
117 | items::token_tree(p); | 127 | while !p.at(EOF) { |
118 | break; | 128 | if p.current() == T![;] { |
119 | } else { | 129 | p.bump(); |
120 | // https://doc.rust-lang.org/reference/attributes.html | 130 | continue; |
121 | // https://doc.rust-lang.org/reference/paths.html#simple-paths | ||
122 | // The start of an meta must be a simple path | ||
123 | match p.current() { | ||
124 | IDENT | T![::] | T![super] | T![self] | T![crate] => p.bump(), | ||
125 | T![=] => { | ||
126 | p.bump(); | ||
127 | match p.current() { | ||
128 | c if c.is_literal() => p.bump(), | ||
129 | T![true] | T![false] => p.bump(), | ||
130 | _ => {} | ||
131 | } | ||
132 | break; | ||
133 | } | ||
134 | _ => break, | ||
135 | } | 131 | } |
132 | |||
133 | expressions::stmt(p, expressions::StmtWithSemi::Optional); | ||
136 | } | 134 | } |
137 | } | ||
138 | 135 | ||
139 | m.complete(p, TOKEN_TREE); | 136 | m.complete(p, MACRO_STMTS); |
140 | } | 137 | } |
141 | 138 | ||
142 | pub(crate) fn item(p: &mut Parser) { | ||
143 | items::item_or_macro(p, true, items::ItemFlavor::Mod) | ||
144 | } | 139 | } |
145 | 140 | ||
146 | pub(crate) fn reparser( | 141 | pub(crate) fn reparser( |
@@ -180,7 +175,7 @@ impl BlockLike { | |||
180 | } | 175 | } |
181 | } | 176 | } |
182 | 177 | ||
183 | pub(crate) fn opt_visibility(p: &mut Parser) -> bool { | 178 | fn opt_visibility(p: &mut Parser) -> bool { |
184 | match p.current() { | 179 | match p.current() { |
185 | T![pub] => { | 180 | T![pub] => { |
186 | let m = p.start(); | 181 | let m = p.start(); |
diff --git a/crates/ra_parser/src/grammar/paths.rs b/crates/ra_parser/src/grammar/paths.rs index 07eb53b0c..28c35a67d 100644 --- a/crates/ra_parser/src/grammar/paths.rs +++ b/crates/ra_parser/src/grammar/paths.rs | |||
@@ -18,7 +18,7 @@ pub(super) fn use_path(p: &mut Parser) { | |||
18 | path(p, Mode::Use) | 18 | path(p, Mode::Use) |
19 | } | 19 | } |
20 | 20 | ||
21 | pub(super) fn type_path(p: &mut Parser) { | 21 | pub(crate) fn type_path(p: &mut Parser) { |
22 | path(p, Mode::Type) | 22 | path(p, Mode::Type) |
23 | } | 23 | } |
24 | 24 | ||
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs index eae70ab85..32cde7de6 100644 --- a/crates/ra_parser/src/grammar/patterns.rs +++ b/crates/ra_parser/src/grammar/patterns.rs | |||
@@ -4,7 +4,7 @@ pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST | |||
4 | .union(paths::PATH_FIRST) | 4 | .union(paths::PATH_FIRST) |
5 | .union(token_set![BOX_KW, REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE, MINUS]); | 5 | .union(token_set![BOX_KW, REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE, MINUS]); |
6 | 6 | ||
7 | pub(super) fn pattern(p: &mut Parser) { | 7 | pub(crate) fn pattern(p: &mut Parser) { |
8 | pattern_r(p, PAT_RECOVERY_SET); | 8 | pattern_r(p, PAT_RECOVERY_SET); |
9 | } | 9 | } |
10 | 10 | ||
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs index 29d173305..9e321b2a6 100644 --- a/crates/ra_parser/src/grammar/types.rs +++ b/crates/ra_parser/src/grammar/types.rs | |||
@@ -7,7 +7,7 @@ pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(token_set![ | |||
7 | 7 | ||
8 | const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA]; | 8 | const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA]; |
9 | 9 | ||
10 | pub(super) fn type_(p: &mut Parser) { | 10 | pub(crate) fn type_(p: &mut Parser) { |
11 | type_with_bounds_cond(p, true); | 11 | type_with_bounds_cond(p, true); |
12 | } | 12 | } |
13 | 13 | ||
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs index 3d88be642..45241e566 100644 --- a/crates/ra_parser/src/lib.rs +++ b/crates/ra_parser/src/lib.rs | |||
@@ -83,62 +83,42 @@ pub fn parse(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | |||
83 | parse_from_tokens(token_source, tree_sink, grammar::root); | 83 | parse_from_tokens(token_source, tree_sink, grammar::root); |
84 | } | 84 | } |
85 | 85 | ||
86 | /// Parse given tokens into the given sink as a path | 86 | pub enum FragmentKind { |
87 | pub fn parse_path(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 87 | Path, |
88 | parse_from_tokens(token_source, tree_sink, grammar::path); | 88 | Expr, |
89 | } | 89 | Statement, |
90 | 90 | Type, | |
91 | /// Parse given tokens into the given sink as a expression | 91 | Pattern, |
92 | pub fn parse_expr(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 92 | Item, |
93 | parse_from_tokens(token_source, tree_sink, grammar::expr); | 93 | Block, |
94 | } | 94 | Visibility, |
95 | 95 | MetaItem, | |
96 | /// Parse given tokens into the given sink as a ty | 96 | |
97 | pub fn parse_ty(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 97 | // These kinds are used when parsing the result of expansion |
98 | parse_from_tokens(token_source, tree_sink, grammar::type_); | 98 | // FIXME: use separate fragment kinds for macro inputs and outputs? |
99 | } | 99 | Items, |
100 | 100 | Statements, | |
101 | /// Parse given tokens into the given sink as a pattern | 101 | } |
102 | pub fn parse_pat(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 102 | |
103 | parse_from_tokens(token_source, tree_sink, grammar::pattern); | 103 | pub fn parse_fragment( |
104 | } | ||
105 | |||
106 | /// Parse given tokens into the given sink as a statement | ||
107 | pub fn parse_stmt( | ||
108 | token_source: &mut dyn TokenSource, | 104 | token_source: &mut dyn TokenSource, |
109 | tree_sink: &mut dyn TreeSink, | 105 | tree_sink: &mut dyn TreeSink, |
110 | with_semi: bool, | 106 | fragment_kind: FragmentKind, |
111 | ) { | 107 | ) { |
112 | parse_from_tokens(token_source, tree_sink, |p| grammar::stmt(p, with_semi)); | 108 | let parser: fn(&'_ mut parser::Parser) = match fragment_kind { |
113 | } | 109 | FragmentKind::Path => grammar::fragments::path, |
114 | 110 | FragmentKind::Expr => grammar::fragments::expr, | |
115 | /// Parse given tokens into the given sink as a block | 111 | FragmentKind::Type => grammar::fragments::type_, |
116 | pub fn parse_block(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 112 | FragmentKind::Pattern => grammar::fragments::pattern, |
117 | parse_from_tokens(token_source, tree_sink, grammar::block); | 113 | FragmentKind::Item => grammar::fragments::item, |
118 | } | 114 | FragmentKind::Block => grammar::fragments::block, |
119 | 115 | FragmentKind::Visibility => grammar::fragments::opt_visibility, | |
120 | pub fn parse_meta(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 116 | FragmentKind::MetaItem => grammar::fragments::meta_item, |
121 | parse_from_tokens(token_source, tree_sink, grammar::meta_item); | 117 | FragmentKind::Statement => grammar::fragments::stmt, |
122 | } | 118 | FragmentKind::Items => grammar::fragments::macro_items, |
123 | 119 | FragmentKind::Statements => grammar::fragments::macro_stmts, | |
124 | /// Parse given tokens into the given sink as an item | 120 | }; |
125 | pub fn parse_item(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | 121 | parse_from_tokens(token_source, tree_sink, parser) |
126 | parse_from_tokens(token_source, tree_sink, grammar::item); | ||
127 | } | ||
128 | |||
129 | /// Parse given tokens into the given sink as an visibility qualifier | ||
130 | pub fn parse_vis(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | ||
131 | parse_from_tokens(token_source, tree_sink, |p| { | ||
132 | grammar::opt_visibility(p); | ||
133 | }); | ||
134 | } | ||
135 | |||
136 | pub fn parse_macro_items(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | ||
137 | parse_from_tokens(token_source, tree_sink, grammar::macro_items); | ||
138 | } | ||
139 | |||
140 | pub fn parse_macro_stmts(token_source: &mut dyn TokenSource, tree_sink: &mut dyn TreeSink) { | ||
141 | parse_from_tokens(token_source, tree_sink, grammar::macro_stmts); | ||
142 | } | 122 | } |
143 | 123 | ||
144 | /// A parsing function for a specific braced-block. | 124 | /// A parsing function for a specific braced-block. |