More progress. Cleaned up grammar based on the fact that the semicolon is no longer a valid statement. Added unit tests. Implemented some more parsing methods

This commit is contained in:
Hackerpilot 2013-06-09 03:10:52 +00:00
parent 4fdcccc8bc
commit 79bfe7af4e
2 changed files with 739 additions and 331 deletions

View File

@ -26,215 +26,214 @@ classes
abstract /// abstract ///
class ASTVisitor class ASTVisitor
{ {
/** */void visit(AddExpression addExpression) {} /** */ void visit(AddExpression addExpression) {}
/** */void visit(AliasDeclaration aliasDeclaration) {} /** */ void visit(AliasDeclaration aliasDeclaration) {}
/** */void visit(AliasInitializer aliasInitializer) {} /** */ void visit(AliasInitializer aliasInitializer) {}
/** */void visit(AliasThisDeclaration aliasThisDeclaration) {} /** */ void visit(AliasThisDeclaration aliasThisDeclaration) {}
/** */void visit(AlignAttribute alignAttribute) {} /** */ void visit(AlignAttribute alignAttribute) {}
/** */void visit(AndAndExpression andAndExpression) {} /** */ void visit(AndAndExpression andAndExpression) {}
/** */void visit(AndExpression andExpression) {} /** */ void visit(AndExpression andExpression) {}
/** */void visit(ArgumentList argumentList) {} /** */ void visit(ArgumentList argumentList) {}
/** */void visit(Arguments arguments) {} /** */ void visit(Arguments arguments) {}
/** */void visit(ArrayInitializer arrayInitializer) {} /** */ void visit(ArrayInitializer arrayInitializer) {}
/** */void visit(ArrayLiteral arrayLiteral) {} /** */ void visit(ArrayLiteral arrayLiteral) {}
/** */void visit(ArrayMemberInitialization arrayMemberInitialization) {} /** */ void visit(ArrayMemberInitialization arrayMemberInitialization) {}
/** */void visit(AsmAddExp asmAddExp) {} /** */ void visit(AsmAddExp asmAddExp) {}
/** */void visit(AsmAndExp asmAndExp) {} /** */ void visit(AsmAndExp asmAndExp) {}
/** */void visit(AsmBrExp asmBrExp) {} /** */ void visit(AsmBrExp asmBrExp) {}
/** */void visit(AsmEqualExp asmEqualExp) {} /** */ void visit(AsmEqualExp asmEqualExp) {}
/** */void visit(AsmExp asmExp) {} /** */ void visit(AsmExp asmExp) {}
/** */void visit(AsmInstruction asmInstruction) {} /** */ void visit(AsmInstruction asmInstruction) {}
/** */void visit(AsmLogAndExp asmLogAndExp) {} /** */ void visit(AsmLogAndExp asmLogAndExp) {}
/** */void visit(AsmLogOrExp asmLogOrExp) {} /** */ void visit(AsmLogOrExp asmLogOrExp) {}
/** */void visit(AsmMulExp asmMulExp) {} /** */ void visit(AsmMulExp asmMulExp) {}
/** */void visit(AsmOrExp asmOrExp) {} /** */ void visit(AsmOrExp asmOrExp) {}
/** */void visit(AsmPrimaryExp asmPrimaryExp) {} /** */ void visit(AsmPrimaryExp asmPrimaryExp) {}
/** */void visit(AsmRelExp asmRelExp) {} /** */ void visit(AsmRelExp asmRelExp) {}
/** */void visit(AsmShiftExp asmShiftExp) {} /** */ void visit(AsmShiftExp asmShiftExp) {}
/** */void visit(AsmStatement asmStatement) {} /** */ void visit(AsmStatement asmStatement) {}
/** */void visit(AsmTypePrefix asmTypePrefix) {} /** */ void visit(AsmTypePrefix asmTypePrefix) {}
/** */void visit(AsmUnaExp asmUnaExp) {} /** */ void visit(AsmUnaExp asmUnaExp) {}
/** */void visit(AsmXorExp asmXorExp) {} /** */ void visit(AsmXorExp asmXorExp) {}
/** */void visit(AssertExpression assertExpression) {} /** */ void visit(AssertExpression assertExpression) {}
/** */void visit(AssertStatement assertStatement) {} /** */ void visit(AssertStatement assertStatement) {}
/** */void visit(AssignExpression assignExpression) {} /** */ void visit(AssignExpression assignExpression) {}
/** */void visit(AssignStatement assignStatement) {} /** */ void visit(AssignStatement assignStatement) {}
/** */void visit(AssocArrayLiteral assocArrayLiteral) {} /** */ void visit(AssocArrayLiteral assocArrayLiteral) {}
/** */void visit(AtAttribute atAttribute) {} /** */ void visit(AtAttribute atAttribute) {}
/** */void visit(Attribute attribute) {} /** */ void visit(Attribute attribute) {}
/** */void visit(AttributedDeclaration attributedDeclaration) {} /** */ void visit(AttributedDeclaration attributedDeclaration) {}
/** */void visit(AutoDeclaration autoDeclaration) {} /** */ void visit(AutoDeclaration autoDeclaration) {}
/** */void visit(BlockStatement blockStatement) {} /** */ void visit(BlockStatement blockStatement) {}
/** */void visit(BodyStatement bodyStatement) {} /** */ void visit(BodyStatement bodyStatement) {}
/** */void visit(BreakStatement breakStatement) {} /** */ void visit(BreakStatement breakStatement) {}
/** */void visit(BaseClass baseClass) {} /** */ void visit(BaseClass baseClass) {}
/** */void visit(BaseClassList baseClassList) {} /** */ void visit(BaseClassList baseClassList) {}
/** */void visit(BasicType builtinType) {} /** */ void visit(BasicType builtinType) {}
/** */void visit(CaseRangeStatement caseRangeStatement) {} /** */ void visit(CaseRangeStatement caseRangeStatement) {}
/** */void visit(CaseStatement caseStatement) {} /** */ void visit(CaseStatement caseStatement) {}
/** */void visit(CastExpression castExpression) {} /** */ void visit(CastExpression castExpression) {}
/** */void visit(CastQualifier castQualifier) {} /** */ void visit(CastQualifier castQualifier) {}
/** */void visit(Catch catch_) {} /** */ void visit(Catch catch_) {}
/** */void visit(Catches catches) {} /** */ void visit(Catches catches) {}
/** */void visit(ClassBody classBody) {} /** */ void visit(ClassBody classBody) {}
/** */void visit(ClassDeclaration classDeclaration) {} /** */ void visit(ClassDeclaration classDeclaration) {}
/** */void visit(CmpExpression cmpExpression) {} /** */ void visit(CmpExpression cmpExpression) {}
/** */void visit(CompileCondition compileCondition) {} /** */ void visit(CompileCondition compileCondition) {}
/** */void visit(ConditionalDeclaration conditionalDeclaration) {} /** */ void visit(ConditionalDeclaration conditionalDeclaration) {}
/** */void visit(ConditionalStatement conditionalStatement) {} /** */ void visit(ConditionalStatement conditionalStatement) {}
/** */void visit(Constraint constraint) {} /** */ void visit(Constraint constraint) {}
/** */void visit(Constructor constructor) {} /** */ void visit(Constructor constructor) {}
/** */void visit(ContinueStatement continueStatement) {} /** */ void visit(ContinueStatement continueStatement) {}
/** */void visit(DebugCondition debugCondition) {} /** */ void visit(DebugCondition debugCondition) {}
/** */void visit(DebugSpecification debugSpecification) {} /** */ void visit(DebugSpecification debugSpecification) {}
/** */void visit(Declaration declaration) {} /** */ void visit(Declaration declaration) {}
/** */void visit(DeclarationsAndStatements declarationsAndStatements) {} /** */ void visit(DeclarationsAndStatements declarationsAndStatements) {}
/** */void visit(DeclarationOrInvariant declarationOrInvariant) {} /** */ void visit(DeclarationOrInvariant declarationOrInvariant) {}
/** */void visit(Declarator declarator) {} /** */ void visit(Declarator declarator) {}
/** */void visit(DeclaratorSuffix declaratorSuffix) {} /** */ void visit(DeclaratorSuffix declaratorSuffix) {}
/** */void visit(DefaultStatement defaultStatement) {} /** */ void visit(DefaultStatement defaultStatement) {}
/** */void visit(DeleteExpression deleteExpression) {} /** */ void visit(DeleteExpression deleteExpression) {}
/** */void visit(DeleteStatement deleteStatement) {} /** */ void visit(DeleteStatement deleteStatement) {}
/** */void visit(Deprecated deprecated_) {} /** */ void visit(Deprecated deprecated_) {}
/** */void visit(Destructor destructor) {} /** */ void visit(Destructor destructor) {}
/** */void visit(DoStatement doStatement) {} /** */ void visit(DoStatement doStatement) {}
/** */void visit(EnumBody enumBody) {} /** */ void visit(EnumBody enumBody) {}
/** */void visit(EnumDeclaration enumDeclaration) {} /** */ void visit(EnumDeclaration enumDeclaration) {}
/** */void visit(EnumMember enumMember) {} /** */ void visit(EnumMember enumMember) {}
/** */void visit(EqualExpression equalExpression) {} /** */ void visit(EqualExpression equalExpression) {}
/** */void visit(Expression expression) {} /** */ void visit(Expression expression) {}
/** */void visit(FinalSwitchStatement finalSwitchStatement) {} /** */ void visit(FinalSwitchStatement finalSwitchStatement) {}
/** */void visit(Finally finally_) {} /** */ void visit(Finally finally_) {}
/** */void visit(ForStatement forStatement) {} /** */ void visit(ForStatement forStatement) {}
/** */void visit(ForeachRangeStatement foreachRangeStatement) {} /** */ void visit(ForeachRangeStatement foreachRangeStatement) {}
/** */void visit(ForeachStatement foreachStatement) {} /** */ void visit(ForeachStatement foreachStatement) {}
/** */void visit(ForeachType foreachType) {} /** */ void visit(ForeachType foreachType) {}
/** */void visit(ForeachTypeList foreachTypeList) {} /** */ void visit(ForeachTypeList foreachTypeList) {}
/** */void visit(FunctionAttribute functionAttribute) {} /** */ void visit(FunctionAttribute functionAttribute) {}
/** */void visit(FunctionBody functionBody) {} /** */ void visit(FunctionBody functionBody) {}
/** */void visit(FunctionCallExpression functionCallExpression) {} /** */ void visit(FunctionCallExpression functionCallExpression) {}
/** */void visit(FunctionCallStatement functionCallStatement) {} /** */ void visit(FunctionCallStatement functionCallStatement) {}
/** */void visit(FunctionDeclaration functionDeclaration) {} /** */ void visit(FunctionDeclaration functionDeclaration) {}
/** */void visit(FunctionLiteralExpression functionLiteralExpression) {} /** */ void visit(FunctionLiteralExpression functionLiteralExpression) {}
/** */void visit(GotoStatement gotoStatement) {} /** */ void visit(GotoStatement gotoStatement) {}
/** */void visit(IdentifierChain identifierChain) {} /** */ void visit(IdentifierChain identifierChain) {}
/** */void visit(IdentifierList identifierList) {} /** */ void visit(IdentifierList identifierList) {}
/** */void visit(IdentifierOrTemplateChain identifierOrTemplateChain) {} /** */ void visit(IdentifierOrTemplateChain identifierOrTemplateChain) {}
/** */void visit(IdentifierOrTemplateInstance identifierOrTemplateInstance) {} /** */ void visit(IdentifierOrTemplateInstance identifierOrTemplateInstance) {}
/** */void visit(IdentityExpression identityExpression) {} /** */ void visit(IdentityExpression identityExpression) {}
/** */void visit(IfStatement ifStatement) {} /** */ void visit(IfStatement ifStatement) {}
/** */void visit(ImportBind importBind) {} /** */ void visit(ImportBind importBind) {}
/** */void visit(ImportBindings importBindings) {} /** */ void visit(ImportBindings importBindings) {}
/** */void visit(ImportDeclaration importDeclaration) {} /** */ void visit(ImportDeclaration importDeclaration) {}
/** */void visit(ImportExpression importExpression) {} /** */ void visit(ImportExpression importExpression) {}
/** */void visit(ImportList importList) {} /** */ void visit(ImportList importList) {}
/** */void visit(IndexExpression indexExpression) {} /** */ void visit(IndexExpression indexExpression) {}
/** */void visit(InExpression inExpression) {} /** */ void visit(InExpression inExpression) {}
/** */void visit(InStatement inStatement) {} /** */ void visit(InStatement inStatement) {}
/** */void visit(Initialize initialize) {} /** */ void visit(Initialize initialize) {}
/** */void visit(Initializer initializer) {} /** */ void visit(Initializer initializer) {}
/** */void visit(InterfaceDeclaration interfaceDeclaration) {} /** */ void visit(InterfaceDeclaration interfaceDeclaration) {}
/** */void visit(Invariant invariant_) {} /** */ void visit(Invariant invariant_) {}
/** */void visit(IsExpression isExpression) {} /** */ void visit(IsExpression isExpression) {}
/** */void visit(KeyValuePair keyValuePair) {} /** */ void visit(KeyValuePair keyValuePair) {}
/** */void visit(KeyValuePairs keyValuePairs) {} /** */ void visit(KeyValuePairs keyValuePairs) {}
/** */void visit(LabeledStatement labeledStatement) {} /** */ void visit(LabeledStatement labeledStatement) {}
/** */void visit(LambdaExpression lambdaExpression) {} /** */ void visit(LambdaExpression lambdaExpression) {}
/** */void visit(LastCatch lastCatch) {} /** */ void visit(LastCatch lastCatch) {}
/** */void visit(LinkageAttribute linkageAttribute) {} /** */ void visit(LinkageAttribute linkageAttribute) {}
/** */void visit(MemberFunctionAttribute memberFunctionAttribute) {} /** */ void visit(MemberFunctionAttribute memberFunctionAttribute) {}
/** */void visit(MixinDeclaration mixinDeclaration) {} /** */ void visit(MixinDeclaration mixinDeclaration) {}
/** */void visit(MixinExpression mixinExpression) {} /** */ void visit(MixinExpression mixinExpression) {}
/** */void visit(MixinTemplateName mixinTemplateName) {} /** */ void visit(MixinTemplateName mixinTemplateName) {}
/** */void visit(Module module_) {} /** */ void visit(Module module_) {}
/** */void visit(ModuleDeclaration moduleDeclaration) {} /** */ void visit(ModuleDeclaration moduleDeclaration) {}
/** */void visit(MulExpression mulExpression) {} /** */ void visit(MulExpression mulExpression) {}
/** */void visit(NewAnonClassExpression newAnonClassExpression) {} /** */ void visit(NewAnonClassExpression newAnonClassExpression) {}
/** */void visit(NewExpression newExpression) {} /** */ void visit(NewExpression newExpression) {}
/** */void visit(NonEmptyStatement nonEmptyStatement) {} /** */ void visit(NonEmptyStatement nonEmptyStatement) {}
/** */void visit(NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault) {} /** */ void visit(NonVoidInitializer nonVoidInitializer) {}
/** */void visit(NonVoidInitializer nonVoidInitializer) {} /** */ void visit(Operand operand) {}
/** */void visit(Operand operand) {} /** */ void visit(Operands operands) {}
/** */void visit(Operands operands) {} /** */ void visit(OrExpression orExpression) {}
/** */void visit(OrExpression orExpression) {} /** */ void visit(OrOrExpression orOrExpression) {}
/** */void visit(OrOrExpression orOrExpression) {} /** */ void visit(OutStatement outStatement) {}
/** */void visit(OutStatement outStatement) {} /** */ void visit(Parameter parameter) {}
/** */void visit(Parameter parameter) {} /** */ void visit(ParameterAttribute parameterAttribute) {}
/** */void visit(ParameterAttribute parameterAttribute) {} /** */ void visit(Parameters parameters) {}
/** */void visit(Parameters parameters) {} /** */ void visit(Postblit postblit) {}
/** */void visit(Postblit postblit) {} /** */ void visit(PostIncDecExpression postIncDecExpression) {}
/** */void visit(PostIncDecExpression postIncDecExpression) {} /** */ void visit(PowExpression powExpression) {}
/** */void visit(PowExpression powExpression) {} /** */ void visit(PragmaDeclaration pragmaDeclaration) {}
/** */void visit(PragmaDeclaration pragmaDeclaration) {} /** */ void visit(PragmaExpression pragmaExpression) {}
/** */void visit(PragmaExpression pragmaExpression) {} /** */ void visit(PreIncDecExpression preIncDecExpression) {}
/** */void visit(PreIncDecExpression preIncDecExpression) {} /** */ void visit(PrimaryExpression primaryExpression) {}
/** */void visit(PrimaryExpression primaryExpression) {} /** */ void visit(Register register) {}
/** */void visit(Register register) {} /** */ void visit(RelExpression relExpression) {}
/** */void visit(RelExpression relExpression) {} /** */ void visit(ReturnStatement returnStatement) {}
/** */void visit(ReturnStatement returnStatement) {} /** */ void visit(ScopeGuardStatement scopeGuardStatement) {}
/** */void visit(ScopeGuardStatement scopeGuardStatement) {} /** */ void visit(SharedStaticConstructor sharedStaticConstructor) {}
/** */void visit(SharedStaticConstructor sharedStaticConstructor) {} /** */ void visit(SharedStaticDestructor sharedStaticDestructor) {}
/** */void visit(SharedStaticDestructor sharedStaticDestructor) {} /** */ void visit(ShiftExpression shiftExpression) {}
/** */void visit(ShiftExpression shiftExpression) {} /** */ void visit(SingleImport singleImport) {}
/** */void visit(SingleImport singleImport) {} /** */ void visit(SliceExpression sliceExpression) {}
/** */void visit(SliceExpression sliceExpression) {} /** */ void visit(Statement statement) {}
/** */void visit(Statement statement) {} /** */ void visit(StatementNoCaseNoDefault statementNoCaseNoDefault) {}
/** */void visit(StatementNoCaseNoDefault statementNoCaseNoDefault) {} /** */ void visit(StaticAssertDeclaration staticAssertDeclaration) {}
/** */void visit(StaticAssertDeclaration staticAssertDeclaration) {} /** */ void visit(StaticAssertStatement staticAssertStatement) {}
/** */void visit(StaticAssertStatement staticAssertStatement) {} /** */ void visit(StaticConstructor staticConstructor) {}
/** */void visit(StaticConstructor staticConstructor) {} /** */ void visit(StaticDestructor staticDestructor) {}
/** */void visit(StaticDestructor staticDestructor) {} /** */ void visit(StaticIfCondition staticIfCondition) {}
/** */void visit(StaticIfCondition staticIfCondition) {} /** */ void visit(StorageClass storageClass) {}
/** */void visit(StorageClass storageClass) {} /** */ void visit(StructBody structBody) {}
/** */void visit(StructBody structBody) {} /** */ void visit(StructBodyItem structBodyItem) {}
/** */void visit(StructBodyItem structBodyItem) {} /** */ void visit(StructDeclaration structDeclaration) {}
/** */void visit(StructDeclaration structDeclaration) {} /** */ void visit(StructInitializer structInitializer) {}
/** */void visit(StructInitializer structInitializer) {} /** */ void visit(StructMemberInitializer structMemberInitializer) {}
/** */void visit(StructMemberInitializer structMemberInitializer) {} /** */ void visit(StructMemberInitializers structMemberInitializers) {}
/** */void visit(StructMemberInitializers structMemberInitializers) {} /** */ void visit(SwitchBody switchBody) {}
/** */void visit(SwitchBody switchBody) {} /** */ void visit(SwitchStatement switchStatement) {}
/** */void visit(SwitchStatement switchStatement) {} /** */ void visit(Symbol symbol) {}
/** */void visit(Symbol symbol) {} /** */ void visit(SynchronizedStatement synchronizedStatement) {}
/** */void visit(SynchronizedStatement synchronizedStatement) {} /** */ void visit(TemplateAliasParameter templateAliasParameter) {}
/** */void visit(TemplateAliasParameter templateAliasParameter) {} /** */ void visit(TemplateArgument templateArgument) {}
/** */void visit(TemplateArgument templateArgument) {} /** */ void visit(TemplateArgumentList templateArgumentList) {}
/** */void visit(TemplateArgumentList templateArgumentList) {} /** */ void visit(TemplateArguments templateArguments) {}
/** */void visit(TemplateArguments templateArguments) {} /** */ void visit(TemplateDeclaration templateDeclaration) {}
/** */void visit(TemplateDeclaration templateDeclaration) {} /** */ void visit(TemplateInstance templateInstance) {}
/** */void visit(TemplateInstance templateInstance) {} /** */ void visit(TemplateMixinStatement templateMixinStatement) {}
/** */void visit(TemplateMixinStatement templateMixinStatement) {} /** */ void visit(TemplateParameter templateParameter) {}
/** */void visit(TemplateParameter templateParameter) {} /** */ void visit(TemplateParameterList templateParameterList) {}
/** */void visit(TemplateParameterList templateParameterList) {} /** */ void visit(TemplateParameters templateParameters) {}
/** */void visit(TemplateParameters templateParameters) {} /** */ void visit(TemplateSingleArgument templateSingleArgument) {}
/** */void visit(TemplateSingleArgument templateSingleArgument) {} /** */ void visit(TemplateThisParameter templateThisParameter) {}
/** */void visit(TemplateThisParameter templateThisParameter) {} /** */ void visit(TemplateTupleParameter templateTupleParameter) {}
/** */void visit(TemplateTupleParameter templateTupleParameter) {} /** */ void visit(TemplateTypeParameter templateTypeParameter) {}
/** */void visit(TemplateTypeParameter templateTypeParameter) {} /** */ void visit(TemplateValueParameter templateValueParameter) {}
/** */void visit(TemplateValueParameter templateValueParameter) {} /** */ void visit(TemplateValueParameterDefault templateValueParameterDefault) {}
/** */void visit(TemplateValueParameterDefault templateValueParameterDefault) {} /** */ void visit(TernaryExpression ternaryExpression) {}
/** */void visit(TernaryExpression ternaryExpression) {} /** */ void visit(ThrowStatement throwStatement) {}
/** */void visit(ThrowStatement throwStatement) {} /** */ void visit(TraitsArgument traitsArgument) {}
/** */void visit(TraitsArgument traitsArgument) {} /** */ void visit(TraitsExpression traitsExpression) {}
/** */void visit(TraitsExpression traitsExpression) {} /** */ void visit(TryStatement tryStatement) {}
/** */void visit(TryStatement tryStatement) {} /** */ void visit(Type type) {}
/** */void visit(Type type) {} /** */ void visit(Type2 type2) {}
/** */void visit(Type2 type2) {} /** */ void visit(Type3 type3) {}
/** */void visit(Type3 type3) {} /** */ void visit(TypeConstructor typeConstructor) {}
/** */void visit(TypeConstructor typeConstructor) {} /** */ void visit(TypeConstructors typeConstructors) {}
/** */void visit(TypeConstructors typeConstructors) {} /** */ void visit(TypeSpecialization typeSpecialization) {}
/** */void visit(TypeSpecialization typeSpecialization) {} /** */ void visit(TypeSuffix typeSuffix) {}
/** */void visit(TypeSuffix typeSuffix) {} /** */ void visit(TypeidExpression typeidExpression) {}
/** */void visit(TypeidExpression typeidExpression) {} /** */ void visit(TypeofExpression typeofExpression) {}
/** */void visit(TypeofExpression typeofExpression) {} /** */ void visit(UnaryExpression unaryExpression) {}
/** */void visit(UnaryExpression unaryExpression) {} /** */ void visit(UnionDeclaration unionDeclaration) {}
/** */void visit(UnionDeclaration unionDeclaration) {} /** */ void visit(Unittest unittest_) {}
/** */void visit(Unittest unittest_) {} /** */ void visit(VariableDeclaration variableDeclaration) {}
/** */void visit(VariableDeclaration variableDeclaration) {} /** */ void visit(VersionCondition versionCondition) {}
/** */void visit(VersionCondition versionCondition) {} /** */ void visit(VersionSpecification versionSpecification) {}
/** */void visit(VersionSpecification versionSpecification) {} /** */ void visit(WhileStatement whileStatement) {}
/** */void visit(WhileStatement whileStatement) {} /** */ void visit(WithStatement withStatement) {}
/** */void visit(WithStatement withStatement) {} /** */ void visit(XorExpression xorExpression) {}
/** */void visit(XorExpression xorExpression) {}
} }
interface ASTNode interface ASTNode
@ -715,7 +714,7 @@ public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ Type type; /** */ Type type;
/** */ Token identifier; /** */ Token identifier;
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
} }
/// ///
@ -776,8 +775,8 @@ class ConditionalStatement : ASTNode
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */CompileCondition compileCondition; /** */CompileCondition compileCondition;
/** */NonEmptyStatementNoCaseNoDefault trueStatement; /** */StatementNoCaseNoDefault trueStatement;
/** */NonEmptyStatementNoCaseNoDefault falseStatement; /** */StatementNoCaseNoDefault falseStatement;
} }
/// ///
@ -993,7 +992,7 @@ class Finally : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
} }
/// ///
@ -1005,7 +1004,7 @@ public:
/** */ Statement initializationStatement; /** */ Statement initializationStatement;
/** */ Expression test; /** */ Expression test;
/** */ Expression increment; /** */ Expression increment;
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
} }
/// ///
@ -1016,7 +1015,7 @@ public:
/** */ ForeachType foreachType; /** */ ForeachType foreachType;
/** */ Expression lower; /** */ Expression lower;
/** */ Expression higher; /** */ Expression higher;
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
} }
/// ///
@ -1027,7 +1026,7 @@ public:
/** */ Token foreachType; /** */ Token foreachType;
/** */ ForeachTypeList foreachTypeList; /** */ ForeachTypeList foreachTypeList;
/** */ Expression expression; /** */ Expression expression;
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
} }
/// ///
@ -1142,7 +1141,7 @@ class IdentifierOrTemplateChain : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ IdentifierOrTemplateInstance[] identifiers; /** */ IdentifierOrTemplateInstance[] identifierOrTemplateInstances;
} }
/// ///
@ -1168,8 +1167,8 @@ class IfStatement : ASTNode
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ Expression expression; /** */ Expression expression;
/** */ NonEmptyStatementNoCaseNoDefault thenStatement; /** */ StatementNoCaseNoDefault thenStatement;
/** */ NonEmptyStatementNoCaseNoDefault elseStatement; /** */ StatementNoCaseNoDefault elseStatement;
} }
/// ///
@ -1179,6 +1178,7 @@ public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ Token left; /** */ Token left;
/** */ Token right; /** */ Token right;
/** */ bool hasRight;
} }
/// ///
@ -1186,8 +1186,8 @@ class ImportBindings : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ SingleImport bind; /** */ SingleImport singleImport;
/** */ ImportBind[] ImportBinds; /** */ ImportBind[] importBinds;
} }
/// ///
@ -1195,8 +1195,8 @@ class ImportDeclaration : Declaration
{ {
public: public:
mixin(OVERRIDE_DEFAULT_ACCEPT); mixin(OVERRIDE_DEFAULT_ACCEPT);
/** */ bool isStatic; /** */ SingleImport[] singleImports;
/** */ ImportList importList; /** */ ImportBindings importBindings;
} }
/// ///
@ -1247,7 +1247,7 @@ class Initialize : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
} }
/// ///
@ -1266,7 +1266,7 @@ public:
/** */ Token identifier; /** */ Token identifier;
/** */ TemplateParameters templateParameters; /** */ TemplateParameters templateParameters;
/** */ Constraint constraint; /** */ Constraint constraint;
/** */ IdentifierList identifierList; /** */ BaseClassList baseClassList;
/** */ StructBody structBody; /** */ StructBody structBody;
} }
@ -1333,7 +1333,7 @@ class LastCatch : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
} }
/// ///
@ -1437,14 +1437,14 @@ class NonEmptyStatement : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
/** */ CaseStatement caseStatement; /** */ CaseStatement caseStatement;
/** */ CaseRangeStatement caseRangeStatement; /** */ CaseRangeStatement caseRangeStatement;
/** */ DefaultStatement defaultStatement; /** */ DefaultStatement defaultStatement;
} }
/// ///
class NonEmptyStatementNoCaseNoDefault : ASTNode class StatementNoCaseNoDefault : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
@ -1668,7 +1668,7 @@ class ScopeGuardStatement : ASTNode
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ Token identifier; /** */ Token identifier;
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
} }
/// ///
@ -1702,8 +1702,8 @@ class SingleImport : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ Token rename; /** */ Token identifier;
/** */ IdentifierChain import_; /** */ IdentifierChain identifierChain;
} }
/// ///
@ -1720,15 +1720,10 @@ class Statement : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ NonEmptyStatement nonEmptyStatement; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
} /** */ CaseStatement caseStatement;
/** */ CaseRangeStatement caseRangeStatement;
/// /** */ DefaultStatement defaultStatement;
class StatementNoCaseNoDefault : ASTNode
{
public:
mixin(DEFAULT_ACCEPT);
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault;
} }
/// ///
@ -1868,7 +1863,7 @@ class SynchronizedStatement : ASTNode
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ Expression expression; /** */ Expression expression;
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
} }
/// ///
@ -2065,7 +2060,7 @@ class TryStatement : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ NonEmptyStatementNoCaseNoDefault nonEmptyStatementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
/** */ Catches catches; /** */ Catches catches;
/** */ Finally finally_; /** */ Finally finally_;
} }

