aboutsummaryrefslogtreecommitdiff
path: root/src/parser/grammar/items/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/grammar/items/mod.rs')
-rw-r--r--src/parser/grammar/items/mod.rs196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs
new file mode 100644
index 000000000..3612802e1
--- /dev/null
+++ b/src/parser/grammar/items/mod.rs
@@ -0,0 +1,196 @@
1use super::*;
2
3mod structs;
4mod use_item;
5mod consts;
6mod traits;
7
8pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
9 attributes::inner_attributes(p);
10 while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) {
11 item(p);
12 }
13}
14
15pub(super) const ITEM_FIRST: TokenSet = token_set![
16 EXTERN_KW, MOD_KW, USE_KW, STRUCT_KW, ENUM_KW, FN_KW, PUB_KW, POUND
17];
18
19fn item(p: &mut Parser) {
20 let item = p.start();
21 attributes::outer_attributes(p);
22 visibility(p);
23 let la = p.nth(1);
24 let item_kind = match p.current() {
25 USE_KW => {
26 use_item::use_item(p);
27 USE_ITEM
28 }
29 // test extern_crate
30 // extern crate foo;
31 EXTERN_KW if la == CRATE_KW => {
32 extern_crate_item(p);
33 EXTERN_CRATE_ITEM
34 }
35 EXTERN_KW => {
36 abi(p);
37 match p.current() {
38 // test extern_fn
39 // extern fn foo() {}
40 FN_KW => {
41 fn_item(p);
42 FN_ITEM
43 }
44 // test extern_block
45 // extern {}
46 L_CURLY => {
47 extern_block(p);
48 EXTERN_BLOCK
49 }
50 // test extern_struct
51 // extern struct Foo;
52 _ => {
53 item.abandon(p);
54 p.error().message("expected `fn` or `{`").emit();
55 return;
56 }
57 }
58 }
59 STATIC_KW => {
60 consts::static_item(p);
61 STATIC_ITEM
62 }
63 CONST_KW => match p.nth(1) {
64 // test const_fn
65 // const fn foo() {}
66 FN_KW => {
67 p.bump();
68 fn_item(p);
69 FN_ITEM
70 }
71 // test const_unsafe_fn
72 // const unsafe fn foo() {}
73 UNSAFE_KW if p.nth(2) == FN_KW => {
74 p.bump();
75 p.bump();
76 fn_item(p);
77 FN_ITEM
78 }
79 _ => {
80 consts::const_item(p);
81 CONST_ITEM
82 }
83 },
84 // TODO: auto trait
85 // test unsafe_trait
86 // unsafe trait T {}
87 UNSAFE_KW if la == TRAIT_KW => {
88 p.bump();
89 traits::trait_item(p);
90 TRAIT_ITEM
91 }
92 // TODO: default impl
93 // test unsafe_impl
94 // unsafe impl Foo {}
95 UNSAFE_KW if la == IMPL_KW => {
96 p.bump();
97 traits::impl_item(p);
98 IMPL_ITEM
99 }
100 MOD_KW => {
101 mod_item(p);
102 MOD_ITEM
103 }
104 STRUCT_KW => {
105 structs::struct_item(p);
106 STRUCT_ITEM
107 }
108 ENUM_KW => {
109 structs::enum_item(p);
110 ENUM_ITEM
111 }
112 FN_KW => {
113 fn_item(p);
114 FN_ITEM
115 }
116 L_CURLY => {
117 item.abandon(p);
118 error_block(p, "expected item");
119 return;
120 }
121 err_token => {
122 item.abandon(p);
123 let message = if err_token == SEMI {
124 //TODO: if the item is incomplete, this message is misleading
125 "expected item, found `;`\n\
126 consider removing this semicolon"
127 } else {
128 "expected item"
129 };
130 p.err_and_bump(message);
131 return;
132 }
133 };
134 item.complete(p, item_kind);
135}
136
137fn extern_crate_item(p: &mut Parser) {
138 assert!(p.at(EXTERN_KW));
139 p.bump();
140 assert!(p.at(CRATE_KW));
141 p.bump();
142
143 p.expect(IDENT) && alias(p) && p.expect(SEMI);
144}
145
146fn extern_block(p: &mut Parser) {
147 assert!(p.at(L_CURLY));
148 p.bump();
149 p.expect(R_CURLY);
150}
151
152fn mod_item(p: &mut Parser) {
153 assert!(p.at(MOD_KW));
154 p.bump();
155
156 if p.expect(IDENT) && !p.eat(SEMI) {
157 if p.expect(L_CURLY) {
158 mod_contents(p, true);
159 p.expect(R_CURLY);
160 }
161 }
162}
163
164fn abi(p: &mut Parser) {
165 assert!(p.at(EXTERN_KW));
166 let abi = p.start();
167 p.bump();
168 match p.current() {
169 STRING | RAW_STRING => p.bump(),
170 _ => (),
171 }
172 abi.complete(p, ABI);
173}
174
175fn fn_item(p: &mut Parser) {
176 assert!(p.at(FN_KW));
177 p.bump();
178
179 p.expect(IDENT);
180 if p.at(L_PAREN) {
181 fn_value_parameters(p);
182 } else {
183 p.error().message("expected function arguments").emit();
184 }
185
186 if p.at(L_CURLY) {
187 p.expect(L_CURLY);
188 p.expect(R_CURLY);
189 }
190
191 fn fn_value_parameters(p: &mut Parser) {
192 assert!(p.at(L_PAREN));
193 p.bump();
194 p.expect(R_PAREN);
195 }
196}