From 6dc1e4c2ff65d158b46b08b5638bfe9f2bd5b1ba Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Mon, 10 Jun 2013 09:30:02 +0000 Subject: [PATCH] Can now actually parse some basic code --- std/d/ast.d | 499 +++++++++++++++++++++++++------------------------ std/d/lexer.d | 2 +- std/d/parser.d | 336 +++++++++++++++++++++++++-------- std/d/tester.d | 50 +++++ 4 files changed, 566 insertions(+), 321 deletions(-) create mode 100644 std/d/tester.d diff --git a/std/d/ast.d b/std/d/ast.d index 019ac92..348093f 100755 --- a/std/d/ast.d +++ b/std/d/ast.d @@ -23,217 +23,214 @@ import std.d.lexer; * for the various AST /// classes */ -abstract /// -class ASTVisitor +abstract class ASTVisitor { - /** */ void visit(AddExpression addExpression) {} - /** */ void visit(AliasDeclaration aliasDeclaration) {} - /** */ void visit(AliasInitializer aliasInitializer) {} - /** */ void visit(AliasThisDeclaration aliasThisDeclaration) {} - /** */ void visit(AlignAttribute alignAttribute) {} - /** */ void visit(AndAndExpression andAndExpression) {} - /** */ void visit(AndExpression andExpression) {} - /** */ void visit(ArgumentList argumentList) {} - /** */ void visit(Arguments arguments) {} - /** */ void visit(ArrayInitializer arrayInitializer) {} - /** */ void visit(ArrayLiteral arrayLiteral) {} - /** */ void visit(ArrayMemberInitialization arrayMemberInitialization) {} - /** */ void visit(AsmAddExp asmAddExp) {} - /** */ void visit(AsmAndExp asmAndExp) {} - /** */ void visit(AsmBrExp asmBrExp) {} - /** */ void visit(AsmEqualExp asmEqualExp) {} - /** */ void visit(AsmExp asmExp) {} - /** */ void visit(AsmInstruction asmInstruction) {} - /** */ void visit(AsmLogAndExp asmLogAndExp) {} - /** */ void visit(AsmLogOrExp asmLogOrExp) {} - /** */ void visit(AsmMulExp asmMulExp) {} - /** */ void visit(AsmOrExp asmOrExp) {} - /** */ void visit(AsmPrimaryExp asmPrimaryExp) {} - /** */ void visit(AsmRelExp asmRelExp) {} - /** */ void visit(AsmShiftExp asmShiftExp) {} - /** */ void visit(AsmStatement asmStatement) {} - /** */ void visit(AsmTypePrefix asmTypePrefix) {} - /** */ void visit(AsmUnaExp asmUnaExp) {} - /** */ void visit(AsmXorExp asmXorExp) {} - /** */ void visit(AssertExpression assertExpression) {} - /** */ void visit(AssertStatement assertStatement) {} - /** */ void visit(AssignExpression assignExpression) {} - /** */ void visit(AssignStatement assignStatement) {} - /** */ void visit(AssocArrayLiteral assocArrayLiteral) {} - /** */ void visit(AtAttribute atAttribute) {} - /** */ void visit(Attribute attribute) {} - /** */ void visit(AttributedDeclaration attributedDeclaration) {} - /** */ void visit(AutoDeclaration autoDeclaration) {} - /** */ void visit(BlockStatement blockStatement) {} - /** */ void visit(BodyStatement bodyStatement) {} - /** */ void visit(BreakStatement breakStatement) {} - /** */ void visit(BaseClass baseClass) {} - /** */ void visit(BaseClassList baseClassList) {} - /** */ void visit(BasicType builtinType) {} - /** */ void visit(CaseRangeStatement caseRangeStatement) {} - /** */ void visit(CaseStatement caseStatement) {} - /** */ void visit(CastExpression castExpression) {} - /** */ void visit(CastQualifier castQualifier) {} - /** */ void visit(Catch catch_) {} - /** */ void visit(Catches catches) {} - /** */ void visit(ClassBody classBody) {} - /** */ void visit(ClassDeclaration classDeclaration) {} - /** */ void visit(CmpExpression cmpExpression) {} - /** */ void visit(CompileCondition compileCondition) {} - /** */ void visit(ConditionalDeclaration conditionalDeclaration) {} - /** */ void visit(ConditionalStatement conditionalStatement) {} - /** */ void visit(Constraint constraint) {} - /** */ void visit(Constructor constructor) {} - /** */ void visit(ContinueStatement continueStatement) {} - /** */ void visit(DebugCondition debugCondition) {} - /** */ void visit(DebugSpecification debugSpecification) {} - /** */ void visit(Declaration declaration) {} - /** */ void visit(DeclarationsAndStatements declarationsAndStatements) {} - /** */ void visit(DeclarationOrInvariant declarationOrInvariant) {} - /** */ void visit(Declarator declarator) {} - /** */ void visit(DeclaratorSuffix declaratorSuffix) {} - /** */ void visit(DefaultStatement defaultStatement) {} - /** */ void visit(DeleteExpression deleteExpression) {} - /** */ void visit(DeleteStatement deleteStatement) {} - /** */ void visit(Deprecated deprecated_) {} - /** */ void visit(Destructor destructor) {} - /** */ void visit(DoStatement doStatement) {} - /** */ void visit(EnumBody enumBody) {} - /** */ void visit(EnumDeclaration enumDeclaration) {} - /** */ void visit(EnumMember enumMember) {} - /** */ void visit(EqualExpression equalExpression) {} - /** */ void visit(Expression expression) {} - /** */ void visit(FinalSwitchStatement finalSwitchStatement) {} - /** */ void visit(Finally finally_) {} - /** */ void visit(ForStatement forStatement) {} - /** */ void visit(ForeachRangeStatement foreachRangeStatement) {} - /** */ void visit(ForeachStatement foreachStatement) {} - /** */ void visit(ForeachType foreachType) {} - /** */ void visit(ForeachTypeList foreachTypeList) {} - /** */ void visit(FunctionAttribute functionAttribute) {} - /** */ void visit(FunctionBody functionBody) {} - /** */ void visit(FunctionCallExpression functionCallExpression) {} - /** */ void visit(FunctionCallStatement functionCallStatement) {} - /** */ void visit(FunctionDeclaration functionDeclaration) {} - /** */ void visit(FunctionLiteralExpression functionLiteralExpression) {} - /** */ void visit(GotoStatement gotoStatement) {} - /** */ void visit(IdentifierChain identifierChain) {} - /** */ void visit(IdentifierList identifierList) {} - /** */ void visit(IdentifierOrTemplateChain identifierOrTemplateChain) {} - /** */ void visit(IdentifierOrTemplateInstance identifierOrTemplateInstance) {} - /** */ void visit(IdentityExpression identityExpression) {} - /** */ void visit(IfStatement ifStatement) {} - /** */ void visit(ImportBind importBind) {} - /** */ void visit(ImportBindings importBindings) {} - /** */ void visit(ImportDeclaration importDeclaration) {} - /** */ void visit(ImportExpression importExpression) {} - /** */ void visit(ImportList importList) {} - /** */ void visit(IndexExpression indexExpression) {} - /** */ void visit(InExpression inExpression) {} - /** */ void visit(InStatement inStatement) {} - /** */ void visit(Initialize initialize) {} - /** */ void visit(Initializer initializer) {} - /** */ void visit(InterfaceDeclaration interfaceDeclaration) {} - /** */ void visit(Invariant invariant_) {} - /** */ void visit(IsExpression isExpression) {} - /** */ void visit(KeyValuePair keyValuePair) {} - /** */ void visit(KeyValuePairs keyValuePairs) {} - /** */ void visit(LabeledStatement labeledStatement) {} - /** */ void visit(LambdaExpression lambdaExpression) {} - /** */ void visit(LastCatch lastCatch) {} - /** */ void visit(LinkageAttribute linkageAttribute) {} - /** */ void visit(MemberFunctionAttribute memberFunctionAttribute) {} - /** */ void visit(MixinDeclaration mixinDeclaration) {} - /** */ void visit(MixinExpression mixinExpression) {} - /** */ void visit(MixinTemplateName mixinTemplateName) {} - /** */ void visit(Module module_) {} - /** */ void visit(ModuleDeclaration moduleDeclaration) {} - /** */ void visit(MulExpression mulExpression) {} - /** */ void visit(NewAnonClassExpression newAnonClassExpression) {} - /** */ void visit(NewExpression newExpression) {} - /** */ void visit(NonEmptyStatement nonEmptyStatement) {} - /** */ void visit(NonVoidInitializer nonVoidInitializer) {} - /** */ void visit(Operand operand) {} - /** */ void visit(Operands operands) {} - /** */ void visit(OrExpression orExpression) {} - /** */ void visit(OrOrExpression orOrExpression) {} - /** */ void visit(OutStatement outStatement) {} - /** */ void visit(Parameter parameter) {} - /** */ void visit(ParameterAttribute parameterAttribute) {} - /** */ void visit(Parameters parameters) {} - /** */ void visit(Postblit postblit) {} - /** */ void visit(PostIncDecExpression postIncDecExpression) {} - /** */ void visit(PowExpression powExpression) {} - /** */ void visit(PragmaDeclaration pragmaDeclaration) {} - /** */ void visit(PragmaExpression pragmaExpression) {} - /** */ void visit(PreIncDecExpression preIncDecExpression) {} - /** */ void visit(PrimaryExpression primaryExpression) {} - /** */ void visit(Register register) {} - /** */ void visit(RelExpression relExpression) {} - /** */ void visit(ReturnStatement returnStatement) {} - /** */ void visit(ScopeGuardStatement scopeGuardStatement) {} - /** */ void visit(SharedStaticConstructor sharedStaticConstructor) {} - /** */ void visit(SharedStaticDestructor sharedStaticDestructor) {} - /** */ void visit(ShiftExpression shiftExpression) {} - /** */ void visit(SingleImport singleImport) {} - /** */ void visit(SliceExpression sliceExpression) {} - /** */ void visit(Statement statement) {} - /** */ void visit(StatementNoCaseNoDefault statementNoCaseNoDefault) {} - /** */ void visit(StaticAssertDeclaration staticAssertDeclaration) {} - /** */ void visit(StaticAssertStatement staticAssertStatement) {} - /** */ void visit(StaticConstructor staticConstructor) {} - /** */ void visit(StaticDestructor staticDestructor) {} - /** */ void visit(StaticIfCondition staticIfCondition) {} - /** */ void visit(StorageClass storageClass) {} - /** */ void visit(StructBody structBody) {} - /** */ void visit(StructBodyItem structBodyItem) {} - /** */ void visit(StructDeclaration structDeclaration) {} - /** */ void visit(StructInitializer structInitializer) {} - /** */ void visit(StructMemberInitializer structMemberInitializer) {} - /** */ void visit(StructMemberInitializers structMemberInitializers) {} - /** */ void visit(SwitchBody switchBody) {} - /** */ void visit(SwitchStatement switchStatement) {} - /** */ void visit(Symbol symbol) {} - /** */ void visit(SynchronizedStatement synchronizedStatement) {} - /** */ void visit(TemplateAliasParameter templateAliasParameter) {} - /** */ void visit(TemplateArgument templateArgument) {} - /** */ void visit(TemplateArgumentList templateArgumentList) {} - /** */ void visit(TemplateArguments templateArguments) {} - /** */ void visit(TemplateDeclaration templateDeclaration) {} - /** */ void visit(TemplateInstance templateInstance) {} - /** */ void visit(TemplateMixinStatement templateMixinStatement) {} - /** */ void visit(TemplateParameter templateParameter) {} - /** */ void visit(TemplateParameterList templateParameterList) {} - /** */ void visit(TemplateParameters templateParameters) {} - /** */ void visit(TemplateSingleArgument templateSingleArgument) {} - /** */ void visit(TemplateThisParameter templateThisParameter) {} - /** */ void visit(TemplateTupleParameter templateTupleParameter) {} - /** */ void visit(TemplateTypeParameter templateTypeParameter) {} - /** */ void visit(TemplateValueParameter templateValueParameter) {} - /** */ void visit(TemplateValueParameterDefault templateValueParameterDefault) {} - /** */ void visit(TernaryExpression ternaryExpression) {} - /** */ void visit(ThrowStatement throwStatement) {} - /** */ void visit(TraitsArgument traitsArgument) {} - /** */ void visit(TraitsExpression traitsExpression) {} - /** */ void visit(TryStatement tryStatement) {} - /** */ void visit(Type type) {} - /** */ void visit(Type2 type2) {} - /** */ void visit(Type3 type3) {} - /** */ void visit(TypeConstructor typeConstructor) {} - /** */ void visit(TypeConstructors typeConstructors) {} - /** */ void visit(TypeSpecialization typeSpecialization) {} - /** */ void visit(TypeSuffix typeSuffix) {} - /** */ void visit(TypeidExpression typeidExpression) {} - /** */ void visit(TypeofExpression typeofExpression) {} - /** */ void visit(UnaryExpression unaryExpression) {} - /** */ void visit(UnionDeclaration unionDeclaration) {} - /** */ void visit(Unittest unittest_) {} - /** */ void visit(VariableDeclaration variableDeclaration) {} - /** */ void visit(VersionCondition versionCondition) {} - /** */ void visit(VersionSpecification versionSpecification) {} - /** */ void visit(WhileStatement whileStatement) {} - /** */ void visit(WithStatement withStatement) {} - /** */ void visit(XorExpression xorExpression) {} + /** */ void visit(AddExpression addExpression) { addExpression.accept(this); } + /** */ void visit(AliasDeclaration aliasDeclaration) { aliasDeclaration.accept(this); } + /** */ void visit(AliasInitializer aliasInitializer) { aliasInitializer.accept(this); } + /** */ void visit(AliasThisDeclaration aliasThisDeclaration) { aliasThisDeclaration.accept(this); } + /** */ void visit(AlignAttribute alignAttribute) { alignAttribute.accept(this); } + /** */ void visit(AndAndExpression andAndExpression) { andAndExpression.accept(this); } + /** */ void visit(AndExpression andExpression) { andExpression.accept(this); } + /** */ void visit(ArgumentList argumentList) { argumentList.accept(this); } + /** */ void visit(Arguments arguments) { arguments.accept(this); } + /** */ void visit(ArrayInitializer arrayInitializer) { arrayInitializer.accept(this); } + /** */ void visit(ArrayLiteral arrayLiteral) { arrayLiteral.accept(this); } + /** */ void visit(ArrayMemberInitialization arrayMemberInitialization) { arrayMemberInitialization.accept(this); } + /** */ void visit(AsmAddExp asmAddExp) { asmAddExp.accept(this); } + /** */ void visit(AsmAndExp asmAndExp) { asmAndExp.accept(this); } + /** */ void visit(AsmBrExp asmBrExp) { asmBrExp.accept(this); } + /** */ void visit(AsmEqualExp asmEqualExp) { asmEqualExp.accept(this); } + /** */ void visit(AsmExp asmExp) { asmExp.accept(this); } + /** */ void visit(AsmInstruction asmInstruction) { asmInstruction.accept(this); } + /** */ void visit(AsmLogAndExp asmLogAndExp) { asmLogAndExp.accept(this); } + /** */ void visit(AsmLogOrExp asmLogOrExp) { asmLogOrExp.accept(this); } + /** */ void visit(AsmMulExp asmMulExp) { asmMulExp.accept(this); } + /** */ void visit(AsmOrExp asmOrExp) { asmOrExp.accept(this); } + /** */ void visit(AsmPrimaryExp asmPrimaryExp) { asmPrimaryExp.accept(this); } + /** */ void visit(AsmRelExp asmRelExp) { asmRelExp.accept(this); } + /** */ void visit(AsmShiftExp asmShiftExp) { asmShiftExp.accept(this); } + /** */ void visit(AsmStatement asmStatement) { asmStatement.accept(this); } + /** */ void visit(AsmTypePrefix asmTypePrefix) { asmTypePrefix.accept(this); } + /** */ void visit(AsmUnaExp asmUnaExp) { asmUnaExp.accept(this); } + /** */ void visit(AsmXorExp asmXorExp) { asmXorExp.accept(this); } + /** */ void visit(AssertExpression assertExpression) { assertExpression.accept(this); } + /** */ void visit(AssertStatement assertStatement) { assertStatement.accept(this); } + /** */ void visit(AssignExpression assignExpression) { assignExpression.accept(this); } + /** */ void visit(AssignStatement assignStatement) { assignStatement.accept(this); } + /** */ void visit(AssocArrayLiteral assocArrayLiteral) { assocArrayLiteral.accept(this); } + /** */ void visit(AtAttribute atAttribute) { atAttribute.accept(this); } + /** */ void visit(Attribute attribute) { attribute.accept(this); } + /** */ void visit(AttributedDeclaration attributedDeclaration) { attributedDeclaration.accept(this); } + /** */ void visit(AutoDeclaration autoDeclaration) { autoDeclaration.accept(this); } + /** */ void visit(BlockStatement blockStatement) { blockStatement.accept(this); } + /** */ void visit(BodyStatement bodyStatement) { bodyStatement.accept(this); } + /** */ void visit(BreakStatement breakStatement) { breakStatement.accept(this); } + /** */ void visit(BaseClass baseClass) { baseClass.accept(this); } + /** */ void visit(BaseClassList baseClassList) { baseClassList.accept(this); } + /** */ void visit(BasicType builtinType) { builtinType.accept(this); } + /** */ void visit(CaseRangeStatement caseRangeStatement) { caseRangeStatement.accept(this); } + /** */ void visit(CaseStatement caseStatement) { caseStatement.accept(this); } + /** */ void visit(CastExpression castExpression) { castExpression.accept(this); } + /** */ void visit(CastQualifier castQualifier) { castQualifier.accept(this); } + /** */ void visit(Catch catch_) { catch_.accept(this); } + /** */ void visit(Catches catches) { catches.accept(this); } + /** */ void visit(ClassBody classBody) { classBody.accept(this); } + /** */ void visit(ClassDeclaration classDeclaration) { classDeclaration.accept(this); } + /** */ void visit(CmpExpression cmpExpression) { cmpExpression.accept(this); } + /** */ void visit(CompileCondition compileCondition) { compileCondition.accept(this); } + /** */ void visit(ConditionalDeclaration conditionalDeclaration) { conditionalDeclaration.accept(this); } + /** */ void visit(ConditionalStatement conditionalStatement) { conditionalStatement.accept(this); } + /** */ void visit(Constraint constraint) { constraint.accept(this); } + /** */ void visit(Constructor constructor) { constructor.accept(this); } + /** */ void visit(ContinueStatement continueStatement) { continueStatement.accept(this); } + /** */ void visit(DebugCondition debugCondition) { debugCondition.accept(this); } + /** */ void visit(DebugSpecification debugSpecification) { debugSpecification.accept(this); } + /** */ void visit(Declaration declaration) { declaration.accept(this); } + /** */ void visit(DeclarationsAndStatements declarationsAndStatements) { declarationsAndStatements.accept(this); } + /** */ void visit(DeclarationOrInvariant declarationOrInvariant) { declarationOrInvariant.accept(this); } + /** */ void visit(Declarator declarator) { declarator.accept(this); } + /** */ void visit(DefaultStatement defaultStatement) { defaultStatement.accept(this); } + /** */ void visit(DeleteExpression deleteExpression) { deleteExpression.accept(this); } + /** */ void visit(DeleteStatement deleteStatement) { deleteStatement.accept(this); } + /** */ void visit(Deprecated deprecated_) { deprecated_.accept(this); } + /** */ void visit(Destructor destructor) { destructor.accept(this); } + /** */ void visit(DoStatement doStatement) { doStatement.accept(this); } + /** */ void visit(EnumBody enumBody) { enumBody.accept(this); } + /** */ void visit(EnumDeclaration enumDeclaration) { enumDeclaration.accept(this); } + /** */ void visit(EnumMember enumMember) { enumMember.accept(this); } + /** */ void visit(EqualExpression equalExpression) { equalExpression.accept(this); } + /** */ void visit(Expression expression) { expression.accept(this); } + /** */ void visit(FinalSwitchStatement finalSwitchStatement) { finalSwitchStatement.accept(this); } + /** */ void visit(Finally finally_) { finally_.accept(this); } + /** */ void visit(ForStatement forStatement) { forStatement.accept(this); } + /** */ void visit(ForeachRangeStatement foreachRangeStatement) { foreachRangeStatement.accept(this); } + /** */ void visit(ForeachStatement foreachStatement) { foreachStatement.accept(this); } + /** */ void visit(ForeachType foreachType) { foreachType.accept(this); } + /** */ void visit(ForeachTypeList foreachTypeList) { foreachTypeList.accept(this); } + /** */ void visit(FunctionAttribute functionAttribute) { functionAttribute.accept(this); } + /** */ void visit(FunctionBody functionBody) { functionBody.accept(this); } + /** */ void visit(FunctionCallExpression functionCallExpression) { functionCallExpression.accept(this); } + /** */ void visit(FunctionCallStatement functionCallStatement) { functionCallStatement.accept(this); } + /** */ void visit(FunctionDeclaration functionDeclaration) { functionDeclaration.accept(this); } + /** */ void visit(FunctionLiteralExpression functionLiteralExpression) { functionLiteralExpression.accept(this); } + /** */ void visit(GotoStatement gotoStatement) { gotoStatement.accept(this); } + /** */ void visit(IdentifierChain identifierChain) { identifierChain.accept(this); } + /** */ void visit(IdentifierList identifierList) { identifierList.accept(this); } + /** */ void visit(IdentifierOrTemplateChain identifierOrTemplateChain) { identifierOrTemplateChain.accept(this); } + /** */ void visit(IdentifierOrTemplateInstance identifierOrTemplateInstance) { identifierOrTemplateInstance.accept(this); } + /** */ void visit(IdentityExpression identityExpression) { identityExpression.accept(this); } + /** */ void visit(IfStatement ifStatement) { ifStatement.accept(this); } + /** */ void visit(ImportBind importBind) { importBind.accept(this); } + /** */ void visit(ImportBindings importBindings) { importBindings.accept(this); } + /** */ void visit(ImportDeclaration importDeclaration) { importDeclaration.accept(this); } + /** */ void visit(ImportExpression importExpression) { importExpression.accept(this); } + /** */ void visit(ImportList importList) { importList.accept(this); } + /** */ void visit(IndexExpression indexExpression) { indexExpression.accept(this); } + /** */ void visit(InExpression inExpression) { inExpression.accept(this); } + /** */ void visit(InStatement inStatement) { inStatement.accept(this); } + /** */ void visit(Initialize initialize) { initialize.accept(this); } + /** */ void visit(Initializer initializer) { initializer.accept(this); } + /** */ void visit(InterfaceDeclaration interfaceDeclaration) { interfaceDeclaration.accept(this); } + /** */ void visit(Invariant invariant_) { invariant_.accept(this); } + /** */ void visit(IsExpression isExpression) { isExpression.accept(this); } + /** */ void visit(KeyValuePair keyValuePair) { keyValuePair.accept(this); } + /** */ void visit(KeyValuePairs keyValuePairs) { keyValuePairs.accept(this); } + /** */ void visit(LabeledStatement labeledStatement) { labeledStatement.accept(this); } + /** */ void visit(LambdaExpression lambdaExpression) { lambdaExpression.accept(this); } + /** */ void visit(LastCatch lastCatch) { lastCatch.accept(this); } + /** */ void visit(LinkageAttribute linkageAttribute) { linkageAttribute.accept(this); } + /** */ void visit(MemberFunctionAttribute memberFunctionAttribute) { memberFunctionAttribute.accept(this); } + /** */ void visit(MixinDeclaration mixinDeclaration) { mixinDeclaration.accept(this); } + /** */ void visit(MixinExpression mixinExpression) { mixinExpression.accept(this); } + /** */ void visit(MixinTemplateName mixinTemplateName) { mixinTemplateName.accept(this); } + /** */ void visit(Module module_) { module_.accept(this); } + /** */ void visit(ModuleDeclaration moduleDeclaration) { moduleDeclaration.accept(this); } + /** */ void visit(MulExpression mulExpression) { mulExpression.accept(this); } + /** */ void visit(NewAnonClassExpression newAnonClassExpression) { newAnonClassExpression.accept(this); } + /** */ void visit(NewExpression newExpression) { newExpression.accept(this); } + /** */ void visit(NonEmptyStatement nonEmptyStatement) { nonEmptyStatement.accept(this); } + /** */ void visit(NonVoidInitializer nonVoidInitializer) { nonVoidInitializer.accept(this); } + /** */ void visit(Operand operand) { operand.accept(this); } + /** */ void visit(Operands operands) { operands.accept(this); } + /** */ void visit(OrExpression orExpression) { orExpression.accept(this); } + /** */ void visit(OrOrExpression orOrExpression) { orOrExpression.accept(this); } + /** */ void visit(OutStatement outStatement) { outStatement.accept(this); } + /** */ void visit(Parameter parameter) { parameter.accept(this); } + /** */ void visit(ParameterAttribute parameterAttribute) { parameterAttribute.accept(this); } + /** */ void visit(Parameters parameters) { parameters.accept(this); } + /** */ void visit(Postblit postblit) { postblit.accept(this); } + /** */ void visit(PostIncDecExpression postIncDecExpression) { postIncDecExpression.accept(this); } + /** */ void visit(PowExpression powExpression) { powExpression.accept(this); } + /** */ void visit(PragmaDeclaration pragmaDeclaration) { pragmaDeclaration.accept(this); } + /** */ void visit(PragmaExpression pragmaExpression) { pragmaExpression.accept(this); } + /** */ void visit(PreIncDecExpression preIncDecExpression) { preIncDecExpression.accept(this); } + /** */ void visit(PrimaryExpression primaryExpression) { primaryExpression.accept(this); } + /** */ void visit(Register register) { register.accept(this); } + /** */ void visit(RelExpression relExpression) { relExpression.accept(this); } + /** */ void visit(ReturnStatement returnStatement) { returnStatement.accept(this); } + /** */ void visit(ScopeGuardStatement scopeGuardStatement) { scopeGuardStatement.accept(this); } + /** */ void visit(SharedStaticConstructor sharedStaticConstructor) { sharedStaticConstructor.accept(this); } + /** */ void visit(SharedStaticDestructor sharedStaticDestructor) { sharedStaticDestructor.accept(this); } + /** */ void visit(ShiftExpression shiftExpression) { shiftExpression.accept(this); } + /** */ void visit(SingleImport singleImport) { singleImport.accept(this); } + /** */ void visit(SliceExpression sliceExpression) { sliceExpression.accept(this); } + /** */ void visit(Statement statement) { statement.accept(this); } + /** */ void visit(StatementNoCaseNoDefault statementNoCaseNoDefault) { statementNoCaseNoDefault.accept(this); } + /** */ void visit(StaticAssertDeclaration staticAssertDeclaration) { staticAssertDeclaration.accept(this); } + /** */ void visit(StaticAssertStatement staticAssertStatement) { staticAssertStatement.accept(this); } + /** */ void visit(StaticConstructor staticConstructor) { staticConstructor.accept(this); } + /** */ void visit(StaticDestructor staticDestructor) { staticDestructor.accept(this); } + /** */ void visit(StaticIfCondition staticIfCondition) { staticIfCondition.accept(this); } + /** */ void visit(StorageClass storageClass) { storageClass.accept(this); } + /** */ void visit(StructBody structBody) { structBody.accept(this); } + /** */ void visit(StructBodyItem structBodyItem) { structBodyItem.accept(this); } + /** */ void visit(StructDeclaration structDeclaration) { structDeclaration.accept(this); } + /** */ void visit(StructInitializer structInitializer) { structInitializer.accept(this); } + /** */ void visit(StructMemberInitializer structMemberInitializer) { structMemberInitializer.accept(this); } + /** */ void visit(StructMemberInitializers structMemberInitializers) { structMemberInitializers.accept(this); } + /** */ void visit(SwitchBody switchBody) { switchBody.accept(this); } + /** */ void visit(SwitchStatement switchStatement) { switchStatement.accept(this); } + /** */ void visit(Symbol symbol) { symbol.accept(this); } + /** */ void visit(SynchronizedStatement synchronizedStatement) { synchronizedStatement.accept(this); } + /** */ void visit(TemplateAliasParameter templateAliasParameter) { templateAliasParameter.accept(this); } + /** */ void visit(TemplateArgument templateArgument) { templateArgument.accept(this); } + /** */ void visit(TemplateArgumentList templateArgumentList) { templateArgumentList.accept(this); } + /** */ void visit(TemplateArguments templateArguments) { templateArguments.accept(this); } + /** */ void visit(TemplateDeclaration templateDeclaration) { templateDeclaration.accept(this); } + /** */ void visit(TemplateInstance templateInstance) { templateInstance.accept(this); } + /** */ void visit(TemplateMixinStatement templateMixinStatement) { templateMixinStatement.accept(this); } + /** */ void visit(TemplateParameter templateParameter) { templateParameter.accept(this); } + /** */ void visit(TemplateParameterList templateParameterList) { templateParameterList.accept(this); } + /** */ void visit(TemplateParameters templateParameters) { templateParameters.accept(this); } + /** */ void visit(TemplateSingleArgument templateSingleArgument) { templateSingleArgument.accept(this); } + /** */ void visit(TemplateThisParameter templateThisParameter) { templateThisParameter.accept(this); } + /** */ void visit(TemplateTupleParameter templateTupleParameter) { templateTupleParameter.accept(this); } + /** */ void visit(TemplateTypeParameter templateTypeParameter) { templateTypeParameter.accept(this); } + /** */ void visit(TemplateValueParameter templateValueParameter) { templateValueParameter.accept(this); } + /** */ void visit(TemplateValueParameterDefault templateValueParameterDefault) { templateValueParameterDefault.accept(this); } + /** */ void visit(TernaryExpression ternaryExpression) { ternaryExpression.accept(this); } + /** */ void visit(ThrowStatement throwStatement) { throwStatement.accept(this); } + /** */ void visit(TraitsArgument traitsArgument) { traitsArgument.accept(this); } + /** */ void visit(TraitsExpression traitsExpression) { traitsExpression.accept(this); } + /** */ void visit(TryStatement tryStatement) { tryStatement.accept(this); } + /** */ void visit(Type type) { type.accept(this); } + /** */ void visit(Type2 type2) { type2.accept(this); } + /** */ void visit(TypeConstructor typeConstructor) { typeConstructor.accept(this); } + /** */ void visit(TypeConstructors typeConstructors) { typeConstructors.accept(this); } + /** */ void visit(TypeSpecialization typeSpecialization) { typeSpecialization.accept(this); } + /** */ void visit(TypeSuffix typeSuffix) { typeSuffix.accept(this); } + /** */ void visit(TypeidExpression typeidExpression) { typeidExpression.accept(this); } + /** */ void visit(TypeofExpression typeofExpression) { typeofExpression.accept(this); } + /** */ void visit(UnaryExpression unaryExpression) { unaryExpression.accept(this); } + /** */ void visit(UnionDeclaration unionDeclaration) { unionDeclaration.accept(this); } + /** */ void visit(Unittest unittest_) { unittest_.accept(this); } + /** */ void visit(VariableDeclaration variableDeclaration) { variableDeclaration.accept(this); } + /** */ void visit(VersionCondition versionCondition) { versionCondition.accept(this); } + /** */ void visit(VersionSpecification versionSpecification) { versionSpecification.accept(this); } + /** */ void visit(WhileStatement whileStatement) { whileStatement.accept(this); } + /** */ void visit(WithStatement withStatement) { withStatement.accept(this); } + /** */ void visit(XorExpression xorExpression) { xorExpression.accept(this); } } interface ASTNode @@ -241,7 +238,6 @@ interface ASTNode /** */ void accept(ASTVisitor visitor); } -immutable string OVERRIDE_DEFAULT_ACCEPT = q{override void accept(ASTVisitor visitor) { visitor.visit(this); }}; immutable string DEFAULT_ACCEPT = q{void accept(ASTVisitor visitor) { visitor.visit(this); }}; @@ -262,10 +258,10 @@ public: } /// -class AliasDeclaration : Declaration +class AliasDeclaration : ASTNode { public: - mixin(OVERRIDE_DEFAULT_ACCEPT); + mixin(DEFAULT_ACCEPT); /** */Type type; /** */Declarator declarator; /** */AliasInitializer[] initializations; @@ -281,10 +277,10 @@ public: } /// -class AliasThisDeclaration : Declaration +class AliasThisDeclaration : ASTNode { public: - mixin(OVERRIDE_DEFAULT_ACCEPT); + mixin(DEFAULT_ACCEPT); /** */Token identifier; } @@ -826,7 +822,34 @@ public: class Declaration : ASTNode { public: - mixin(DEFAULT_ACCEPT); + + override void accept(ASTVisitor visitor) + { + if (attributedDeclaration !is null) visitor.visit(attributedDeclaration); + if (importDeclaration !is null) visitor.visit(importDeclaration); + if (functionDeclaration !is null) visitor.visit(functionDeclaration); + if (variableDeclaration !is null) visitor.visit(variableDeclaration); + if (aliasThisDeclaration !is null) visitor.visit(aliasThisDeclaration); + if (structDeclaration !is null) visitor.visit(structDeclaration); + if (classDeclaration !is null) visitor.visit(classDeclaration); + if (interfaceDeclaration !is null) visitor.visit(interfaceDeclaration); + if (unionDeclaration !is null) visitor.visit(unionDeclaration); + if (enumDeclaration !is null) visitor.visit(enumDeclaration); + if (aliasDeclaration !is null) visitor.visit(aliasDeclaration); + if (mixinDeclaration !is null) visitor.visit(mixinDeclaration); + if (unittest_ !is null) visitor.visit(unittest_); + if (staticAssertDeclaration !is null) visitor.visit(staticAssertDeclaration); + if (templateDeclaration !is null) visitor.visit(templateDeclaration); + if (constructor !is null) visitor.visit(constructor); + if (destructor !is null) visitor.visit(destructor); + if (staticConstructor !is null) visitor.visit(staticConstructor); + if (staticDestructor !is null) visitor.visit(staticDestructor); + if (sharedStaticDestructor !is null) visitor.visit(sharedStaticDestructor); + if (sharedStaticConstructor !is null) visitor.visit(sharedStaticConstructor); + if (conditionalDeclaration !is null) visitor.visit(conditionalDeclaration); + if (pragmaDeclaration !is null) visitor.visit(pragmaDeclaration); + } + /** */ AttributedDeclaration attributedDeclaration; /** */ ImportDeclaration importDeclaration; /** */ FunctionDeclaration functionDeclaration; @@ -873,19 +896,9 @@ class Declarator : ASTNode public: mixin(DEFAULT_ACCEPT); /** */ Token identifier; - /** */ DeclaratorSuffix declaratorSuffix; /** */ Initializer initializer; } -/// -class DeclaratorSuffix : ASTNode -{ -public: - mixin(DEFAULT_ACCEPT); - /** */ Type type; - /** */ AssignExpression assignExpression; -} - /// class DefaultStatement : ASTNode { @@ -1086,16 +1099,17 @@ public: } /// -class FunctionDeclaration : Declaration +class FunctionDeclaration : ASTNode { public: - mixin(OVERRIDE_DEFAULT_ACCEPT); + mixin(DEFAULT_ACCEPT); /** */ Type returnType; /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Parameters parameters; /** */ Constraint constraint; /** */ FunctionBody functionBody; + /** */ MemberFunctionAttribute[] memberFunctionAttributes; } /// @@ -1191,10 +1205,10 @@ public: } /// -class ImportDeclaration : Declaration +class ImportDeclaration : ASTNode { public: - mixin(OVERRIDE_DEFAULT_ACCEPT); + mixin(DEFAULT_ACCEPT); /** */ SingleImport[] singleImports; /** */ ImportBindings importBindings; } @@ -1384,7 +1398,13 @@ public: class Module : ASTNode { public: - mixin(DEFAULT_ACCEPT); + override void accept(ASTVisitor visitor) + { + if (moduleDeclaration !is null) + visitor.visit(moduleDeclaration); + foreach(d; declarations) + visitor.visit(d); + } /** */ ModuleDeclaration moduleDeclaration; /** */ Declaration[] declarations; } @@ -2071,6 +2091,7 @@ class Type : ASTNode public: mixin(DEFAULT_ACCEPT); /** */ TypeConstructors typeConstructors; + /** */ TypeSuffix[] typeSuffixes; /** */ Type2 type2; } @@ -2079,17 +2100,7 @@ class Type2 : ASTNode { public: mixin(DEFAULT_ACCEPT); - /** */ Type2 type2; - /** */ Type3 type3; - /** */ TypeSuffix typeSuffix; -} - -/// -class Type3 : ASTNode -{ -public: - mixin(DEFAULT_ACCEPT); - /** */ BasicType builtinType; + /** */ BasicType basicType; /** */ Symbol symbol; /** */ TypeofExpression typeofExpression; /** */ IdentifierOrTemplateChain identifierOrTemplateChain; @@ -2194,10 +2205,10 @@ public: } /// -class VariableDeclaration : Declaration +class VariableDeclaration : ASTNode { public: - mixin(OVERRIDE_DEFAULT_ACCEPT); + mixin(DEFAULT_ACCEPT); /** */ Type type; /** */ Declarator[] declarators; /** */ StorageClass storageClass; diff --git a/std/d/lexer.d b/std/d/lexer.d index 9c2d210..3a187ef 100755 --- a/std/d/lexer.d +++ b/std/d/lexer.d @@ -2505,7 +2505,7 @@ bool isRangeEoF(R)(ref R range) } // Lookup table for token values -immutable(string[TokenType.max + 1]) tokenValues = [ +package immutable(string[TokenType.max + 1]) tokenValues = [ "=", "@", "&", diff --git a/std/d/parser.d b/std/d/parser.d index 3a89f48..5834192 100755 --- a/std/d/parser.d +++ b/std/d/parser.d @@ -70,16 +70,17 @@ import std.array; version (unittest) import std.stdio; version = development; +version(development) import std.stdio; /** * Params: * tokens = the tokens parsed by std.d.lexer * Returns: the parsed module */ -Module parseModule(R)(R tokens) if (is (ElementType!R == Token)) +Module parseModule(const(Token)[] tokens) { auto parser = new Parser(); - parser.tokens = tokens.array(); + parser.tokens = tokens; return parser.parseModule(); } @@ -720,7 +721,7 @@ struct Parser * | $(LITERAL 'const') * | $(LITERAL 'auto') * | $(LITERAL 'scope') - * | $(LITERAL 'gshared') + * | $(LITERAL '___gshared') * | $(LITERAL 'shared') * | $(LITERAL 'immutable') * | $(LITERAL 'inout') @@ -829,8 +830,9 @@ struct Parser { auto node = new BlockStatement(); expect(TokenType.lBrace); - if (!currentIs(TokenType.rBrace)) - node.declarationsAndStatements = parseDeclarationsAndStatements(); + skipBraceContent(); + //if (!currentIs(TokenType.rBrace)) + // node.declarationsAndStatements = parseDeclarationsAndStatements(); expect(TokenType.rBrace); return node; } @@ -1506,6 +1508,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}; */ Declaration parseDeclaration() { + import std.stdio; auto node = new Declaration; switch (current().type) { @@ -1540,17 +1543,22 @@ class ClassFour(A, B) if (someTest()) : Super {}}; node.pragmaDeclaration = parsePragmaDeclaration(); break; case TokenType.shared_: - // TODO: - // sharedStaticConstructor shared static this - // sharedStaticDestructor shared static ~ this - // attributedDeclaration shared anything else + if (startsWith(TokenType.shared_, TokenType.static_, TokenType.this_)) + node.sharedStaticConstructor = parseSharedStaticConstructor(); + else if (startsWith(TokenType.shared_, TokenType.static_, TokenType.tilde)) + node.sharedStaticDestructor = parseSharedStaticDestructor(); + else + node.attributedDeclaration = parseAttributedDeclaration(); break; case TokenType.static_: - // TODO: - // staticConstructor static this - // staticDestructor static ~ - // attributedDeclaration static anything else - // conditionalDeclaration static if + if (startsWith(TokenType.static_, TokenType.this_)) + node.staticConstructor = parseStaticConstructor(); + else if (startsWith(TokenType.static_, TokenType.tilde)) + node.staticDestructor = parseStaticDestructor(); + else if (startsWith(TokenType.static_, TokenType.if_)) + node.conditionalDeclaration = parseConditionalDeclaration(); + else + node.attributedDeclaration = parseAttributedDeclaration(); break; case TokenType.struct_: node.structDeclaration = parseStructDeclaration(); @@ -1564,17 +1572,53 @@ class ClassFour(A, B) if (someTest()) : Super {}}; case TokenType.unittest_: node.unittest_ = parseUnittest(); break; + case TokenType.bool_: .. case TokenType.wchar_: case TokenType.identifier: - // TODO: - // variableDeclaration - // functionDeclaration + Type type = parseType(); + if (!currentIs(TokenType.identifier)) + { + error("Identifier expected"); + return null; + } + if (peekIs(TokenType.lParen)) + node.functionDeclaration = parseFunctionDeclaration(type); + else + node.variableDeclaration = parseVariableDeclaration(type); break; case TokenType.version_: case TokenType.debug_: node.conditionalDeclaration = parseConditionalDeclaration(); break; + case TokenType.at: + case TokenType.extern_: + case TokenType.align_: + //case TokenType.pragma_: + case TokenType.deprecated_: + case TokenType.private_: + case TokenType.package_: + case TokenType.protected_: + case TokenType.public_: + case TokenType.export_: + //case TokenType.extern_: + case TokenType.final_: + case TokenType.synchronized_: + case TokenType.override_: + case TokenType.abstract_: + case TokenType.const_: + case TokenType.auto_: + case TokenType.scope_: + case TokenType.gshared: + //case TokenType.shared_: + case TokenType.immutable_: + case TokenType.inout_: + //case TokenType.static_: + case TokenType.pure_: + case TokenType.nothrow_: + node.attributedDeclaration = parseAttributedDeclaration(); + break; default: error("Declaration expected"); + advance(); return null; } return node; @@ -1616,15 +1660,20 @@ class ClassFour(A, B) if (someTest()) : Super {}}; * Parses a Declarator * * $(GRAMMAR $(RULEDEF declarator): - * $(LITERAL Identifier) $(RULE declaratorSuffix)? ($(LITERAL '=') $(RULE initializer))? + * $(LITERAL Identifier) ($(LITERAL '=') $(RULE initializer))? * ;) */ Declarator parseDeclarator() { auto node = new Declarator; - node.identifier = *expect(TokenType.identifier); - if (currentIs(TokenType.lBracket)) - node.declaratorSuffix = parseDeclaratorSuffix(); + auto id = expect(TokenType.identifier); + if (id is null) return null; + node.identifier = *id; + if (currentIsOneOf(TokenType.lBracket, TokenType.star)) + { + error("C-style variable declarations are not supported."); + return null; + } if (currentIs(TokenType.assign)) { advance(); @@ -1633,20 +1682,6 @@ class ClassFour(A, B) if (someTest()) : Super {}}; return node; } - /** - * Parses a DeclaratorSuffix - * - * $(GRAMMAR $(RULEDEF declaratorSuffix): - * $(LITERAL '[') ($(RULE type) | $(RULE assignExpression))? $(LITERAL ']') - * ;) - */ - DeclaratorSuffix parseDeclaratorSuffix() - { - auto node = new DeclaratorSuffix; - // TODO - return node; - } - /** * Parses a DefaultStatement * @@ -1730,6 +1765,17 @@ class ClassFour(A, B) if (someTest()) : Super {}}; return node; } + unittest + { + auto sourceCode = q{~this(){}}c; + Parser p = getParserForUnittest(sourceCode, "parseDestructor"); + Destructor d = p.parseDestructor(); + assert (d !is null); + assert (d.functionBody !is null); + assert (p.errorCount == 0); + stderr.writeln("Unittest for parseDestructor() passed."); + } + /** * Parses a DoStatement * @@ -2080,10 +2126,56 @@ body {} // six * | $(RULE memberFunctionAttribute)* ($(RULE type) | $(LITERAL 'auto') $(LITERAL 'ref')? | $(LITERAL 'ref') $(LITERAL 'auto')?) $(LITERAL Identifier) $(RULE parameters) $(RULE memberFunctionAttribute)* ($(RULE functionBody) | $(LITERAL ';')) * ;) */ - FunctionDeclaration parseFunctionDeclaration() + FunctionDeclaration parseFunctionDeclaration(Type type = null) { auto node = new FunctionDeclaration; - // TODO + + while(moreTokens() && currentIsMemberFunctionAttribute()) + node.memberFunctionAttributes ~= parseMemberFunctionAttribute(); + + switch (current.type) + { + case TokenType.auto_: + break; + case TokenType.ref_: + break; + default: + break; + } + + node.returnType = type is null ? parseType() : type; + + auto ident = expect(TokenType.identifier); + if (ident is null) return null; + + node.name = *ident; + + if (!currentIs(TokenType.lParen)) + { + error(`"(" expected`); + return null; + } + + bool isTemplate = peekPastParens().type == TokenType.lParen; + + if (isTemplate) + node.templateParameters = parseTemplateParameters(); + + node.parameters = parseParameters(); + + while(moreTokens() && currentIsMemberFunctionAttribute()) + node.memberFunctionAttributes ~= parseMemberFunctionAttribute(); + + if (isTemplate && currentIs(TokenType.if_)) + node.constraint = parseConstraint(); + + if (isTemplate) + node.functionBody = parseFunctionBody(); + else if (currentIs(TokenType.semicolon)) + advance(); + else + node.functionBody = parseFunctionBody(); + return node; } @@ -2736,9 +2828,9 @@ interface "Four" Module parseModule() { Module m = new Module; - while (index < tokens.length) + while (moreTokens()) { - switch (tokens[index].type) + switch (current().type) { case TokenType.module_: if (m.moduleDeclaration is null) @@ -2747,7 +2839,9 @@ interface "Four" error("Only one module declaration is allowed per module"); break; default: - m.declarations ~= parseDeclaration(); + auto declaration = parseDeclaration(); + if (declaration !is null) + m.declarations ~= declaration; } } return m; @@ -3001,7 +3095,9 @@ interface "Four" Parameters parseParameters() { auto node = new Parameters; - // TODO + expect(TokenType.lParen); + version(development) skipParenContent(); + expect(TokenType.rParen); return node; } @@ -3958,13 +4054,38 @@ interface "Four" * Parses a Type * * $(GRAMMAR $(RULEDEF type): - * $(RULE typeConstructors)? $(RULE type2) + * $(RULE typeConstructors)? $(RULE type2) $(RULE typeSuffix)* * ;) */ Type parseType() { auto node = new Type; - // TODO + switch(current.type) + { + case TokenType.const_: + case TokenType.immutable_: + case TokenType.inout_: + case TokenType.shared_: + node.typeConstructors = parseTypeConstructors(); + break; + default: + break; + } + node.type2 = parseType2(); + loop: while (true) + { + switch (current.type) + { + case TokenType.star: + case TokenType.lBracket: + case TokenType.delegate_: + case TokenType.function_: + node.typeSuffixes ~= parseTypeSuffix(); + break; + default: + break loop; + } + } return node; } @@ -3972,31 +4093,45 @@ interface "Four" * Parses a Type2 * * $(GRAMMAR $(RULEDEF type2): - * $(RULE type3) $(RULE typeSuffix)? - * | $(RULE type2) $(RULE typeSuffix) - * ;) - */ - Type2 parseType2() - { - auto node = new Type2; - // TODO - return node; - } - - /** - * Parses a Type3 - * - * $(GRAMMAR $(RULEDEF type3): * $(RULE builtinType) * | $(RULE symbol) * | $(RULE typeofExpression) ($(LITERAL '.') $(RULE identifierOrTemplateChain))? * | $(RULE typeConstructor) $(LITERAL '$(LPAREN)') $(RULE type) $(LITERAL '$(RPAREN)') * ;) */ - Type3 parseType3() + Type2 parseType2() { - auto node = new Type3; - // TODO + auto node = new Type2; + switch (current.type) + { + case TokenType.identifier: + case TokenType.dot: + node.symbol = parseSymbol(); + break; + case TokenType.bool_: .. case TokenType.wchar_: + node.basicType = parseBasicType(); + break; + case TokenType.typeof_: + node.typeofExpression = parseTypeofExpression(); + if (currentIs(TokenType.dot)) + { + advance(); + node.identifierOrTemplateChain = parseIdentifierOrTemplateChain(); + } + break; + case TokenType.const_: + case TokenType.immutable_: + case TokenType.inout_: + case TokenType.shared_: + node.typeConstructor = parseTypeConstructor(); + expect(TokenType.lParen); + node.type = parseType(); + expect(TokenType.rParen); + break; + default: + error("Basic type, type constructor, symbol, or typeof expected"); + break; + } return node; } @@ -4086,7 +4221,8 @@ interface "Four" case TokenType.function_: advance(); node.parameters = parseParameters(); - // TODO: memberFunctionAttribute + while (currentIsMemberFunctionAttribute()) + node.memberFunctionAttributes ~= parseMemberFunctionAttribute(); return node; default: error(`"*", "[", "delegate", or "function" expected.`); @@ -4249,10 +4385,29 @@ interface "Four" * | $(RULE autoDeclaration) * ;) */ - VariableDeclaration parseVariableDeclaration() + VariableDeclaration parseVariableDeclaration(Type type = null) { auto node = new VariableDeclaration; - // TODO + + if (currentIs(TokenType.auto_)) + { + node.autoDeclaration = parseAutoDeclaration(); + return node; + } + + node.type = type is null ? parseType() : type; + + while(true) + { + auto declarator = parseDeclarator(); + if (declarator is null) return null; + node.declarators ~= declarator; + if (moreTokens() && currentIs(TokenType.comma)) + advance(); + else + break; + } + expect(TokenType.semicolon); return node; } @@ -4355,18 +4510,42 @@ interface "Four" return node; } - void error(string message) + private bool currentIsMemberFunctionAttribute() const { - ++errorCount; - import std.stdio; - stderr.writefln("%s(%d:%d): %s", fileName, tokens[index].line, - tokens[index].column, message); - while (index < tokens.length) + switch (current.type) { - if (tokens[index].type == TokenType.semicolon) + case TokenType.const_: + case TokenType.immutable_: + case TokenType.inout_: + case TokenType.shared_: + case TokenType.at: + case TokenType.pure_: + case TokenType.nothrow_: + return true; + default: + return false; + } + } + + void error(lazy string message) + { + import std.stdio; + ++errorCount; + if (errorFunction is null) + stderr.writefln("%s(%d:%d): %s", fileName, tokens[index].line, + tokens[index].column, message); + else + errorFunction(fileName, tokens[index].line, tokens[index].column, + message); + while (moreTokens()) + { + if (currentIsOneOf(TokenType.semicolon, TokenType.rBrace)) + { + advance(); break; + } else - index++; + advance(); } } @@ -4472,8 +4651,8 @@ interface "Four" return &tokens[index++]; else { - error("Expected " ~ to!string(type) ~ " instead of " - ~ to!string(tokens[index].type)); + error("Expected " ~ tokenValues[type] ~ " instead of " + ~ tokens[index].value); return null; } } @@ -4481,7 +4660,7 @@ interface "Four" /** * Returns: the _current token */ - Token current() const + Token current() const @property { return tokens[index]; } @@ -4525,15 +4704,19 @@ interface "Four" */ bool moreTokens() const { - return index < tokens.length; + return index + 1 < tokens.length; } + version (unittest) static void doNothingErrorFunction(string fileName, + int line, int column, string message) {} + version (unittest) static Parser getParserForUnittest(string sourceCode, string testName) { LexerConfig config; auto r = byToken(cast(const(ubyte)[]) sourceCode, config); Parser p; + p.errorFunction = &doNothingErrorFunction; p.fileName = testName ~ ".d"; p.tokens = r.array(); return p; @@ -4543,4 +4726,5 @@ interface "Four" const(Token)[] tokens; size_t index; string fileName; + void function(string, int, int, string) errorFunction; } diff --git a/std/d/tester.d b/std/d/tester.d new file mode 100644 index 0000000..c873c95 --- /dev/null +++ b/std/d/tester.d @@ -0,0 +1,50 @@ +import std.d.lexer; +import std.d.ast; +import std.d.parser; +import std.stdio; +import std.file; +import std.array; + +class TestVisitor : ASTVisitor +{ + override void visit(ClassDeclaration classDeclaration) + { + writeln("class ", classDeclaration.name.value, " on line ", classDeclaration.name.line); + } + + override void visit(ModuleDeclaration md) + { + writeln("module declaration found"); + } + + override void visit(FunctionDeclaration funDec) + { + writeln("function ", funDec.name.value, " on line ", funDec.name.line); + } + + override void visit(VariableDeclaration varDec) + { + writeln("variable ", varDec.declarators[0].identifier.value, + " on line ", varDec.declarators[0].identifier.line); + } + + override void visit(ImportDeclaration impDec) + { + writeln("import declaration found"); + } + + alias ASTVisitor.visit visit; +} + +void main(string[] args) +{ + auto de = dirEntry(args[1]); + ubyte[] sourceBuffer = new ubyte[de.size]; + auto f = File(args[1]); + ubyte[] rawSource = f.rawRead(sourceBuffer); + LexerConfig config; + auto tokens = byToken(rawSource, config).array(); + Module m = parseModule(tokens); + ASTVisitor visitor = new TestVisitor; + visitor.visit(m); +}