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 }