Update lexer and parser for 2.066 language changes

This commit is contained in:
Hackerpilot 2014-05-27 08:26:06 +00:00
parent 8d34ba7144
commit f54f7823dc
2 changed files with 132 additions and 52 deletions

View File

@ -386,10 +386,10 @@ final class AliasDeclaration : ASTNode
public: public:
override void accept(ASTVisitor visitor) const override void accept(ASTVisitor visitor) const
{ {
mixin (visitIfNotNull!(linkageAttribute, type, name, initializers)); mixin (visitIfNotNull!(storageClasses, type, name, initializers));
} }
mixin OpEquals; mixin OpEquals;
/** */ LinkageAttribute linkageAttribute; /** */ StorageClass[] storageClasses;
/** */ Type type; /** */ Type type;
/** */ Token name; /** */ Token name;
/** */ AliasInitializer[] initializers; /** */ AliasInitializer[] initializers;
@ -402,10 +402,12 @@ final class AliasInitializer : ASTNode
public: public:
override void accept(ASTVisitor visitor) const override void accept(ASTVisitor visitor) const
{ {
mixin (visitIfNotNull!(name, type)); mixin (visitIfNotNull!(name, templateParameters, storageClasses, type));
} }
mixin OpEquals; mixin OpEquals;
/** */ Token name; /** */ Token name;
/** */ StorageClass[] storageClasses;
/** */ TemplateParameters templateParameters;
/** */ Type type; /** */ Type type;
} }
@ -752,11 +754,8 @@ final class Attribute : ASTNode
public: public:
override void accept(ASTVisitor visitor) const override void accept(ASTVisitor visitor) const
{ {
mixin (visitIfNotNull!(linkageAttribute, alignAttribute, mixin (visitIfNotNull!(pragmaExpression, storageClass));
pragmaExpression, storageClass));
} }
/** */ LinkageAttribute linkageAttribute;
/** */ AlignAttribute alignAttribute;
/** */ PragmaExpression pragmaExpression; /** */ PragmaExpression pragmaExpression;
/** */ StorageClass storageClass; /** */ StorageClass storageClass;
/** */ IdType attribute; /** */ IdType attribute;
@ -1325,6 +1324,7 @@ public:
/** */ Token name; /** */ Token name;
/** */ TemplateParameters templateParameters; /** */ TemplateParameters templateParameters;
/** */ AssignExpression assignExpression; /** */ AssignExpression assignExpression;
/** */ Type type;
mixin OpEquals; mixin OpEquals;
} }
@ -2254,11 +2254,11 @@ final class PrimaryExpression : ExpressionNode
public: public:
override void accept(ASTVisitor visitor) const override void accept(ASTVisitor visitor) const
{ {
mixin (visitIfNotNull!(basicType, primary, typeofExpression, mixin (visitIfNotNull!(basicType, typeConstructor, type, primary,
typeidExpression, arrayLiteral, assocArrayLiteral, expression, typeofExpression, typeidExpression, arrayLiteral, assocArrayLiteral,
dot, identifierOrTemplateInstance, isExpression, lambdaExpression, expression, dot, identifierOrTemplateInstance, isExpression,
functionLiteralExpression, traitsExpression, mixinExpression, lambdaExpression, functionLiteralExpression,
importExpression, vector)); mixinExpression, importExpression, vector));
} }
/** */ Token dot; /** */ Token dot;
/** */ Token primary; /** */ Token primary;
@ -2276,6 +2276,9 @@ public:
/** */ MixinExpression mixinExpression; /** */ MixinExpression mixinExpression;
/** */ ImportExpression importExpression; /** */ ImportExpression importExpression;
/** */ Vector vector; /** */ Vector vector;
/** */ Type type;
/** */ Token typeConstructor;
/** */ Arguments arguments;
mixin OpEquals; mixin OpEquals;
} }
@ -2484,8 +2487,11 @@ final class StorageClass : ASTNode
public: public:
override void accept(ASTVisitor visitor) const override void accept(ASTVisitor visitor) const
{ {
mixin (visitIfNotNull!(token, deprecated_, atAttribute)); mixin (visitIfNotNull!(token, alignAttribute, linkageAttribute,
atAttribute, deprecated_));
} }
/** */ AlignAttribute alignAttribute;
/** */ LinkageAttribute linkageAttribute;
/** */ AtAttribute atAttribute; /** */ AtAttribute atAttribute;
/** */ Deprecated deprecated_; /** */ Deprecated deprecated_;
/** */ Token token; /** */ Token token;

