comparison trunk/src/dil/Parser.d @ 484:265c0b655f18

Added more calls to set(). Removed method skipToOnePast(). Added methods start2() and isNodeSet().
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Mon, 26 Nov 2007 20:18:54 +0100
parents 180711cc4b66
children ea8c7459f1c4
comparison
equal deleted inserted replaced
483:180711cc4b66 484:265c0b655f18
73 { 73 {
74 lx.nextToken(); 74 lx.nextToken();
75 token = lx.token; 75 token = lx.token;
76 } while (token.isWhitespace) // Skip whitespace 76 } while (token.isWhitespace) // Skip whitespace
77 } 77 }
78 /+ 78
79 void skipToOnePast(TOK tok) 79 /++
80 { 80 Start the parser and return the parsed Declarations.
81 for (; token.type != tok && token.type != T.EOF; nT()) 81 +/
82 {} 82 Declarations start()
83 nT(); 83 {
84 } 84 init();
85 +/ 85 auto begin = token;
86 auto decls = new Declarations;
87 if (token.type == T.Module)
88 decls ~= parseModuleDeclaration();
89 decls ~= parseDeclarationDefinitions();
90 set(decls, begin);
91 return decls;
92 }
93
94 /++
95 Start the parser and return the parsed Expression.
96 +/
97 Expression start2()
98 {
99 init();
100 return parseExpression();
101 }
102
86 uint trying; 103 uint trying;
87 uint errorCount; 104 uint errorCount;
88 105
89 /++ 106 /++
90 This method executes the delegate parseMethod and when an error occurred 107 This method executes the delegate parseMethod and when an error occurred
115 success = true; 132 success = true;
116 --trying; 133 --trying;
117 return result; 134 return result;
118 } 135 }
119 136
137 /++
138 Sets the begin and end tokens of an AST node.
139 +/
120 Class set(Class)(Class node, Token* begin) 140 Class set(Class)(Class node, Token* begin)
121 { 141 {
122 node.setTokens(begin, this.prevToken); 142 node.setTokens(begin, this.prevToken);
123 return node; 143 return node;
144 }
145
146 /++
147 Returns true if set() has been called on a node, or false otherwise.
148 +/
149 bool isNodeSet(Node node)
150 {
151 return node.begin !is null && node.end !is null;
124 } 152 }
125 153
126 TOK peekNext() 154 TOK peekNext()
127 { 155 {
128 auto state = lx.getState(); 156 auto state = lx.getState();
147 175
148 /++++++++++++++++++++++++++++++ 176 /++++++++++++++++++++++++++++++
149 + Declaration parsing methods + 177 + Declaration parsing methods +
150 ++++++++++++++++++++++++++++++/ 178 ++++++++++++++++++++++++++++++/
151 179
152 Declarations start()
153 {
154 init();
155 auto decls = new Declarations;
156 if (token.type == T.Module)
157 decls ~= parseModuleDeclaration();
158 decls ~= parseDeclarationDefinitions();
159 return decls;
160 }
161
162 Declaration parseModuleDeclaration() 180 Declaration parseModuleDeclaration()
163 { 181 {
164 auto begin = token; 182 auto begin = token;
165 ModuleFQN moduleFQN; 183 ModuleFQN moduleFQN;
166 do 184 do
185 { } 203 { }
186 { DeclDefs } 204 { DeclDefs }
187 */ 205 */
188 Declarations parseDeclarationDefinitionsBlock() 206 Declarations parseDeclarationDefinitionsBlock()
189 { 207 {
208 auto begin = token;
190 auto decls = new Declarations; 209 auto decls = new Declarations;
191 require(T.LBrace); 210 require(T.LBrace);
192 while (token.type != T.RBrace && token.type != T.EOF) 211 while (token.type != T.RBrace && token.type != T.EOF)
193 decls ~= parseDeclarationDefinition(); 212 decls ~= parseDeclarationDefinition();
194 require(T.RBrace); 213 require(T.RBrace);
195 return decls; 214 return set(decls, token);
196 } 215 }
197 216
198 Declaration parseDeclarationDefinition() 217 Declaration parseDeclarationDefinition()
199 { 218 {
200 auto begin = token; 219 auto begin = token;
361 break; 380 break;
362 case T.Colon: 381 case T.Colon:
363 if (noColon == true) 382 if (noColon == true)
364 goto default; 383 goto default;
365 nT(); 384 nT();
385 auto begin = token;
366 auto decls = new Declarations; 386 auto decls = new Declarations;
367 while (token.type != T.RBrace && token.type != T.EOF) 387 while (token.type != T.RBrace && token.type != T.EOF)
368 decls ~= parseDeclarationDefinition(); 388 decls ~= parseDeclarationDefinition();
369 d = decls; 389 d = set(decls, begin);
370 break; 390 break;
371 default: 391 default:
372 d = parseDeclarationDefinition(); 392 d = parseDeclarationDefinition();
373 } 393 }
394 assert(isNodeSet(d));
374 return d; 395 return d;
375 } 396 }
376 397
377 Declaration parseDeclarationsBlockNoColon() 398 Declaration parseDeclarationsBlockNoColon()
378 { 399 {
815 require(T.RParen); 836 require(T.RParen);
816 837
817 if (token.type == T.Semicolon) 838 if (token.type == T.Semicolon)
818 { 839 {
819 nT(); 840 nT();
841 // TODO: call set()?
820 decls = new EmptyDeclaration(); 842 decls = new EmptyDeclaration();
821 } 843 }
822 else 844 else
823 decls = parseDeclarationsBlock(); 845 decls = parseDeclarationsBlock();
824 846
1016 nT(); 1038 nT();
1017 } 1039 }
1018 else if (token.type == T.LBrace) 1040 else if (token.type == T.LBrace)
1019 { 1041 {
1020 hasBody = true; 1042 hasBody = true;
1021 // 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.
1022 decls = parseDeclarationDefinitionsBlock(); 1043 decls = parseDeclarationDefinitionsBlock();
1023 } 1044 }
1024 else 1045 else
1025 expected(T.LBrace); // TODO: better error msg 1046 expected(T.LBrace); // TODO: better error msg
1026 1047
1481 TemplateInstance: 1502 TemplateInstance:
1482 Identifier !( TemplateArguments ) 1503 Identifier !( TemplateArguments )
1483 +/ 1504 +/
1484 DotListType parseDotListType() 1505 DotListType parseDotListType()
1485 { 1506 {
1507 auto begin = token;
1486 Type[] identList; 1508 Type[] identList;
1487 if (token.type == T.Dot) 1509 if (token.type == T.Dot)
1488 { 1510 {
1489 identList ~= new IdentifierType(token); 1511 identList ~= set(new IdentifierType(token), begin);
1490 nT(); 1512 nT();
1491 } 1513 }
1492 else if (token.type == T.Typeof) 1514 else if (token.type == T.Typeof)
1493 { 1515 {
1494 requireNext(T.LParen); 1516 requireNext(T.LParen);
1495 identList ~= new TypeofType(parseExpression()); 1517 identList ~= set(new TypeofType(parseExpression()), begin);
1496 require(T.RParen); 1518 require(T.RParen);
1497 if (token.type != T.Dot) 1519 if (token.type != T.Dot)
1498 goto Lreturn; 1520 goto Lreturn;
1499 nT(); 1521 nT();
1500 } 1522 }
1501 1523
1502 while (1) 1524 while (1)
1503 { 1525 {
1504 auto begin2 = token; 1526 begin = token;
1505 auto ident = requireId(); 1527 auto ident = requireId();
1506 // NB.: Currently Types can't be followed by "!=" so we don't need to peek for "(" when parsing TemplateInstances. 1528 // NB.: Currently Types can't be followed by "!=" so we don't need to peek for "(" when parsing TemplateInstances.
1507 if (token.type == T.Not/+ && peekNext() == T.LParen+/) // Identifier !( TemplateArguments ) 1529 if (token.type == T.Not/+ && peekNext() == T.LParen+/) // Identifier !( TemplateArguments )
1508 { 1530 {
1509 nT(); // Skip !. 1531 nT(); // Skip !.
1510 identList ~= set(new TemplateInstanceType(ident, parseTemplateArguments()), begin2); 1532 identList ~= set(new TemplateInstanceType(ident, parseTemplateArguments()), begin);
1511 } 1533 }
1512 else // Identifier 1534 else // Identifier
1513 identList ~= set(new IdentifierType(ident), begin2); 1535 identList ~= set(new IdentifierType(ident), begin);
1514 1536
1515 if (token.type != T.Dot) 1537 if (token.type != T.Dot)
1516 break; 1538 break;
1517 nT(); 1539 nT();
1518 } 1540 }
1551 Token* mixinIdent; 1573 Token* mixinIdent;
1552 1574
1553 // This code is similar to parseDotListType(). 1575 // This code is similar to parseDotListType().
1554 if (token.type == T.Dot) 1576 if (token.type == T.Dot)
1555 { 1577 {
1556 templateIdent ~= new IdentifierExpression(token); 1578 templateIdent ~= set(new IdentifierExpression(token), begin);
1557 nT(); 1579 nT();
1558 } 1580 }
1559 1581
1560 while (1) 1582 while (1)
1561 { 1583 {
1584 begin = token;
1562 auto ident = requireId(); 1585 auto ident = requireId();
1563 Expression e; 1586 Expression e;
1564 if (token.type == T.Not) // Identifier !( TemplateArguments ) 1587 if (token.type == T.Not) // Identifier !( TemplateArguments )
1565 { 1588 {
1566 // No need to peek for T.LParen. This must be a template instance. 1589 // No need to peek for T.LParen. This must be a template instance.
1567 nT(); 1590 nT();
1568 e = new TemplateInstanceExpression(ident, parseTemplateArguments()); 1591 e = set(new TemplateInstanceExpression(ident, parseTemplateArguments()), begin);
1569 } 1592 }
1570 else // Identifier 1593 else // Identifier
1571 e = new IdentifierExpression(ident); 1594 e = set(new IdentifierExpression(ident), begin);
1572 1595
1573 templateIdent ~= e; 1596 templateIdent ~= e;
1574 1597
1575 if (token.type != T.Dot) 1598 if (token.type != T.Dot)
1576 break; 1599 break;
2005 Statement ifBody, elseBody; 2028 Statement ifBody, elseBody;
2006 2029
2007 require(T.LParen); 2030 require(T.LParen);
2008 2031
2009 Token* ident; 2032 Token* ident;
2033 auto begin = token; // For start of AutoDeclaration or normal Declaration.
2010 // auto Identifier = Expression 2034 // auto Identifier = Expression
2011 if (token.type == T.Auto) 2035 if (token.type == T.Auto)
2012 { 2036 {
2013 nT(); 2037 nT();
2014 ident = requireId(); 2038 ident = requireId();
2015 require(T.Assign); 2039 require(T.Assign);
2016 auto init = parseExpression(); 2040 auto init = parseExpression();
2017 variable = new AttributeStatement(T.Auto, new DeclarationStatement(new VariableDeclaration(null, [ident], [init]))); 2041 auto v = new VariableDeclaration(null, [ident], [init]);
2042 set(v, ident);
2043 auto d = new DeclarationStatement(v);
2044 set(d, ident);
2045 variable = new AttributeStatement(T.Auto, d);
2046 set(variable, begin);
2018 } 2047 }
2019 else 2048 else
2020 { 2049 {
2021 // Declarator = Expression 2050 // Declarator = Expression
2022 Type parseDeclaratorAssign() 2051 Type parseDeclaratorAssign()
2028 bool success; 2057 bool success;
2029 auto type = try_(&parseDeclaratorAssign, success); 2058 auto type = try_(&parseDeclaratorAssign, success);
2030 if (success) 2059 if (success)
2031 { 2060 {
2032 auto init = parseExpression(); 2061 auto init = parseExpression();
2033 variable = new DeclarationStatement(new VariableDeclaration(type, [ident], [init])); 2062 auto v = new VariableDeclaration(type, [ident], [init]);
2063 set(v, begin);
2064 variable = new DeclarationStatement(v);
2065 set(variable, begin);
2034 } 2066 }
2035 else 2067 else
2036 condition = parseExpression(); 2068 condition = parseExpression();
2037 } 2069 }
2038 require(T.RParen); 2070 require(T.RParen);
3753 nT(); 3785 nT();
3754 set(t, begin); 3786 set(t, begin);
3755 break; 3787 break;
3756 case T.Identifier, T.Typeof, T.Dot: 3788 case T.Identifier, T.Typeof, T.Dot:
3757 t = parseDotListType(); 3789 t = parseDotListType();
3790 assert(!isNodeSet(t));
3791 set(t, begin);
3758 break; 3792 break;
3759 version(D2) 3793 version(D2)
3760 { 3794 {
3761 case T.Const: 3795 case T.Const:
3762 // const ( Type ) 3796 // const ( Type )