View File

@ -1,6 +1,7 @@
// Written in the D programming language // Written in the D programming language
/** /**
* <script type="text/javascript">inhibitQuickIndex = 1</script>
* This module contains a _parser for D source code. * This module contains a _parser for D source code.
* *
* Grammar: * Grammar:
@ -21,9 +22,31 @@
* $(LI Rule definitions begin with the rule name followed by a colon (:). Rule * $(LI Rule definitions begin with the rule name followed by a colon (:). Rule
* definitions end with a semicolon (;).) * definitions end with a semicolon (;).)
* ) * )
*
* The grammar for D starts with the $(LINK2 #.module, module) rule.
*
* Examples: * Examples:
* --- * ---
* // TODO * import std.d.lexer;
* import std.d.parser;
* import std.d.ast;
* import std.array;
*
* string sourceCode = q{
* import std.stdio;
*
* void main()
* {
* writeln("Hello, World.");
* }
* }c;
* void main()
* {
* LexerConfig config;
* auto tokens = byToken(cast(ubyte[]) sourceCode, config).array();
* Module mod = parseModule(tokens);
* // Use module here...
* }
* --- * ---
* *
* Copyright: Brian Schott 2013 * Copyright: Brian Schott 2013
@ -33,7 +56,7 @@
* MACROS: * MACROS:
* GRAMMAR = $(D_CODE $0) * GRAMMAR = $(D_CODE $0)
* RULEDEF = $(DDOC_ANCHOR $0) $(B $0) * RULEDEF = $(DDOC_ANCHOR $0) $(B $0)
* RULE = $(LINK2 #$0, $(B $0)) * RULE = $(LINK2 #.$0, $(B $0))
* LITERAL = $(D_STRING $0) * LITERAL = $(D_STRING $0)
*/ */
@ -44,7 +67,9 @@ import std.d.ast;
import std.conv; import std.conv;
import std.algorithm; import std.algorithm;
import std.array; import std.array;
version(unittest) import std.stdio; version (unittest) import std.stdio;
version = development;
/** /**
* Params: * Params:
@ -1028,12 +1053,18 @@ struct Parser
case TokenType.const_: case TokenType.const_:
node.first = advance().type; node.first = advance().type;
if (currentIs(TokenType.shared_)) if (currentIs(TokenType.shared_))
{
node.hasSecond = true;
node.second = advance().type; node.second = advance().type;
}
break; break;
case TokenType.shared_: case TokenType.shared_:
node.first = advance().type; node.first = advance().type;
if (currentIsOneOf(TokenType.const_, TokenType.inout_)) if (currentIsOneOf(TokenType.const_, TokenType.inout_))
{
node.hasSecond = true;
node.second = advance().type; node.second = advance().type;
}
break; break;
case TokenType.immutable_: case TokenType.immutable_:
node.first = advance().type; node.first = advance().type;
@ -1045,6 +1076,73 @@ struct Parser
return node; return node;
} }
unittest
{
auto sourceCode = q{
const;
const shared;
immutable;
inout;
inout shared;
shared;
shared const;
shared inout;
incorrect;
};
Parser p = getParserForUnittest(sourceCode, "parseCastQualifier");
CastQualifier one = p.parseCastQualifier();
assert (one.first == TokenType.const_);
assert (!one.hasSecond);
p.expect(TokenType.semicolon);
CastQualifier two = p.parseCastQualifier();
assert (two.first == TokenType.const_);
assert (two.hasSecond);
assert (two.second == TokenType.shared_);
p.expect(TokenType.semicolon);
CastQualifier three = p.parseCastQualifier();
assert (three.first == TokenType.immutable_);
assert (!three.hasSecond);
p.expect(TokenType.semicolon);
CastQualifier four = p.parseCastQualifier();
assert (four.first == TokenType.inout_);
assert (!four.hasSecond);
p.expect(TokenType.semicolon);
CastQualifier five = p.parseCastQualifier();
assert (five.first == TokenType.inout_);
assert (five.hasSecond);
assert (five.second == TokenType.shared_);
p.expect(TokenType.semicolon);
CastQualifier six = p.parseCastQualifier();
assert (six.first == TokenType.shared_);
assert (!six.hasSecond);
p.expect(TokenType.semicolon);
CastQualifier seven = p.parseCastQualifier();
assert (seven.first == TokenType.shared_);
assert (seven.hasSecond);
assert (seven.second == TokenType.const_);
p.expect(TokenType.semicolon);
CastQualifier eight = p.parseCastQualifier();
assert (eight.first == TokenType.shared_);
assert (eight.hasSecond);
assert (eight.second == TokenType.inout_);
p.expect(TokenType.semicolon);
CastQualifier nine = p.parseCastQualifier();
assert (nine is null);
assert (p.errorCount > 0);
stderr.writeln("Unittest for parseCastQualifier() passed.");
}
/** /**
* Parses a Catch * Parses a Catch
* *
@ -1061,7 +1159,7 @@ struct Parser
if (currentIs(TokenType.identifier)) if (currentIs(TokenType.identifier))
node.identifier = advance(); node.identifier = advance();
expect(TokenType.rParen); expect(TokenType.rParen);
node.nonEmptyStatementNoCaseNoDefault = parseNonEmptyStatementNoCaseNoDefault(); node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
return node; return node;
} }
@ -1107,9 +1205,7 @@ struct Parser
{ {
auto node = new ClassBody; auto node = new ClassBody;
expect(TokenType.lBrace); expect(TokenType.lBrace);
while (!currentIs(TokenType.rBrace)) version (development) skipBraceContent();
//node.declarationOrInvariants ~= parseDeclarationOrInvariant();
advance();
expect(TokenType.rBrace); expect(TokenType.rBrace);
return node; return node;
} }
@ -1130,10 +1226,15 @@ struct Parser
{ {
node.templateParameters = parseTemplateParameters(); node.templateParameters = parseTemplateParameters();
if (currentIs(TokenType.if_)) if (currentIs(TokenType.if_))
{
node.constraint = parseConstraint(); node.constraint = parseConstraint();
} }
}
if (currentIs(TokenType.colon)) if (currentIs(TokenType.colon))
{
advance();
node.baseClassList = parseBaseClassList(); node.baseClassList = parseBaseClassList();
}
node.classBody = parseClassBody(); node.classBody = parseClassBody();
return node; return node;
} }
@ -1146,11 +1247,7 @@ class ClassTwo : Super {}
class ClassThree(A, B) : Super {} class ClassThree(A, B) : Super {}
class ClassFour(A, B) if (someTest()) : Super {}}; class ClassFour(A, B) if (someTest()) : Super {}};
LexerConfig config; Parser p = getParserForUnittest(sourceCode, "parseClassDeclaration");
auto r = byToken(cast(const(ubyte)[]) sourceCode, config);
Parser p;
p.fileName = "parseClassDeclaration.d";
p.tokens = r.array();
auto classOne = p.parseClassDeclaration(); auto classOne = p.parseClassDeclaration();
assert (classOne.name == "ClassOne"); assert (classOne.name == "ClassOne");
@ -1160,10 +1257,31 @@ class ClassFour(A, B) if (someTest()) : Super {}};
assert (classOne.templateParameters is null); assert (classOne.templateParameters is null);
auto classTwo = p.parseClassDeclaration(); auto classTwo = p.parseClassDeclaration();
assert (classOne.name == "ClassTwo"); assert (classTwo.name == "ClassTwo", classTwo.name.value);
assert (classOne.baseClassList !is null); assert (classTwo.baseClassList !is null);
assert (classOne.baseClassList.baseClasses.length == 1); assert (classTwo.baseClassList.baseClasses.length == 1,
assert (classOne.classBody.declarationOrInvariants.length == 0); to!string(classTwo.baseClassList.baseClasses.length));
assert (classTwo.classBody.declarationOrInvariants.length == 0,
to!string(classTwo.classBody.declarationOrInvariants.length));
auto classThree = p.parseClassDeclaration();
assert (classThree.name == "ClassThree", classThree.name.value);
assert (classThree.templateParameters !is null);
assert (classThree.baseClassList !is null);
assert (classThree.baseClassList.baseClasses.length == 1);
assert (classThree.classBody.declarationOrInvariants.length == 0,
to!string(classThree.classBody.declarationOrInvariants.length));
auto classFour = p.parseClassDeclaration();
assert (classFour.name == "ClassFour", classFour.name.value);
assert (classFour.templateParameters !is null);
assert (classFour.baseClassList !is null);
assert (classFour.constraint !is null);
assert (classFour.baseClassList.baseClasses.length == 1);
assert (classFour.classBody.declarationOrInvariants.length == 0,
to!string(classFour.classBody.declarationOrInvariants.length));
stderr.writeln("Unittest for parseClassDeclaration() passed.");
} }
/** /**
@ -1254,6 +1372,9 @@ class ClassFour(A, B) if (someTest()) : Super {}};
auto node = new Constraint; auto node = new Constraint;
expect(TokenType.if_); expect(TokenType.if_);
expect(TokenType.lParen); expect(TokenType.lParen);
version (development)
skipParenContent();
else
node.expression = parseExpression(); node.expression = parseExpression();
expect(TokenType.rParen); expect(TokenType.rParen);
return node; return node;
@ -1853,10 +1974,76 @@ class ClassFour(A, B) if (someTest()) : Super {}};
FunctionBody parseFunctionBody() FunctionBody parseFunctionBody()
{ {
auto node = new FunctionBody; auto node = new FunctionBody;
// TODO if (currentIs(TokenType.lBrace))
node.blockStatement = parseBlockStatement();
else
{
if (currentIs(TokenType.in_))
{
node.inStatement = parseInStatement();
if (currentIs(TokenType.out_))
node.outStatement = parseOutStatement();
}
else if (currentIs(TokenType.out_))
{
node.outStatement = parseOutStatement();
if (currentIs(TokenType.in_))
node.inStatement = parseInStatement();
}
node.bodyStatement = parseBodyStatement();
}
return node; return node;
} }
unittest
{
auto sourceCode = q{
{} // one
in {} body{} // two
out {} body{} // three
in {} out {} body {} // four
out {} in {} body {} // five
body {} // six
};
Parser p = getParserForUnittest(sourceCode, "parseFunctionBody");
FunctionBody functionBodyOne = p.parseFunctionBody();
assert (functionBodyOne.blockStatement !is null);
FunctionBody functionBodyTwo = p.parseFunctionBody();
assert (functionBodyTwo.blockStatement is null);
assert (functionBodyTwo.inStatement !is null);
assert (functionBodyTwo.outStatement is null);
assert (functionBodyTwo.bodyStatement !is null);
FunctionBody functionBodyThree = p.parseFunctionBody();
assert (functionBodyThree.blockStatement is null);
assert (functionBodyThree.inStatement is null);
assert (functionBodyThree.outStatement !is null);
assert (functionBodyThree.bodyStatement !is null);
FunctionBody functionBodyFour = p.parseFunctionBody();
assert (functionBodyFour.blockStatement is null);
assert (functionBodyFour.inStatement !is null);
assert (functionBodyFour.outStatement !is null);
assert (functionBodyFour.bodyStatement !is null);
FunctionBody functionBodyFive = p.parseFunctionBody();
assert (functionBodyFive.blockStatement is null);
assert (functionBodyFive.inStatement !is null);
assert (functionBodyFive.outStatement !is null);
assert (functionBodyFive.bodyStatement !is null);
FunctionBody functionBodySix = p.parseFunctionBody();
assert (functionBodySix.blockStatement is null);
assert (functionBodySix.inStatement is null);
assert (functionBodySix.outStatement is null);
assert (functionBodySix.bodyStatement !is null);
stderr.writeln("Unittest for parseFunctionBody() passed.");
}
/** /**
* Parses a FunctionCallExpression * Parses a FunctionCallExpression
* *
@ -1998,7 +2185,12 @@ class ClassFour(A, B) if (someTest()) : Super {}};
IdentifierOrTemplateChain parseIdentifierOrTemplateChain() IdentifierOrTemplateChain parseIdentifierOrTemplateChain()
{ {
auto node = new IdentifierOrTemplateChain; auto node = new IdentifierOrTemplateChain;
// TODO while (true)
{
node.identifierOrTemplateInstances ~= parseIdentifierOrTemplateInstance();
if (!currentIs(TokenType.dot))
break;
}
return node; return node;
} }
@ -2013,7 +2205,10 @@ class ClassFour(A, B) if (someTest()) : Super {}};
IdentifierOrTemplateInstance parseIdentifierOrTemplateInstance() IdentifierOrTemplateInstance parseIdentifierOrTemplateInstance()
{ {
auto node = new IdentifierOrTemplateInstance; auto node = new IdentifierOrTemplateInstance;
// TODO if (peekIs(TokenType.not))
node.templateInstance = parseTemplateInstance();
else
node.identifier = *expect(TokenType.identifier);
return node; return node;
} }
@ -2055,21 +2250,43 @@ class ClassFour(A, B) if (someTest()) : Super {}};
ImportBind parseImportBind() ImportBind parseImportBind()
{ {
auto node = new ImportBind; auto node = new ImportBind;
// TODO if (!currentIs(TokenType.identifier))
{
error("Identifier expected.");
return null;
}
if (peekIs(TokenType.assign))
{
node.left = advance();
advance();
node.hasRight = true;
node.right = *expect(TokenType.identifier);
}
else
node.left = advance();
return node; return node;
} }
/** /**
* Parses an ImportBindings * Parses ImportBindings
* *
* $(GRAMMAR $(RULEDEF importBindings): * $(GRAMMAR $(RULEDEF importBindings):
* $(RULE singleImport) $(LITERAL ':') $(RULE importBind) ($(LITERAL ',') $(RULE importBind))* * $(RULE singleImport) $(LITERAL ':') $(RULE importBind) ($(LITERAL ',') $(RULE importBind))*
* ;) * ;)
*/ */
ImportBindings parseImportBindings() ImportBindings parseImportBindings(SingleImport singleImport)
{ {
auto node = new ImportBindings; auto node = new ImportBindings;
// TODO node.singleImport = singleImport is null ? parseSingleImport() : singleImport;
expect(TokenType.colon);
while (true)
{
node.importBinds ~= parseImportBind();
if (moreTokens() && currentIs(TokenType.comma))
advance();
else
break;
}
return node; return node;
} }
@ -2077,16 +2294,82 @@ class ClassFour(A, B) if (someTest()) : Super {}};
* Parses an ImportDeclaration * Parses an ImportDeclaration
* *
* $(GRAMMAR $(RULEDEF importDeclaration): * $(GRAMMAR $(RULEDEF importDeclaration):
* $(LITERAL 'static')? $(LITERAL 'import') $(RULE importList) $(LITERAL ';') * $(LITERAL 'import') ($(RULE singleImport) ($(LITERAL ',') $(RULE singleImport))* | $(RULE importBindings)) $(LITERAL ';')
* ;) * ;)
*/ */
ImportDeclaration parseImportDeclaration() ImportDeclaration parseImportDeclaration()
{ {
auto node = new ImportDeclaration; auto node = new ImportDeclaration;
// TODO expect(TokenType.import_);
SingleImport si = parseSingleImport();
if (currentIs(TokenType.colon))
node.importBindings = parseImportBindings(si);
else
{
node.singleImports ~= si;
if (currentIs(TokenType.comma))
{
advance();
while (true)
{
node.singleImports ~= parseSingleImport();
if (moreTokens() && currentIs(TokenType.comma))
advance();
else
break;
}
}
}
expect(TokenType.semicolon);
return node; return node;
} }
unittest
{
auto sourceCode =
q{import std.stdio;
import foo, bar;
import io = std.stdio;
import std.stdio: writefln, foo = writef;
import io = std.stdio : foo = writefln;
import foo, bar, baz;
}c;
Parser p = getParserForUnittest(sourceCode, "parseImportDeclaration");
ImportDeclaration one = p.parseImportDeclaration();
assert (one !is null);
assert (one.singleImports.length == 1);
assert (p.errorCount == 0);
ImportDeclaration two = p.parseImportDeclaration();
assert (two !is null);
assert (two.singleImports.length == 2);
assert (p.errorCount == 0);
ImportDeclaration three = p.parseImportDeclaration();
assert (three !is null);
assert (three.singleImports.length == 1);
assert (p.errorCount == 0);
ImportDeclaration four = p.parseImportDeclaration();
assert (four !is null);
assert (four.importBindings !is null);
assert (four.importBindings.importBinds.length == 2);
assert (p.errorCount == 0);
ImportDeclaration five = p.parseImportDeclaration();
assert (five !is null);
assert (p.errorCount == 0);
ImportDeclaration six = p.parseImportDeclaration();
assert (six !is null);
assert (six.singleImports.length == 3);
assert (p.errorCount == 0);
stderr.writeln("Unittest for parseImportDeclaration() passed.");
}
/** /**
* Parses an ImportExpression * Parses an ImportExpression
* *
@ -2097,21 +2380,10 @@ class ClassFour(A, B) if (someTest()) : Super {}};
ImportExpression parseImportExpression() ImportExpression parseImportExpression()
{ {
auto node = new ImportExpression; auto node = new ImportExpression;
// TODO expect(TokenType.import_);
return node; expect(TokenType.lParen);
} node.assignExpression = parseAssignExpression();
expect(TokenType.rParen);
/**
* Parses an ImportList
*
* $(GRAMMAR $(RULEDEF importList): $(RULE singleImport) ($(LITERAL ',') $(RULE importList))?
* | $(RULE importBindings)
* ;)
*/
ImportList parseImportList()
{
auto node = new ImportList;
// TODO
return node; return node;
} }
@ -2122,10 +2394,13 @@ class ClassFour(A, B) if (someTest()) : Super {}};
* $(RULE unaryExpression) $(LITERAL '[') $(RULE argumentList) $(LITERAL ']') * $(RULE unaryExpression) $(LITERAL '[') $(RULE argumentList) $(LITERAL ']')
* ;) * ;)
*/ */
IndexExpression parseImportList() IndexExpression parseIndexExpression(UnaryExpression unaryExpression = null)
{ {
auto node = new IndexExpression; auto node = new IndexExpression;
// TODO node.unaryExpression = unaryExpression is null ? parseUnaryExpression() : unaryExpression;
if (expect(TokenType.lBracket) is null) return null;
node.argumentList = parseArgumentList();
if (expect(TokenType.rBracket) is null) return null;
return node; return node;
} }
@ -2153,7 +2428,8 @@ class ClassFour(A, B) if (someTest()) : Super {}};
InStatement parseInStatement() InStatement parseInStatement()
{ {
auto node = new InStatement; auto node = new InStatement;
// TODO expect(TokenType.in_);
node.blockStatement = parseBlockStatement();
return node; return node;
} }
@ -2162,7 +2438,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
* *
* $(GRAMMAR $(RULEDEF initialize): * $(GRAMMAR $(RULEDEF initialize):
* $(LITERAL ';') * $(LITERAL ';')
* | $(RULE nonEmptyStatementNoCaseNoDefault) * | $(RULE statementNoCaseNoDefault)
* ;) * ;)
*/ */
Initialize parseInitialize() Initialize parseInitialize()
@ -2183,7 +2459,10 @@ class ClassFour(A, B) if (someTest()) : Super {}};
Initializer parseInitializer() Initializer parseInitializer()
{ {
auto node = new Initializer; auto node = new Initializer;
// TODO if (currentIs(TokenType.void_))
advance();
else
node.nonVoidInitializer = parseNonVoidInitializer();
return node; return node;
} }
@ -2197,9 +2476,73 @@ class ClassFour(A, B) if (someTest()) : Super {}};
InterfaceDeclaration parseInterfaceDeclaration() InterfaceDeclaration parseInterfaceDeclaration()
{ {
auto node = new InterfaceDeclaration; auto node = new InterfaceDeclaration;
expect(TokenType.interface_);
if (!currentIs(TokenType.identifier))
{
error("Identifier expected");
return null;
}
node.identifier = advance();
if (currentIs(TokenType.lParen))
{
node.templateParameters = parseTemplateParameters();
if (currentIs(TokenType.if_))
node.constraint = parseConstraint();
}
if (currentIs(TokenType.colon))
{
advance();
node.baseClassList = parseBaseClassList();
}
node.structBody = parseStructBody();
return node; return node;
} }
unittest
{
auto sourceCode =
q{interface One {}
interface Two : Number {}
interface Three(T) if (someTest(T)) {}
interface "Four"
}c;
Parser p = getParserForUnittest(sourceCode, "parseInterfaceDeclaration");
InterfaceDeclaration one = p.parseInterfaceDeclaration();
assert (one !is null);
assert (one.identifier == "One");
assert (one.constraint is null);
assert (one.templateParameters is null);
assert (one.structBody !is null);
assert (one.baseClassList is null);
assert (p.errorCount == 0);
InterfaceDeclaration two = p.parseInterfaceDeclaration();
assert (two !is null);
assert (two.identifier == "Two");
assert (two.constraint is null);
assert (two.templateParameters is null);
assert (two.structBody !is null);
assert (two.baseClassList !is null);
assert (p.errorCount == 0);
InterfaceDeclaration three = p.parseInterfaceDeclaration();
assert (three !is null);
assert (three.identifier == "Three");
assert (three.constraint !is null);
assert (three.templateParameters !is null);
assert (three.structBody !is null);
assert (three.baseClassList is null);
assert (p.errorCount == 0);
InterfaceDeclaration four = p.parseInterfaceDeclaration();
assert (four is null);
assert (p.errorCount > 0);
stderr.writeln("Unittest for parseInterfaceDeclaration() passed.");
}
/** /**
* Parses an Invariant * Parses an Invariant
* *
@ -2446,7 +2789,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
} }
/** /**
* Parses an NewAnonClassExpression * Parses a NewAnonClassExpression
* *
* $(GRAMMAR $(RULEDEF newAnonClassExpression): * $(GRAMMAR $(RULEDEF newAnonClassExpression):
* $(LITERAL 'new') $(RULE arguments)? $(LITERAL 'class') $(RULE arguments)? $(LITERAL Identifier) $(RULE identifierList)? $(RULE classBody) * $(LITERAL 'new') $(RULE arguments)? $(LITERAL 'class') $(RULE arguments)? $(LITERAL Identifier) $(RULE identifierList)? $(RULE classBody)
@ -2460,7 +2803,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
} }
/** /**
* Parses an NewExpression * Parses a NewExpression
* *
* $(GRAMMAR $(RULEDEF newExpression): * $(GRAMMAR $(RULEDEF newExpression):
* $(LITERAL 'new') $(RULE type) ($(LITERAL '[') $(RULE assignExpression) $(LITERAL ']') | $(RULE arguments))? * $(LITERAL 'new') $(RULE type) ($(LITERAL '[') $(RULE assignExpression) $(LITERAL ']') | $(RULE arguments))?
@ -2475,7 +2818,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
} }
/** /**
* Parses an NonEmptyStatement * Parses a NonEmptyStatement
* *
* $(GRAMMAR $(RULEDEF nonEmptyStatement): * $(GRAMMAR $(RULEDEF nonEmptyStatement):
* $(RULE nonEmptyStatementNoCaseNoDefault) * $(RULE nonEmptyStatementNoCaseNoDefault)
@ -2491,9 +2834,9 @@ class ClassFour(A, B) if (someTest()) : Super {}};
} }
/** /**
* Parses an NonEmptyStatementNoCaseNoDefault * Parses a StatementNoCaseNoDefault
* *
* $(GRAMMAR $(RULEDEF nonEmptyStatementNoCaseNoDefault): * $(GRAMMAR $(RULEDEF statementNoCaseNoDefault):
* $(RULE labeledStatement) * $(RULE labeledStatement)
* | $(RULE blockStatement) * | $(RULE blockStatement)
* | $(RULE assignStatement) * | $(RULE assignStatement)
@ -2525,9 +2868,9 @@ class ClassFour(A, B) if (someTest()) : Super {}};
* | $(RULE deleteStatement) * | $(RULE deleteStatement)
* ;) * ;)
*/ */
NonEmptyStatementNoCaseNoDefault parseNonEmptyStatementNoCaseNoDefault() StatementNoCaseNoDefault parseStatementNoCaseNoDefault()
{ {
auto node = new NonEmptyStatementNoCaseNoDefault; auto node = new StatementNoCaseNoDefault;
// TODO // TODO
return node; return node;
} }
@ -2921,7 +3264,17 @@ class ClassFour(A, B) if (someTest()) : Super {}};
SingleImport parseSingleImport() SingleImport parseSingleImport()
{ {
auto node = new SingleImport; auto node = new SingleImport;
// TODO if (!currentIs(TokenType.identifier))
{
error("Identifier expected");
return null;
}
if (peekIs(TokenType.assign))
{
node.identifier = advance();
advance();
}
node.identifierChain = parseIdentifierChain();
return node; return node;
} }
@ -2929,35 +3282,27 @@ class ClassFour(A, B) if (someTest()) : Super {}};
* Parses a Statement * Parses a Statement
* *
* $(GRAMMAR $(RULEDEF statement): * $(GRAMMAR $(RULEDEF statement):
* $(LITERAL ';') * $(RULE statementNoCaseNoDefault)
* | $(RULE nonEmptyStatement) * | $(RULE caseStatement)
* | $(RULE caseRangeStatement)
* | $(RULE defaultStatement)
* ;) * ;)
*/ */
Statement parseStatement() Statement parseStatement()
{ {
auto node = new Statement; auto node = new Statement;
if (currentIs(TokenType.semicolon)) switch (current().type)
advance();
else
node.nonEmptyStatement = parseNonEmptyStatement();
return node;
}
/**
* Parses a StatementNoCaseNoDefault
*
* $(GRAMMAR $(RULEDEF statementNoCaseNoDefault):
* $(LITERAL ';')
* | $(RULE nonEmptyStatementNoCaseNoDefault)
* ;)
*/
StatementNoCaseNoDefault parseStatementNoCaseNoDefault()
{ {
auto node = new StatementNoCaseNoDefault; case TokenType.case_:
if (tokens[index] != TokenType.semicolon) // TODO
node.nonEmptyStatementNoCaseNoDefault = parseNonEmptyStatementNoCaseNoDefault(); break;
else case TokenType.default_:
expect(TokenType.semicolon); node.defaultStatement = parseDefaultStatement();
break;
default:
node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
break;
}
return node; return node;
} }
@ -3259,7 +3604,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
node.expression = parseExpression(); node.expression = parseExpression();
expect(TokenType.rParen); expect(TokenType.rParen);
} }
node.nonEmptyStatementNoCaseNoDefault = parseNonEmptyStatementNoCaseNoDefault(); node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
return node; return node;
} }
@ -3405,7 +3750,10 @@ class ClassFour(A, B) if (someTest()) : Super {}};
TemplateParameters parseTemplateParameters() TemplateParameters parseTemplateParameters()
{ {
auto node = new TemplateParameters; auto node = new TemplateParameters;
expect(TokenType.lParen);
// TODO // TODO
version (development) skipParenContent();
expect(TokenType.rParen);
return node; return node;
} }
@ -3568,13 +3916,22 @@ class ClassFour(A, B) if (someTest()) : Super {}};
* Parses an TraitsExpression * Parses an TraitsExpression
* *
* $(GRAMMAR $(RULEDEF traitsExpression): * $(GRAMMAR $(RULEDEF traitsExpression):
* $(LITERAL '__traits') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) $(LITERAL ',') $(RULE traitsArgument) ($(LITERAL ',') $(RULE traitsArgument))* $(LITERAL '$(RPAREN)') * $(LITERAL '__traits') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) ($(LITERAL ',') $(RULE traitsArgument))+ $(LITERAL '$(RPAREN)')
* ;) * ;)
*/ */
TraitsExpression parseTraitsExpression() TraitsExpression parseTraitsExpression()
{ {
auto node = new TraitsExpression; auto node = new TraitsExpression;
// TODO expect(TokenType.traits);
expect(TokenType.lParen);
node.identifier = *expect(TokenType.identifier);
do
{
expect(TokenType.comma);
node.traitsArguments ~= parseTraitsArgument();
}
while (moreTokens() && currentIs(TokenType.comma));
expect(TokenType.rParen);
return node; return node;
} }
@ -3588,7 +3945,12 @@ class ClassFour(A, B) if (someTest()) : Super {}};
TryStatement parseTryStatement() TryStatement parseTryStatement()
{ {
auto node = new TryStatement; auto node = new TryStatement;
// TODO expect(TokenType.try_);
node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
if (currentIs(TokenType.catch_))
node.catches = parseCatches();
if (currentIs(TokenType.finally_))
node.finally_ = parseFinally();
return node; return node;
} }
@ -3974,7 +4336,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
expect(TokenType.lParen); expect(TokenType.lParen);
// TODO: magic here // TODO: magic here
expect(TokenType.rParen); expect(TokenType.rParen);
parseNonEmptyStatementNoCaseNoDefault(); parseStatementNoCaseNoDefault();
return node; return node;
} }
@ -4008,6 +4370,46 @@ class ClassFour(A, B) if (someTest()) : Super {}};
} }
} }
void skipContent(alias O, alias C)()
{
int depth = 1;
while (moreTokens())
{
switch (tokens[index].type)
{
case O:
depth++;
advance();
break;
case C:
depth--;
if (depth <= 0)
return;
else
advance();
break;
default:
advance();
break;
}
}
}
void skipBraceContent()
{
skipContent!(TokenType.lBrace, TokenType.rBrace)();
}
void skipParenContent()
{
skipContent!(TokenType.lParen, TokenType.rParen)();
}
void skipBracketContent()
{
skipContent!(TokenType.lBracket, TokenType.rBracket)();
}
const(Token)* peekPast(alias O, alias C)() const(Token)* peekPast(alias O, alias C)()
in in
{ {
@ -4126,6 +4528,17 @@ class ClassFour(A, B) if (someTest()) : Super {}};
return index < tokens.length; return index < tokens.length;
} }
version (unittest) static Parser getParserForUnittest(string sourceCode,
string testName)
{
LexerConfig config;
auto r = byToken(cast(const(ubyte)[]) sourceCode, config);
Parser p;
p.fileName = testName ~ ".d";
p.tokens = r.array();
return p;
}
uint errorCount; uint errorCount;
const(Token)[] tokens; const(Token)[] tokens;
size_t index; size_t index;