Evet, bu üzerinden kalkabileceğimiz basitlikte bir işlev. Sanırım biz bu işi yapacağız...:)
Ancak yine de ileride tıkanmamak için dil/src/dil/parser/ImportParser dosyasına ısrarcıyım. Olayı case'ler ile halletmiş ama lexer dizin içindeki her yapıya göre ayrı tasarlanmış sınıflar ile birlikte çalışıyor. Yani sandığımdan kapsamlıymış bu iş! Örneğin sadece olayın başladığı kısımın kodu şöyle:
void parseDeclarationDefinition(Protection prot)
{
switch (token.kind)
{
case T.Align:
nT();
if (token.kind == T.LParen)
nT(), nT(), nT(); // ( Integer )
parseDeclarationsBlock(prot);
break;
case T.Pragma:
nT();
skipToTokenAfterClosingParen();
parseDeclarationsBlock(prot);
break;
case T.Export,
T.Private,
T.Package,
T.Protected,
T.Public:
parseProtectionAttribute();
break;
// Storage classes
case T.Extern:
nT();
token.kind == T.LParen && skipToTokenAfterClosingParen();
parseDeclarationsBlock(prot);
break;
case T.Const:
version(D2)
{
if (peekNext() == T.LParen)
goto case_Declaration;
}
case T.Override,
T.Deprecated,
T.Abstract,
T.Synchronized,
// T.Static,
T.Final,
T.Auto,
T.Scope:
case_StaticAttribute:
case_InvariantAttribute:
nT();
parseDeclarationsBlock(prot);
break;
// End of storage classes.
case T.Alias, T.Typedef:
nT();
goto case_Declaration;
case T.Static:
switch (peekNext())
{
case T.Import:
goto case_Import;
case T.This:
nT(), nT(); // static this
skipToTokenAfterClosingParen();
parseFunctionBody();
break;
case T.Tilde:
nT(), nT(), nT(), nT(), nT(); // static ~ this ( )
parseFunctionBody();
break;
case T.If:
nT(), nT();
skipToTokenAfterClosingParen();
parseDeclarationsBlock(prot);
if (token.kind == T.Else)
nT(), parseDeclarationsBlock(prot);
break;
case T.Assert:
nT(), nT(); // static assert
skipToTokenAfterClosingParen();
skip(T.Semicolon);
break;
default:
goto case_StaticAttribute;
}
break;
case T.Import:
case_Import:
auto decl = parseImportDecl();
decl.setProtection(prot); // Set the protection attribute.
imports ~= decl.to!(ImportDecl);
break;
case T.Enum:
nT();
token.kind == T.Identifier && nT();
if (token.kind == T.Colon)
{
nT();
while (token.kind != T.LBrace && token.kind != T.EOF)
nT();
}
if (token.kind == T.Semicolon)
nT();
else
skipToTokenAfterClosingBrace();
break;
case T.Class:
case T.Interface:
nT(), skip(T.Identifier); // class Identifier
token.kind == T.LParen && skipToTokenAfterClosingParen(); // Skip template params.
if (token.kind == T.Colon)
{ // BaseClasses
nT();
while (token.kind != T.LBrace && token.kind != T.EOF)
if (token.kind == T.LParen) // Skip ( tokens... )
skipToTokenAfterClosingParen();
else
nT();
}
if (token.kind == T.Semicolon)
nT();
else
parseDeclarationDefinitionsBlock(Protection.None);
break;
case T.Struct, T.Union:
nT(); skip(T.Identifier);
token.kind == T.LParen && skipToTokenAfterClosingParen();
if (token.kind == T.Semicolon)
nT();
else
parseDeclarationDefinitionsBlock(Protection.None);
break;
case T.Tilde:
nT(); // ~
case T.This:
nT(); nT(); nT(); // this ( )
parseFunctionBody();
break;
case T.Invariant:
version(D2)
{
auto next = token;
if (peekAfter(next) == T.LParen)
{
if (peekAfter(next) != T.RParen)
goto case_Declaration;
}
else
goto case_InvariantAttribute;
}
nT();
token.kind == T.LParen && skipToTokenAfterClosingParen();
parseFunctionBody();
break;
case T.Unittest:
nT();
parseFunctionBody();
break;
case T.Debug:
nT();
if (token.kind == T.Equal)
{
nT(), nT(), nT(); // = Condition ;
break;
}
if (token.kind == T.LParen)
nT(), nT(), nT(); // ( Condition )
parseDeclarationsBlock(prot);
if (token.kind == T.Else)
nT(), parseDeclarationsBlock(prot);
break;
case T.Version:
nT();
if (token.kind == T.Equal)
{
nT(), nT(), nT(); // = Condition ;
break;
}
nT(), nT(), nT(); // ( Condition )
parseDeclarationsBlock(prot);
if (token.kind == T.Else)
nT(), parseDeclarationsBlock(prot);
break;
case T.Template:
nT();
skip(T.Identifier);
skipToTokenAfterClosingParen();
parseDeclarationDefinitionsBlock(Protection.None);
break;
case T.New:
nT();
skipToTokenAfterClosingParen();
parseFunctionBody();
break;
case T.Delete:
nT();
skipToTokenAfterClosingParen();
parseFunctionBody();
break;
case T.Mixin:
while (token.kind != T.Semicolon && token.kind != T.EOF)
if (token.kind == T.LParen)
skipToTokenAfterClosingParen();
else
nT();
skip(T.Semicolon);
break;
case T.Semicolon:
nT();
break;
// Declaration
case T.Identifier, T.Dot, T.Typeof:
case_Declaration:
while (token.kind != T.Semicolon && token.kind != T.EOF)
if (token.kind == T.LParen)
skipToTokenAfterClosingParen();
else if (token.kind == T.LBrace)
skipToTokenAfterClosingBrace();
else
nT();
skip(T.Semicolon);
break;
default:
if (token.isIntegralType)
goto case_Declaration;
nT();
}
}
FuncBodyStmt parseFunctionBody()
{
while (1)
{
switch (token.kind)
{
case T.LBrace:
skipToTokenAfterClosingBrace();
break;
case T.Semicolon:
nT();
break;
case T.In:
nT();
skipToTokenAfterClosingBrace();
continue;
case T.Out:
nT();
if (token.kind == T.LParen)
nT(), nT(), nT(); // ( Identifier )
skipToTokenAfterClosingBrace();
continue;
case T.Body:
nT();
goto case T.LBrace;
default:
}
break; // Exit loop.
}
return null;
}
}
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]