Mercurial > projects > dil
comparison src/dil/parser/ImportParser.d @ 806:bcb74c9b895c
Moved out files in the trunk folder to the root.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sun, 09 Mar 2008 00:12:19 +0100 |
parents | trunk/src/dil/parser/ImportParser.d@c24be8d4f6ab |
children |
comparison
equal
deleted
inserted
replaced
805:a3fab8b74a7d | 806:bcb74c9b895c |
---|---|
1 /++ | |
2 Author: Aziz Köksal | |
3 License: GPL3 | |
4 +/ | |
5 module dil.parser.ImportParser; | |
6 | |
7 import dil.parser.Parser; | |
8 import dil.ast.Node; | |
9 import dil.ast.Declarations; | |
10 import dil.ast.Statements; | |
11 import dil.SourceText; | |
12 import dil.Enums; | |
13 import common; | |
14 | |
15 private alias TOK T; | |
16 | |
17 /// A light-weight parser which looks only for import statements | |
18 /// in the source text. | |
19 class ImportParser : Parser | |
20 { | |
21 this(SourceText srcText) | |
22 { | |
23 super(srcText); | |
24 } | |
25 | |
26 override CompoundDeclaration start() | |
27 { | |
28 auto decls = new CompoundDeclaration; | |
29 super.init(); | |
30 if (token.kind == T.Module) | |
31 decls ~= parseModuleDeclaration(); | |
32 while (token.kind != T.EOF) | |
33 parseDeclarationDefinition(Protection.None); | |
34 return decls; | |
35 } | |
36 | |
37 void parseDeclarationDefinitionsBlock(Protection prot) | |
38 { | |
39 skip(T.LBrace); | |
40 while (token.kind != T.RBrace && token.kind != T.EOF) | |
41 parseDeclarationDefinition(prot); | |
42 skip(T.RBrace); | |
43 } | |
44 | |
45 void parseDeclarationsBlock(Protection prot) | |
46 { | |
47 switch (token.kind) | |
48 { | |
49 case T.LBrace: | |
50 parseDeclarationDefinitionsBlock(prot); | |
51 break; | |
52 case T.Colon: | |
53 nT(); | |
54 while (token.kind != T.RBrace && token.kind != T.EOF) | |
55 parseDeclarationDefinition(prot); | |
56 break; | |
57 default: | |
58 parseDeclarationDefinition(prot); | |
59 } | |
60 } | |
61 | |
62 bool skipToClosing(T opening, T closing) | |
63 { | |
64 alias token next; | |
65 uint level = 1; | |
66 while (1) | |
67 { | |
68 lexer.peek(next); | |
69 if (next.kind == opening) | |
70 ++level; | |
71 else if (next.kind == closing && --level == 0) | |
72 return true; | |
73 else if (next.kind == T.EOF) | |
74 break; | |
75 } | |
76 return false; | |
77 } | |
78 | |
79 void skipToTokenAfterClosingParen() | |
80 { | |
81 skipToClosing(T.LParen, T.RParen); | |
82 nT(); | |
83 } | |
84 | |
85 void skipToTokenAfterClosingBrace() | |
86 { | |
87 skipToClosing(T.LBrace, T.RBrace); | |
88 nT(); | |
89 } | |
90 | |
91 void skip(TOK tok) | |
92 { | |
93 token.kind == tok && nT(); | |
94 } | |
95 | |
96 void parseProtectionAttribute() | |
97 { | |
98 Protection prot; | |
99 switch (token.kind) | |
100 { | |
101 case T.Private: | |
102 prot = Protection.Private; break; | |
103 case T.Package: | |
104 prot = Protection.Package; break; | |
105 case T.Protected: | |
106 prot = Protection.Protected; break; | |
107 case T.Public: | |
108 prot = Protection.Public; break; | |
109 case T.Export: | |
110 prot = Protection.Export; break; | |
111 default: | |
112 assert(0); | |
113 } | |
114 nT(); | |
115 parseDeclarationsBlock(prot); | |
116 } | |
117 | |
118 void parseDeclarationDefinition(Protection prot) | |
119 { | |
120 switch (token.kind) | |
121 { | |
122 case T.Align: | |
123 nT(); | |
124 if (token.kind == T.LParen) | |
125 nT(), nT(), nT(); // ( Integer ) | |
126 parseDeclarationsBlock(prot); | |
127 break; | |
128 case T.Pragma: | |
129 nT(); | |
130 skipToTokenAfterClosingParen(); | |
131 parseDeclarationsBlock(prot); | |
132 break; | |
133 case T.Export, | |
134 T.Private, | |
135 T.Package, | |
136 T.Protected, | |
137 T.Public: | |
138 parseProtectionAttribute(); | |
139 break; | |
140 // Storage classes | |
141 case T.Extern: | |
142 nT(); | |
143 token.kind == T.LParen && skipToTokenAfterClosingParen(); | |
144 parseDeclarationsBlock(prot); | |
145 break; | |
146 case T.Const: | |
147 version(D2) | |
148 { | |
149 if (peekNext() == T.LParen) | |
150 goto case_Declaration; | |
151 } | |
152 case T.Override, | |
153 T.Deprecated, | |
154 T.Abstract, | |
155 T.Synchronized, | |
156 // T.Static, | |
157 T.Final, | |
158 T.Auto, | |
159 T.Scope: | |
160 case_StaticAttribute: | |
161 case_InvariantAttribute: | |
162 nT(); | |
163 parseDeclarationsBlock(prot); | |
164 break; | |
165 // End of storage classes. | |
166 case T.Alias, T.Typedef: | |
167 nT(); | |
168 goto case_Declaration; | |
169 case T.Static: | |
170 switch (peekNext()) | |
171 { | |
172 case T.Import: | |
173 goto case_Import; | |
174 case T.This: | |
175 nT(), nT(); // static this | |
176 skipToTokenAfterClosingParen(); | |
177 parseFunctionBody(); | |
178 break; | |
179 case T.Tilde: | |
180 nT(), nT(), nT(), nT(), nT(); // static ~ this ( ) | |
181 parseFunctionBody(); | |
182 break; | |
183 case T.If: | |
184 nT(), nT(); | |
185 skipToTokenAfterClosingParen(); | |
186 parseDeclarationsBlock(prot); | |
187 if (token.kind == T.Else) | |
188 nT(), parseDeclarationsBlock(prot); | |
189 break; | |
190 case T.Assert: | |
191 nT(), nT(); // static assert | |
192 skipToTokenAfterClosingParen(); | |
193 skip(T.Semicolon); | |
194 break; | |
195 default: | |
196 goto case_StaticAttribute; | |
197 } | |
198 break; | |
199 case T.Import: | |
200 case_Import: | |
201 auto decl = parseImportDeclaration(); | |
202 decl.setProtection(prot); // Set the protection attribute. | |
203 imports ~= decl.to!(ImportDeclaration); | |
204 break; | |
205 case T.Enum: | |
206 nT(); | |
207 token.kind == T.Identifier && nT(); | |
208 if (token.kind == T.Colon) | |
209 { | |
210 nT(); | |
211 while (token.kind != T.LBrace && token.kind != T.EOF) | |
212 nT(); | |
213 } | |
214 if (token.kind == T.Semicolon) | |
215 nT(); | |
216 else | |
217 skipToTokenAfterClosingBrace(); | |
218 break; | |
219 case T.Class: | |
220 case T.Interface: | |
221 nT(), skip(T.Identifier); // class Identifier | |
222 token.kind == T.LParen && skipToTokenAfterClosingParen(); // Skip template params. | |
223 if (token.kind == T.Colon) | |
224 { // BaseClasses | |
225 nT(); | |
226 while (token.kind != T.LBrace && token.kind != T.EOF) | |
227 if (token.kind == T.LParen) // Skip ( tokens... ) | |
228 skipToTokenAfterClosingParen(); | |
229 else | |
230 nT(); | |
231 } | |
232 if (token.kind == T.Semicolon) | |
233 nT(); | |
234 else | |
235 parseDeclarationDefinitionsBlock(Protection.None); | |
236 break; | |
237 case T.Struct, T.Union: | |
238 nT(); skip(T.Identifier); | |
239 token.kind == T.LParen && skipToTokenAfterClosingParen(); | |
240 if (token.kind == T.Semicolon) | |
241 nT(); | |
242 else | |
243 parseDeclarationDefinitionsBlock(Protection.None); | |
244 break; | |
245 case T.Tilde: | |
246 nT(); // ~ | |
247 case T.This: | |
248 nT(); nT(); nT(); // this ( ) | |
249 parseFunctionBody(); | |
250 break; | |
251 case T.Invariant: | |
252 version(D2) | |
253 { | |
254 auto next = token; | |
255 if (peekAfter(next) == T.LParen) | |
256 { | |
257 if (peekAfter(next) != T.RParen) | |
258 goto case_Declaration; | |
259 } | |
260 else | |
261 goto case_InvariantAttribute; | |
262 } | |
263 nT(); | |
264 token.kind == T.LParen && skipToTokenAfterClosingParen(); | |
265 parseFunctionBody(); | |
266 break; | |
267 case T.Unittest: | |
268 nT(); | |
269 parseFunctionBody(); | |
270 break; | |
271 case T.Debug: | |
272 nT(); | |
273 if (token.kind == T.Assign) | |
274 { | |
275 nT(), nT(), nT(); // = Condition ; | |
276 break; | |
277 } | |
278 if (token.kind == T.LParen) | |
279 nT(), nT(), nT(); // ( Condition ) | |
280 parseDeclarationsBlock(prot); | |
281 if (token.kind == T.Else) | |
282 nT(), parseDeclarationsBlock(prot); | |
283 break; | |
284 case T.Version: | |
285 nT(); | |
286 if (token.kind == T.Assign) | |
287 { | |
288 nT(), nT(), nT(); // = Condition ; | |
289 break; | |
290 } | |
291 nT(), nT(), nT(); // ( Condition ) | |
292 parseDeclarationsBlock(prot); | |
293 if (token.kind == T.Else) | |
294 nT(), parseDeclarationsBlock(prot); | |
295 break; | |
296 case T.Template: | |
297 nT(); | |
298 skip(T.Identifier); | |
299 skipToTokenAfterClosingParen(); | |
300 parseDeclarationDefinitionsBlock(Protection.None); | |
301 break; | |
302 case T.New: | |
303 nT(); | |
304 skipToTokenAfterClosingParen(); | |
305 parseFunctionBody(); | |
306 break; | |
307 case T.Delete: | |
308 nT(); | |
309 skipToTokenAfterClosingParen(); | |
310 parseFunctionBody(); | |
311 break; | |
312 case T.Mixin: | |
313 while (token.kind != T.Semicolon && token.kind != T.EOF) | |
314 if (token.kind == T.LParen) | |
315 skipToTokenAfterClosingParen(); | |
316 else | |
317 nT(); | |
318 skip(T.Semicolon); | |
319 break; | |
320 case T.Semicolon: | |
321 nT(); | |
322 break; | |
323 // Declaration | |
324 case T.Identifier, T.Dot, T.Typeof: | |
325 case_Declaration: | |
326 while (token.kind != T.Semicolon && token.kind != T.EOF) | |
327 if (token.kind == T.LParen) | |
328 skipToTokenAfterClosingParen(); | |
329 else if (token.kind == T.LBrace) | |
330 skipToTokenAfterClosingBrace(); | |
331 else | |
332 nT(); | |
333 skip(T.Semicolon); | |
334 break; | |
335 default: | |
336 if (token.isIntegralType) | |
337 goto case_Declaration; | |
338 nT(); | |
339 } | |
340 } | |
341 | |
342 FuncBodyStatement parseFunctionBody() | |
343 { | |
344 while (1) | |
345 { | |
346 switch (token.kind) | |
347 { | |
348 case T.LBrace: | |
349 skipToTokenAfterClosingBrace(); | |
350 break; | |
351 case T.Semicolon: | |
352 nT(); | |
353 break; | |
354 case T.In: | |
355 nT(); | |
356 skipToTokenAfterClosingBrace(); | |
357 continue; | |
358 case T.Out: | |
359 nT(); | |
360 if (token.kind == T.LParen) | |
361 nT(), nT(), nT(); // ( Identifier ) | |
362 skipToTokenAfterClosingBrace(); | |
363 continue; | |
364 case T.Body: | |
365 nT(); | |
366 goto case T.LBrace; | |
367 default: | |
368 } | |
369 break; // Exit loop. | |
370 } | |
371 return null; | |
372 } | |
373 } |