Mercurial > projects > dil
comparison trunk/src/dil/Parser.d @ 555:d9e328c3bab9
Fixed infinite loop in dil.Parser.parseMixin().
Fixed MSG.ExpectedNonEmptyStatement.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sat, 22 Dec 2007 20:16:30 +0100 |
parents | 3418027c3914 |
children | 0df647660e76 |
comparison
equal
deleted
inserted
replaced
554:d6212e3b9f36 | 555:d9e328c3bab9 |
---|---|
430 } | 430 } |
431 | 431 |
432 /++ | 432 /++ |
433 Parses either a VariableDeclaration or a FunctionDeclaration. | 433 Parses either a VariableDeclaration or a FunctionDeclaration. |
434 Params: | 434 Params: |
435 stc = the previously parsed storage classes | 435 stc = previously parsed storage classes |
436 protection = previously parsed protection attribute | |
437 linkType = previously parsed linkage type | |
438 testAutoDeclaration = whether to check for an AutoDeclaration | |
436 optionalParameterList = a hint for how to parse C-style function pointers | 439 optionalParameterList = a hint for how to parse C-style function pointers |
437 +/ | 440 +/ |
438 Declaration parseVariableOrFunction(StorageClass stc = StorageClass.None, | 441 Declaration parseVariableOrFunction(StorageClass stc = StorageClass.None, |
439 Protection protection = Protection.None, | 442 Protection protection = Protection.None, |
440 LinkageType linkType = LinkageType.None, | 443 LinkageType linkType = LinkageType.None, |
919 Declaration parseImportDeclaration() | 922 Declaration parseImportDeclaration() |
920 { | 923 { |
921 assert(token.type == T.Import || token.type == T.Static); | 924 assert(token.type == T.Import || token.type == T.Static); |
922 bool isStatic = skipped(T.Static); | 925 bool isStatic = skipped(T.Static); |
923 assert(token.type == T.Import); | 926 assert(token.type == T.Import); |
927 nT(); // Skip import keyword. | |
924 | 928 |
925 ModuleFQN[] moduleFQNs; | 929 ModuleFQN[] moduleFQNs; |
926 Identifier*[] moduleAliases; | 930 Identifier*[] moduleAliases; |
927 Identifier*[] bindNames; | 931 Identifier*[] bindNames; |
928 Identifier*[] bindAliases; | 932 Identifier*[] bindAliases; |
929 | 933 |
930 nT(); // Skip import keyword. | |
931 while (1) | 934 while (1) |
932 { | 935 { |
933 ModuleFQN moduleFQN; | 936 ModuleFQN moduleFQN; |
934 Identifier* moduleAlias; | 937 Identifier* moduleAlias; |
935 | 938 |
984 } | 987 } |
985 | 988 |
986 Declaration parseEnumDeclaration() | 989 Declaration parseEnumDeclaration() |
987 { | 990 { |
988 assert(token.type == T.Enum); | 991 assert(token.type == T.Enum); |
992 nT(); // Skip enum keyword. | |
989 | 993 |
990 Identifier* enumName; | 994 Identifier* enumName; |
991 Type baseType; | 995 Type baseType; |
992 EnumMember[] members; | 996 EnumMember[] members; |
993 bool hasBody; | 997 bool hasBody; |
994 | 998 |
995 nT(); // Skip enum keyword. | |
996 | |
997 enumName = optionalIdentifier(); | 999 enumName = optionalIdentifier(); |
998 | 1000 |
999 if (skipped(T.Colon)) | 1001 if (skipped(T.Colon)) |
1000 baseType = parseBasicType(); | 1002 baseType = parseBasicType(); |
1001 | 1003 |
1033 } | 1035 } |
1034 | 1036 |
1035 Declaration parseClassDeclaration() | 1037 Declaration parseClassDeclaration() |
1036 { | 1038 { |
1037 assert(token.type == T.Class); | 1039 assert(token.type == T.Class); |
1040 nT(); // Skip class keyword. | |
1038 | 1041 |
1039 Identifier* className; | 1042 Identifier* className; |
1040 TemplateParameters tparams; | 1043 TemplateParameters tparams; |
1041 BaseClass[] bases; | 1044 BaseClass[] bases; |
1042 Declarations decls; | 1045 Declarations decls; |
1043 | 1046 |
1044 nT(); // Skip class keyword. | |
1045 className = requireIdentifier(MSG.ExpectedClassName); | 1047 className = requireIdentifier(MSG.ExpectedClassName); |
1046 | 1048 |
1047 if (token.type == T.LParen) | 1049 if (token.type == T.LParen) |
1048 tparams = parseTemplateParameterList(); | 1050 tparams = parseTemplateParameterList(); |
1049 | 1051 |
1102 } | 1104 } |
1103 | 1105 |
1104 Declaration parseInterfaceDeclaration() | 1106 Declaration parseInterfaceDeclaration() |
1105 { | 1107 { |
1106 assert(token.type == T.Interface); | 1108 assert(token.type == T.Interface); |
1109 nT(); // Skip interface keyword. | |
1107 | 1110 |
1108 Identifier* name; | 1111 Identifier* name; |
1109 TemplateParameters tparams; | 1112 TemplateParameters tparams; |
1110 BaseClass[] bases; | 1113 BaseClass[] bases; |
1111 Declarations decls; | 1114 Declarations decls; |
1112 | 1115 |
1113 nT(); // Skip interface keyword. | |
1114 name = requireIdentifier(MSG.ExpectedInterfaceName); | 1116 name = requireIdentifier(MSG.ExpectedInterfaceName); |
1115 | 1117 |
1116 if (token.type == T.LParen) | 1118 if (token.type == T.LParen) |
1117 tparams = parseTemplateParameterList(); | 1119 tparams = parseTemplateParameterList(); |
1118 | 1120 |
1133 } | 1135 } |
1134 | 1136 |
1135 Declaration parseAggregateDeclaration() | 1137 Declaration parseAggregateDeclaration() |
1136 { | 1138 { |
1137 assert(token.type == T.Struct || token.type == T.Union); | 1139 assert(token.type == T.Struct || token.type == T.Union); |
1138 | |
1139 TOK tok = token.type; | 1140 TOK tok = token.type; |
1141 nT(); // Skip struct or union keyword. | |
1140 | 1142 |
1141 Identifier* name; | 1143 Identifier* name; |
1142 TemplateParameters tparams; | 1144 TemplateParameters tparams; |
1143 Declarations decls; | 1145 Declarations decls; |
1144 | |
1145 nT(); // Skip struct or union keyword. | |
1146 | 1146 |
1147 name = optionalIdentifier(); | 1147 name = optionalIdentifier(); |
1148 | 1148 |
1149 if (name && token.type == T.LParen) | 1149 if (name && token.type == T.LParen) |
1150 tparams = parseTemplateParameterList(); | 1150 tparams = parseTemplateParameterList(); |
1527 | 1527 |
1528 // This code is similar to parseDotListType(). | 1528 // This code is similar to parseDotListType(). |
1529 if (skipped(T.Dot)) | 1529 if (skipped(T.Dot)) |
1530 templateIdent ~= set(new DotExpression(), begin); | 1530 templateIdent ~= set(new DotExpression(), begin); |
1531 | 1531 |
1532 while (1) | 1532 do |
1533 { | 1533 { |
1534 begin = token; | 1534 begin = token; |
1535 auto ident = requireIdentifier(MSG.ExpectedAnIdentifier); | 1535 auto ident = requireIdentifier(MSG.ExpectedAnIdentifier); |
1536 Expression e; | 1536 Expression e; |
1537 if (skipped(T.Not)) // Identifier !( TemplateArguments ) | 1537 if (skipped(T.Not)) // Identifier !( TemplateArguments ) |
2152 Statement parseBreakStatement() | 2152 Statement parseBreakStatement() |
2153 { | 2153 { |
2154 assert(token.type == T.Break); | 2154 assert(token.type == T.Break); |
2155 nT(); | 2155 nT(); |
2156 auto ident = optionalIdentifier(); | 2156 auto ident = optionalIdentifier(); |
2157 require(T.Semicolon); | |
2157 return new BreakStatement(ident); | 2158 return new BreakStatement(ident); |
2158 } | 2159 } |
2159 | 2160 |
2160 Statement parseReturnStatement() | 2161 Statement parseReturnStatement() |
2161 { | 2162 { |
2350 nT(); | 2351 nT(); |
2351 assert(token.type == T.Assert); | 2352 assert(token.type == T.Assert); |
2352 nT(); | 2353 nT(); |
2353 Expression condition, message; | 2354 Expression condition, message; |
2354 require(T.LParen); | 2355 require(T.LParen); |
2355 condition = parseAssignExpression(); | 2356 condition = parseAssignExpression(); // Condition. |
2356 if (skipped(T.Comma)) | 2357 if (skipped(T.Comma)) |
2357 message = parseAssignExpression(); | 2358 message = parseAssignExpression(); // Error message. |
2358 require(T.RParen); | 2359 require(T.RParen); |
2359 require(T.Semicolon); | 2360 require(T.Semicolon); |
2360 return new StaticAssertStatement(condition, message); | 2361 return new StaticAssertStatement(condition, message); |
2361 } | 2362 } |
2362 | 2363 |