Mercurial > projects > dil
comparison trunk/src/Parser.d @ 115:cea36caeec42
- Added method requireIdentifier(). Removed if-else-statements which checked for T.Identifier and replaced with requireIdentifier().
- Simplified parseModule().
author | aziz |
---|---|
date | Mon, 09 Jul 2007 13:17:00 +0000 |
parents | 83bb5190c0fc |
children | f0c1883cdd4c |
comparison
equal
deleted
inserted
replaced
114:83bb5190c0fc | 115:cea36caeec42 |
---|---|
88 { | 88 { |
89 Declaration[] decls; | 89 Declaration[] decls; |
90 | 90 |
91 if (token.type == T.Module) | 91 if (token.type == T.Module) |
92 { | 92 { |
93 nT(); | 93 ModuleName moduleName; |
94 string[] idents; | |
95 do | 94 do |
96 { | 95 { |
97 nT(); | 96 nT(); |
98 if (token.type == T.Identifier) | 97 moduleName ~= requireIdentifier(); |
99 { | |
100 idents ~= token.identifier; | |
101 nT(); | |
102 } | |
103 else | |
104 { | |
105 errorIfNot(T.Identifier); | |
106 skipToOnePast(T.Semicolon); | |
107 goto Lreturn; | |
108 } | |
109 } while (token.type == T.Dot) | 98 } while (token.type == T.Dot) |
110 require(T.Semicolon); | 99 require(T.Semicolon); |
111 decls ~= new ModuleDeclaration(idents); | 100 decls ~= new ModuleDeclaration(moduleName); |
112 } | 101 } |
113 decls ~= parseDeclarationDefinitions(); | 102 decls ~= parseDeclarationDefinitions(); |
114 Lreturn: | |
115 return decls; | 103 return decls; |
116 } | 104 } |
117 | 105 |
118 Declaration[] parseDeclarationDefinitions() | 106 Declaration[] parseDeclarationDefinitions() |
119 { | 107 { |
199 ModuleName[] moduleNames; | 187 ModuleName[] moduleNames; |
200 string[] moduleAliases; | 188 string[] moduleAliases; |
201 string[] bindNames; | 189 string[] bindNames; |
202 string[] bindAliases; | 190 string[] bindAliases; |
203 | 191 |
192 nT(); // Skip import keyword. | |
204 do | 193 do |
205 { | 194 { |
206 ModuleName moduleName; | 195 ModuleName moduleName; |
207 string moduleAlias; | 196 string moduleAlias; |
208 | 197 |
209 if (token.type == T.Identifier) | 198 moduleAlias = requireIdentifier(); |
210 { | 199 |
211 moduleAlias = token.identifier; | 200 // AliasName = ModuleName |
201 if (token.type == T.Assign) | |
202 { | |
212 nT(); | 203 nT(); |
213 } | 204 moduleName ~= requireIdentifier(); |
214 else | 205 } |
215 errorIfNot(T.Identifier); // TODO: better error msg | 206 else // import Identifier [^=] |
216 | |
217 // import Identifier [^=] | |
218 if (token.type != T.Assign) | |
219 { | 207 { |
220 moduleName ~= moduleAlias; | 208 moduleName ~= moduleAlias; |
221 moduleAlias = null; | 209 moduleAlias = null; |
222 } | 210 } |
223 else | 211 |
224 { | |
225 nT(); | |
226 // AliasName = ModuleName | |
227 if (token.type == T.Identifier) | |
228 { | |
229 moduleName ~= token.identifier; | |
230 nT(); | |
231 } | |
232 else | |
233 errorIfNot(T.Identifier); | |
234 } | |
235 | 212 |
236 // parse Identifier(.Identifier)* | 213 // parse Identifier(.Identifier)* |
237 while (token.type == T.Dot) | 214 while (token.type == T.Dot) |
238 { | 215 { |
239 nT(); | 216 nT(); |
240 if (token.type == T.Identifier) | 217 moduleName ~= requireIdentifier(); |
241 { | |
242 moduleName ~= token.identifier; | |
243 nT(); | |
244 } | |
245 else | |
246 errorIfNot(T.Identifier); | |
247 } | 218 } |
248 | 219 |
249 // Push identifiers. | 220 // Push identifiers. |
250 moduleNames ~= moduleName; | 221 moduleNames ~= moduleName; |
251 moduleAliases ~= moduleAlias; | 222 moduleAliases ~= moduleAlias; |
256 { | 227 { |
257 string bindName, bindAlias; | 228 string bindName, bindAlias; |
258 do | 229 do |
259 { | 230 { |
260 nT(); | 231 nT(); |
261 if (token.type == T.Identifier) | 232 bindAlias = requireIdentifier(); |
262 { | |
263 bindAlias = token.identifier; | |
264 nT(); | |
265 } | |
266 else | |
267 errorIfNot(T.Identifier); | |
268 | 233 |
269 if (token.type == T.Assign) | 234 if (token.type == T.Assign) |
270 { | 235 { |
271 nT(); | 236 nT(); |
272 if (token.type == T.Identifier) | 237 bindName = requireIdentifier(); |
273 { | |
274 bindName = token.identifier; | |
275 nT(); | |
276 } | |
277 else | |
278 errorIfNot(T.Identifier); | |
279 } | 238 } |
280 else | 239 else |
281 { | 240 { |
282 bindName = bindAlias; | 241 bindName = bindAlias; |
283 bindAlias = null; | 242 bindAlias = null; |
303 string enumName; | 262 string enumName; |
304 Type baseType; | 263 Type baseType; |
305 string[] members; | 264 string[] members; |
306 Expression[] values; | 265 Expression[] values; |
307 | 266 |
308 nT(); | 267 nT(); // Skip enum keyword. |
309 if (token.type == T.Identifier) | 268 enumName = requireIdentifier(); |
310 { | |
311 enumName = token.identifier; | |
312 nT(); | |
313 } | |
314 | 269 |
315 if (token.type == T.Colon) | 270 if (token.type == T.Colon) |
316 { | 271 { |
317 nT(); | 272 nT(); |
318 baseType = parseBasicType(); | 273 baseType = parseBasicType(); |
319 } | 274 } |
320 | 275 |
321 // if (token.type == T.Semicolon && ident.length == 0) | 276 if (token.type == T.Semicolon) |
322 // error | 277 { |
323 if (token.type == T.LBrace) | 278 //if (ident.length == 0) |
279 // TODO: issue error msg | |
280 nT(); | |
281 } | |
282 else if (token.type == T.LBrace) | |
324 { | 283 { |
325 nT(); | 284 nT(); |
326 do | 285 do |
327 { | 286 { |
328 if (token.type == T.Identifier) | 287 members ~= requireIdentifier(); |
329 { | |
330 members ~= token.identifier; | |
331 nT(); | |
332 } | |
333 else | |
334 errorIfNot(T.Identifier); | |
335 | 288 |
336 if (token.type == T.Assign) | 289 if (token.type == T.Assign) |
337 { | 290 { |
291 nT(); | |
338 values ~= parseAssignExpression(); | 292 values ~= parseAssignExpression(); |
339 nT(); | |
340 } | 293 } |
341 else | 294 else |
342 values ~= null; | 295 values ~= null; |
343 | 296 |
344 if (token.type == T.Comma) | 297 if (token.type == T.Comma) |
345 nT(); | 298 nT(); |
346 else if (token.type != T.RBrace) | 299 else if (token.type != T.RBrace) |
300 { | |
347 errorIfNot(T.RBrace); | 301 errorIfNot(T.RBrace); |
302 break; | |
303 } | |
348 } while (token.type != T.RBrace) | 304 } while (token.type != T.RBrace) |
349 nT(); | 305 nT(); |
350 } | 306 } |
351 | 307 |
352 return new EnumDeclaration(enumName, baseType, members, values); | 308 return new EnumDeclaration(enumName, baseType, members, values); |
358 | 314 |
359 string className; | 315 string className; |
360 BaseClass[] bases; | 316 BaseClass[] bases; |
361 Declaration[] decls; | 317 Declaration[] decls; |
362 | 318 |
363 nT(); | 319 nT(); // Skip class keyword. |
364 if (token.type == T.Identifier) | 320 className = requireIdentifier(); |
365 { | |
366 className = token.identifier; | |
367 nT(); | |
368 } | |
369 else | |
370 errorIfNot(T.Identifier); | |
371 | 321 |
372 if (token.type == T.LParen) | 322 if (token.type == T.LParen) |
373 { | 323 { |
374 // TODO: parse template parameters | 324 // TODO: parse template parameters |
375 } | 325 } |
384 nT(); | 334 nT(); |
385 } | 335 } |
386 else if (token.type == T.LBrace) | 336 else if (token.type == T.LBrace) |
387 { | 337 { |
388 nT(); | 338 nT(); |
339 // TODO: think about setting a member status variable to a flag InClassBody... this way we can check for DeclDefs that are illegal in class bodies in the parsing phase. | |
389 decls = parseDeclarationDefinitions(); | 340 decls = parseDeclarationDefinitions(); |
390 require(T.RBrace); | 341 require(T.RBrace); |
391 } | 342 } |
392 else | 343 else |
393 errorIfNot(T.LBrace); // TODO: better error msg | 344 errorIfNot(T.LBrace); // TODO: better error msg |
428 LisIdentifier: | 379 LisIdentifier: |
429 ident = token.identifier; | 380 ident = token.identifier; |
430 nT(); | 381 nT(); |
431 // TODO: handle template instantiations: class Foo : Bar!(int) | 382 // TODO: handle template instantiations: class Foo : Bar!(int) |
432 } | 383 } |
384 else | |
385 errorIfNot(T.Identifier); | |
433 bases ~= new BaseClass(prot, ident); | 386 bases ~= new BaseClass(prot, ident); |
434 if (token.type != T.Comma) | 387 if (token.type != T.Comma) |
435 break; | 388 break; |
436 } | 389 } |
437 return bases; | 390 return bases; |
443 | 396 |
444 string name; | 397 string name; |
445 BaseClass[] bases; | 398 BaseClass[] bases; |
446 Declaration[] decls; | 399 Declaration[] decls; |
447 | 400 |
448 nT(); | 401 nT(); // Skip interface keyword. |
449 if (token.type == T.Identifier) | 402 name = requireIdentifier(); |
450 { | |
451 name = token.identifier; | |
452 nT(); | |
453 } | |
454 else | |
455 errorIfNot(T.Identifier); | |
456 | 403 |
457 if (token.type == T.LParen) | 404 if (token.type == T.LParen) |
458 { | 405 { |
459 // TODO: parse template parameters | 406 // TODO: parse template parameters |
460 } | 407 } |
463 bases = parseBaseClasses(); | 410 bases = parseBaseClasses(); |
464 | 411 |
465 if (token.type == T.Semicolon) | 412 if (token.type == T.Semicolon) |
466 { | 413 { |
467 //if (bases.length != 0) | 414 //if (bases.length != 0) |
468 // error: bases classes are not allowed in forward declarations. | 415 // TODO: error: base classes are not allowed in forward declarations. |
469 nT(); | 416 nT(); |
470 } | 417 } |
471 else if (token.type == T.LBrace) | 418 else if (token.type == T.LBrace) |
472 { | 419 { |
473 nT(); | 420 nT(); |
489 TOK tok = token.type; | 436 TOK tok = token.type; |
490 | 437 |
491 string name; | 438 string name; |
492 Declaration[] decls; | 439 Declaration[] decls; |
493 | 440 |
494 nT(); | 441 nT(); // Skip struct or union keyword. |
442 // name is optional. | |
495 if (token.type == T.Identifier) | 443 if (token.type == T.Identifier) |
496 { | 444 { |
497 name = token.identifier; | 445 name = token.identifier; |
498 nT(); | 446 nT(); |
499 } | 447 if (token.type == T.LParen) |
500 | 448 { |
501 if (token.type == T.LParen) | 449 // TODO: parse template parameters |
502 { | 450 } |
503 // TODO: parse template parameters | |
504 } | 451 } |
505 | 452 |
506 if (token.type == T.Semicolon) | 453 if (token.type == T.Semicolon) |
507 nT(); | 454 { |
455 //if (name.length == 0) | |
456 // TODO: error: forward declarations must have a name. | |
457 nT(); | |
458 } | |
508 else if (token.type == T.LBrace) | 459 else if (token.type == T.LBrace) |
509 { | 460 { |
510 nT(); | 461 nT(); |
511 decls = parseDeclarationDefinitions(); | 462 decls = parseDeclarationDefinitions(); |
512 require(T.RBrace); | 463 require(T.RBrace); |
797 case T.LParen: | 748 case T.LParen: |
798 // ( Type ) . Identifier | 749 // ( Type ) . Identifier |
799 auto type = parseType(); | 750 auto type = parseType(); |
800 require(T.RParen); | 751 require(T.RParen); |
801 require(T.Dot); | 752 require(T.Dot); |
802 string ident; | 753 string ident = requireIdentifier(); |
803 if (token.type == T.Identifier) | |
804 { | |
805 ident = token.identifier; | |
806 nT(); | |
807 } | |
808 else | |
809 errorIfNot(T.Identifier); | |
810 e = new TypeDotIdExpression(type, ident); | 754 e = new TypeDotIdExpression(type, ident); |
811 break; | 755 break; |
812 default: | 756 default: |
813 e = parsePostExpression(parsePrimaryExpression()); | 757 e = parsePostExpression(parsePrimaryExpression()); |
814 break; | 758 break; |
1037 case T.Typeof: | 981 case T.Typeof: |
1038 requireNext(T.LParen); | 982 requireNext(T.LParen); |
1039 auto type = new TypeofType(parseExpression()); | 983 auto type = new TypeofType(parseExpression()); |
1040 require(T.RParen); | 984 require(T.RParen); |
1041 if (token.type == T.Dot) | 985 if (token.type == T.Dot) |
1042 { | 986 { // typeof ( Expression ) . Identifier |
1043 nT(); | 987 nT(); |
1044 string ident; | 988 string ident = requireIdentifier; |
1045 if (token.type == T.Identifier) | |
1046 { | |
1047 ident = token.identifier; | |
1048 nT(); | |
1049 } | |
1050 else | |
1051 errorIfNot(T.Identifier); | |
1052 e = new TypeDotIdExpression(type, ident); | 989 e = new TypeDotIdExpression(type, ident); |
1053 } | 990 } |
1054 else | 991 else // typeof ( Expression ) |
1055 e = new TypeofExpression(type); | 992 e = new TypeofExpression(type); |
1056 break; | 993 break; |
1057 case T.Is: | 994 case T.Is: |
1058 requireNext(T.LParen); | 995 requireNext(T.LParen); |
1059 | 996 |
1103 T.Int, T.Uint, T.Long, T.Ulong, | 1040 T.Int, T.Uint, T.Long, T.Ulong, |
1104 T.Float, T.Double, T.Real, | 1041 T.Float, T.Double, T.Real, |
1105 T.Ifloat, T.Idouble, T.Ireal, | 1042 T.Ifloat, T.Idouble, T.Ireal, |
1106 T.Cfloat, T.Cdouble, T.Creal: | 1043 T.Cfloat, T.Cdouble, T.Creal: |
1107 auto type = new Type(token.type); | 1044 auto type = new Type(token.type); |
1108 | |
1109 requireNext(T.Dot); | 1045 requireNext(T.Dot); |
1110 | 1046 auto ident = requireIdentifier(); |
1111 string ident; | |
1112 if (token.type == T.Identifier) | |
1113 { | |
1114 ident = token.identifier; | |
1115 nT(); | |
1116 } | |
1117 else | |
1118 errorIfNot(T.Identifier); | |
1119 | 1047 |
1120 e = new TypeDotIdExpression(type, ident); | 1048 e = new TypeDotIdExpression(type, ident); |
1121 break; | 1049 break; |
1122 default: | 1050 default: |
1123 // TODO: issue error msg and decide what to return. | 1051 // TODO: issue error msg and decide what to return. |
1182 // parse template instance | 1110 // parse template instance |
1183 Lident: | 1111 Lident: |
1184 while (token.type == T.Dot) | 1112 while (token.type == T.Dot) |
1185 { | 1113 { |
1186 nT(); | 1114 nT(); |
1187 if (token.type == T.Identifier) | 1115 tident ~= requireIdentifier(); |
1188 { | |
1189 tident ~= token.identifier; | |
1190 nT(); | |
1191 } | |
1192 else | |
1193 errorIfNot(T.Identifier); | |
1194 // TODO: parse template instance | 1116 // TODO: parse template instance |
1195 // if (token.type == T.Not) | 1117 // if (token.type == T.Not) |
1196 // parse template instance | 1118 // parse template instance |
1197 } | 1119 } |
1198 t = tident; | 1120 t = tident; |
1395 nT(); | 1317 nT(); |
1396 else | 1318 else |
1397 error(MID.ExpectedButFound, tok, token.srcText); | 1319 error(MID.ExpectedButFound, tok, token.srcText); |
1398 } | 1320 } |
1399 | 1321 |
1322 string requireIdentifier() | |
1323 { | |
1324 string identifier; | |
1325 if (token.type == T.Identifier) | |
1326 { | |
1327 identifier = token.identifier; | |
1328 nT(); | |
1329 } | |
1330 else | |
1331 error(MID.ExpectedButFound, "Identifier", token.srcText); | |
1332 return identifier; | |
1333 } | |
1334 | |
1400 void error(MID id, ...) | 1335 void error(MID id, ...) |
1401 { | 1336 { |
1402 errors ~= new Information(InfoType.Parser, id, lx.loc, arguments(_arguments, _argptr)); | 1337 errors ~= new Information(InfoType.Parser, id, lx.loc, arguments(_arguments, _argptr)); |
1403 } | 1338 } |
1404 } | 1339 } |