aboutsummaryrefslogtreecommitdiff
path: root/src/parser/event_parser/grammar/items/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/event_parser/grammar/items/mod.rs')
-rw-r--r--src/parser/event_parser/grammar/items/mod.rs178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/parser/event_parser/grammar/items/mod.rs b/src/parser/event_parser/grammar/items/mod.rs
new file mode 100644
index 000000000..867776415
--- /dev/null
+++ b/src/parser/event_parser/grammar/items/mod.rs
@@ -0,0 +1,178 @@
1use super::*;
2
3mod structs;
4
5pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
6 attributes::inner_attributes(p);
7 while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) {
8 item(p);
9 }
10}
11
12pub(super) const ITEM_FIRST: TokenSet =
13 token_set![EXTERN_KW, MOD_KW, USE_KW, STRUCT_KW, FN_KW, PUB_KW, POUND,];
14
15fn item(p: &mut Parser) {
16 let item = p.start();
17 attributes::outer_attributes(p);
18 visibility(p);
19 let la = p.nth(1);
20 let item_kind = match p.current() {
21 EXTERN_KW if la == CRATE_KW => {
22 extern_crate_item(p);
23 EXTERN_CRATE_ITEM
24 }
25 MOD_KW => {
26 mod_item(p);
27 MOD_ITEM
28 }
29 USE_KW => {
30 use_item(p);
31 USE_ITEM
32 }
33 STRUCT_KW => {
34 structs::struct_item(p);
35 STRUCT_ITEM
36 }
37 FN_KW => {
38 fn_item(p);
39 FN_ITEM
40 }
41 L_CURLY => {
42 item.abandon(p);
43 error_block(p, "expected item");
44 return;
45 }
46 err_token => {
47 item.abandon(p);
48 let message = if err_token == SEMI {
49 //TODO: if the item is incomplete, this message is misleading
50 "expected item, found `;`\n\
51 consider removing this semicolon"
52 } else {
53 "expected item"
54 };
55 p.err_and_bump(message);
56 return;
57 }
58 };
59 item.complete(p, item_kind);
60}
61
62fn generic_parameters(_: &mut Parser) {}
63
64fn where_clause(_: &mut Parser) {}
65
66fn extern_crate_item(p: &mut Parser) {
67 assert!(p.at(EXTERN_KW));
68 p.bump();
69 assert!(p.at(CRATE_KW));
70 p.bump();
71
72 p.expect(IDENT) && alias(p) && p.expect(SEMI);
73}
74
75fn mod_item(p: &mut Parser) {
76 assert!(p.at(MOD_KW));
77 p.bump();
78
79 if p.expect(IDENT) && !p.eat(SEMI) {
80 if p.expect(L_CURLY) {
81 mod_contents(p, true);
82 p.expect(R_CURLY);
83 }
84 }
85}
86
87pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool {
88 kind == STAR || kind == L_CURLY
89}
90
91fn use_item(p: &mut Parser) {
92 assert!(p.at(USE_KW));
93 p.bump();
94
95 use_tree(p);
96 p.expect(SEMI);
97
98 fn use_tree(p: &mut Parser) {
99 let la = p.nth(1);
100 let m = p.start();
101 match (p.current(), la) {
102 (STAR, _) => p.bump(),
103 (COLONCOLON, STAR) => {
104 p.bump();
105 p.bump();
106 }
107 (L_CURLY, _) | (COLONCOLON, L_CURLY) => {
108 if p.at(COLONCOLON) {
109 p.bump();
110 }
111 nested_trees(p);
112 }
113 _ if paths::is_path_start(p) => {
114 paths::use_path(p);
115 match p.current() {
116 AS_KW => {
117 alias(p);
118 }
119 COLONCOLON => {
120 p.bump();
121 match p.current() {
122 STAR => {
123 p.bump();
124 }
125 L_CURLY => nested_trees(p),
126 _ => {
127 // is this unreachable?
128 p.error().message("expected `{` or `*`").emit();
129 }
130 }
131 }
132 _ => (),
133 }
134 }
135 _ => {
136 m.abandon(p);
137 p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`");
138 return;
139 }
140 }
141 m.complete(p, USE_TREE);
142 }
143
144 fn nested_trees(p: &mut Parser) {
145 assert!(p.at(L_CURLY));
146 p.bump();
147 while !p.at(EOF) && !p.at(R_CURLY) {
148 use_tree(p);
149 if !p.at(R_CURLY) {
150 p.expect(COMMA);
151 }
152 }
153 p.expect(R_CURLY);
154 }
155}
156
157fn fn_item(p: &mut Parser) {
158 assert!(p.at(FN_KW));
159 p.bump();
160
161 p.expect(IDENT);
162 if p.at(L_PAREN) {
163 fn_value_parameters(p);
164 } else {
165 p.error().message("expected function arguments").emit();
166 }
167
168 if p.at(L_CURLY) {
169 p.expect(L_CURLY);
170 p.expect(R_CURLY);
171 }
172
173 fn fn_value_parameters(p: &mut Parser) {
174 assert!(p.at(L_PAREN));
175 p.bump();
176 p.expect(R_PAREN);
177 }
178}