View File

@ -74,7 +74,7 @@ class Parser
* *
* $(GRAMMAR $(RULEDEF aliasDeclaration): * $(GRAMMAR $(RULEDEF aliasDeclaration):
* $(LITERAL 'alias') $(RULE aliasInitializer) $(LPAREN)$(LITERAL ',') $(RULE aliasInitializer)$(RPAREN)* $(LITERAL ';') * $(LITERAL 'alias') $(RULE aliasInitializer) $(LPAREN)$(LITERAL ',') $(RULE aliasInitializer)$(RPAREN)* $(LITERAL ';')
* | $(LITERAL 'alias') $(RULE linkageAttribute)? $(RULE type) $(LITERAL identifier) $(LITERAL ';') * | $(LITERAL 'alias') $(RULE storageClass)* $(RULE type) $(LITERAL identifier) $(LITERAL ';')
* ;) * ;)
*/ */
AliasDeclaration parseAliasDeclaration() AliasDeclaration parseAliasDeclaration()
@ -85,7 +85,7 @@ class Parser
node.comment = comment; node.comment = comment;
comment = null; comment = null;
if (startsWith(tok!"identifier", tok!"=")) if (startsWith(tok!"identifier", tok!"=") || startsWith(tok!"identifier", tok!"("))
{ {
AliasInitializer[] initializers; AliasInitializer[] initializers;
do do
@ -103,15 +103,11 @@ class Parser
} }
else else
{ {
// 'alias extern(C) void function() f;' => supported in DMD and DScanner. StorageClass[] storageClasses;
// 'alias f = extern(C) void function();' => not supported in both DMD and DScanner. See D Bugzilla 10471. while (moreTokens() && isStorageClass())
// 'alias extern void function() f;' => supported in DMD, not supported in DScanner since it's a storage class. storageClasses ~= parseStorageClass();
if (currentIs(tok!"extern")) if (storageClasses.length > 0)
{ node.storageClasses = ownArray(storageClasses);
if (!peekIs(tok!"("))
error(`"(" expected for the linkage attribute`);
node.linkageAttribute = parseLinkageAttribute();
}
warn("Prefer the new \"'alias' identifier '=' type ';'\" syntax" warn("Prefer the new \"'alias' identifier '=' type ';'\" syntax"
~ " to the old \"'alias' type identifier ';'\" syntax"); ~ " to the old \"'alias' type identifier ';'\" syntax");
if ((node.type = parseType()) is null) return null; if ((node.type = parseType()) is null) return null;
@ -143,7 +139,7 @@ alias core.sys.posix.stdio.fileno fileno;
/** /**
* Parses an AliasInitializer * Parses an AliasInitializer
* $(GRAMMAR $(RULEDEF aliasInitializer): * $(GRAMMAR $(RULEDEF aliasInitializer):
* $(LITERAL Identifier) $(LITERAL '=') $(RULE type) * $(LITERAL Identifier) $(RULE templateParameters)? $(LITERAL '=') $(RULE storageClass)* $(RULE type)
* ;) * ;)
*/ */
AliasInitializer parseAliasInitializer() AliasInitializer parseAliasInitializer()
@ -152,9 +148,15 @@ alias core.sys.posix.stdio.fileno fileno;
auto node = allocate!AliasInitializer; auto node = allocate!AliasInitializer;
auto i = expect(tok!"identifier"); auto i = expect(tok!"identifier");
if (i is null) return null; if (i is null) return null;
assert (i.text.length < 10_000);
node.name = *i; node.name = *i;
if (currentIs(tok!"("))
node.templateParameters = parseTemplateParameters();
if (expect(tok!"=") is null) return null; if (expect(tok!"=") is null) return null;
StorageClass[] storageClasses;
while (moreTokens() && isStorageClass())
storageClasses ~= parseStorageClass();
if (storageClasses.length > 0)
node.storageClasses = ownArray(storageClasses);
node.type = parseType(); node.type = parseType();
return node; return node;
} }
@ -740,8 +742,6 @@ alias core.sys.posix.stdio.fileno fileno;
* Parses an Attribute * Parses an Attribute
* *
* $(GRAMMAR $(RULEDEF attribute): * $(GRAMMAR $(RULEDEF attribute):
* $(RULE alignAttribute)
* | $(RULE linkageAttribute)
* | $(RULE pragmaExpression) * | $(RULE pragmaExpression)
* | $(RULE storageClass) * | $(RULE storageClass)
* | $(LITERAL 'export') * | $(LITERAL 'export')
@ -757,15 +757,6 @@ alias core.sys.posix.stdio.fileno fileno;
auto node = allocate!Attribute; auto node = allocate!Attribute;
switch (current.type) switch (current.type)
{ {
case tok!"extern":
if (peekIs(tok!"("))
node.linkageAttribute = parseLinkageAttribute();
else
goto default;
break;
case tok!"align":
node.alignAttribute = parseAlignAttribute();
break;
case tok!"pragma": case tok!"pragma":
node.pragmaExpression = parsePragmaExpression(); node.pragmaExpression = parsePragmaExpression();
break; break;
@ -4220,7 +4211,9 @@ q{(int a, ...)
* $(GRAMMAR $(RULEDEF primaryExpression): * $(GRAMMAR $(RULEDEF primaryExpression):
* $(RULE identifierOrTemplateInstance) * $(RULE identifierOrTemplateInstance)
* | $(LITERAL '.') $(RULE identifierOrTemplateInstance) * | $(LITERAL '.') $(RULE identifierOrTemplateInstance)
* | $(RULE typeConstructor) $(LITERAL '(') $(RULE basicType) $(LITERAL ')') $(LITERAL '.') $(LITERAL Identifier)
* | $(RULE basicType) $(LITERAL '.') $(LITERAL Identifier) * | $(RULE basicType) $(LITERAL '.') $(LITERAL Identifier)
* | $(RULE basicType) $(RULE arguments)
* | $(RULE typeofExpression) * | $(RULE typeofExpression)
* | $(RULE typeidExpression) * | $(RULE typeidExpression)
* | $(RULE vector) * | $(RULE vector)
@ -4275,12 +4268,30 @@ q{(int a, ...)
else else
node.identifierOrTemplateInstance = parseIdentifierOrTemplateInstance(); node.identifierOrTemplateInstance = parseIdentifierOrTemplateInstance();
break; break;
case tok!"immutable":
case tok!"const":
case tok!"inout":
case tok!"shared":
advance();
expect(tok!"(");
node.type = parseType();
expect(tok!")");
expect(tok!".");
auto ident = expect(tok!"identifier");
if (ident !is null)
node.primary = *ident;
break;
mixin (BASIC_TYPE_CASES); mixin (BASIC_TYPE_CASES);
node.basicType = advance(); node.basicType = advance();
expect(tok!"."); if (currentIs(tok!"."))
{
advance();
auto t = expect(tok!"identifier"); auto t = expect(tok!"identifier");
if (t !is null) if (t !is null)
node.primary = *t; node.primary = *t;
}
else if (currentIs(tok!"("))
node.arguments = parseArguments();
break; break;
case tok!"function": case tok!"function":
case tok!"delegate": case tok!"delegate":
@ -4701,10 +4712,12 @@ q{(int a, ...)
} }
/** /**
* Parses an StorageClass * Parses a StorageClass
* *
* $(GRAMMAR $(RULEDEF storageClass): * $(GRAMMAR $(RULEDEF storageClass):
* $(RULE atAttribute) * $(RULE alignAttribute)
* | $(RULE linkageAttribute)
* | $(RULE atAttribute)
* | $(RULE typeConstructor) * | $(RULE typeConstructor)
* | $(RULE deprecated) * | $(RULE deprecated)
* | $(LITERAL 'abstract') * | $(LITERAL 'abstract')
@ -4735,6 +4748,16 @@ q{(int a, ...)
case tok!"deprecated": case tok!"deprecated":
node.deprecated_ = parseDeprecated(); node.deprecated_ = parseDeprecated();
break; break;
case tok!"align":
node.alignAttribute = parseAlignAttribute();
break;
case tok!"extern":
if (peekIs(tok!"("))
{
node.linkageAttribute = parseLinkageAttribute();
break;
}
else goto case;
case tok!"const": case tok!"const":
case tok!"immutable": case tok!"immutable":
case tok!"inout": case tok!"inout":
@ -4742,7 +4765,6 @@ q{(int a, ...)
case tok!"abstract": case tok!"abstract":
case tok!"auto": case tok!"auto":
case tok!"enum": case tok!"enum":
case tok!"extern":
case tok!"final": case tok!"final":
case tok!"virtual": case tok!"virtual":
case tok!"nothrow": case tok!"nothrow":
@ -5118,19 +5140,24 @@ q{(int a, ...)
* *
* $(GRAMMAR $(RULEDEF eponymousTemplateDeclaration): * $(GRAMMAR $(RULEDEF eponymousTemplateDeclaration):
* $(LITERAL 'enum') $(LITERAL Identifier) $(RULE templateParameters) $(LITERAL '=') $(RULE assignExpression) $(LITERAL ';') * $(LITERAL 'enum') $(LITERAL Identifier) $(RULE templateParameters) $(LITERAL '=') $(RULE assignExpression) $(LITERAL ';')
* $(LITERAL 'enum') $(LITERAL Identifier) $(RULE templateParameters) $(LITERAL '=') $(RULE type) $(LITERAL ';')
* ;) * ;)
*/ */
EponymousTemplateDeclaration parseEponymousTemplateDeclaration() EponymousTemplateDeclaration parseEponymousTemplateDeclaration()
{ {
mixin(traceEnterAndExit!(__FUNCTION__)); mixin(traceEnterAndExit!(__FUNCTION__));
auto node = allocate!EponymousTemplateDeclaration; auto node = allocate!EponymousTemplateDeclaration;
expect(tok!"enum"); if (currentIsOneOf(tok!"enum", tok!"alias"))
advance();
auto ident = expect(tok!"identifier"); auto ident = expect(tok!"identifier");
if (ident is null) return null; if (ident is null) return null;
node.name = *ident; node.name = *ident;
node.templateParameters = parseTemplateParameters(); node.templateParameters = parseTemplateParameters();
expect(tok!"="); expect(tok!"=");
if (isExpression())
node.assignExpression = parseAssignExpression(); node.assignExpression = parseAssignExpression();
else
node.type = parseType();
expect(tok!";"); expect(tok!";");
return node; return node;
} }
@ -5696,10 +5723,11 @@ q{(int a, ...)
case tok!"inout": case tok!"inout":
case tok!"shared": case tok!"shared":
if (peekIsOneOf(tok!")", tok!",")) if (peekIsOneOf(tok!")", tok!","))
{
node.token = advance(); node.token = advance();
else
goto default;
break; break;
}
goto default;
default: default:
node.type = parseType(); node.type = parseType();
break; break;
@ -5863,6 +5891,19 @@ q{(int a, ...)
case tok!"immutable": case tok!"immutable":
case tok!"inout": case tok!"inout":
case tok!"shared": case tok!"shared":
auto b = setBookmark();
if (peekIs(tok!"("))
{
advance();
auto past = peekPastParens();
if (past !is null && past.type == tok!".")
{
goToBookmark(b);
goto default;
}
}
goToBookmark(b);
goto case;
case tok!"scope": case tok!"scope":
case tok!"pure": case tok!"pure":
case tok!"nothrow": case tok!"nothrow":
@ -6436,6 +6477,39 @@ protected:
return false; return false;
} }
bool isStorageClass()
{
if (!moreTokens()) return false;
switch (current.type)
{
case tok!"const":
case tok!"immutable":
case tok!"inout":
case tok!"shared":
return !peekIs(tok!"(");
case tok!"@":
case tok!"deprecated":
case tok!"abstract":
case tok!"align":
case tok!"auto":
case tok!"enum":
case tok!"extern":
case tok!"final":
case tok!"virtual":
case tok!"nothrow":
case tok!"override":
case tok!"pure":
case tok!"ref":
case tok!"__gshared":
case tok!"scope":
case tok!"static":
case tok!"synchronized":
return true;
default:
return false;
}
}
bool isAttribute() bool isAttribute()
{ {
if (!moreTokens()) return false; if (!moreTokens()) return false;
@ -6778,7 +6852,7 @@ protected:
size_t setBookmark() size_t setBookmark()
{ {
mixin(traceEnterAndExit!(__FUNCTION__)); // mixin(traceEnterAndExit!(__FUNCTION__));
suppressMessages++; suppressMessages++;
auto i = index; auto i = index;
return i; return i;