diff --git a/d.y b/d.y new file mode 100644 index 0000000..8dcc900 --- /dev/null +++ b/d.y @@ -0,0 +1,1642 @@ + +%token assign "=" +%token at "@" +%token bitAnd "&" +%token bitAndEqual "&=" +%token bitOr "|" +%token bitOrEqual "|=" +%token catEqual "~=" +%token colon ":" +%token comma "," +%token decrement "--" +%token div "/" +%token divEqual "/=" +%token dollar "$" +%token dot "." +%token equal "==" +%token goesTo "=>" +%token greater ">" +%token greaterEqual ">=" +%token hash "#" +%token increment "++" +%token lBrace "{" +%token lBracket "[" +%token less "<" +%token lessEqual "<=" +%token lessEqualGreater "<>=" +%token lessOrGreater "<>" +%token logicAnd "&&" +%token logicOr "||" +%token lParen "(" +%token minus "-" +%token minusEqual "-=" +%token mod "%" +%token modEqual "%=" +%token mulEqual "*=" +%token not "!" +%token notEqual "!=" +%token notGreater "!>" +%token notGreaterEqual "!>=" +%token notLess "!<" +%token notLessEqual "!<=" +%token notLessEqualGreater "!<>" +%token plus "+" +%token plusEqual "+=" +%token pow "^^" +%token powEqual "^^=" +%token rBrace "}" +%token rBracket "]" +%token rParen ")" +%token semicolon ";" +%token shiftLeft "<<" +%token shiftLeftEqual "<<=" +%token shiftRight ">>" +%token shiftRightEqual ">>=" +%token slice ".." +%token star "*" +%token ternary "?" +%token tilde "~" +%token unordered "!<>=" +%token unsignedShiftRight ">>>" +%token unsignedShiftRightEqual ">>>=" +%token vararg "..." +%token xor "^" +%token xorEqual "^=" +%token bool_ "bool" +%token byte_ "byte" +%token cdouble_ "cdouble" +%token cent_ "cent" +%token cfloat_ "cfloat" +%token char_ "char" +%token creal_ "creal" +%token dchar_ "dchar" +%token double_ "double" +%token float_ "float" +%token function_ "function" +%token idouble_ "idouble" +%token ifloat_ "ifloat" +%token int_ "int" +%token ireal_ "ireal" +%token long_ "long" +%token real_ "real" +%token short_ "short" +%token ubyte_ "ubyte" +%token ucent_ "ucent" +%token uint_ "uint" +%token ulong_ "ulong" +%token ushort_ "ushort" +%token void_ "void" +%token wchar_ "wchar" +%token align_ "align" +%token deprecated_ "deprecated" +%token extern_ "extern" +%token pragma_ "pragma" +%token export_ "export" +%token package_ "package" +%token private_ "private" +%token protected_ "protected" +%token public_ "public" +%token abstract_ "abstract" +%token auto_ "auto" +%token const_ "const" +%token final_ "final" +%token gshared +%token immutable_ "immutable" +%token inout_ "inout" +%token scope_ "scope" +%token shared_ "shared" +%token static_ "static" +%token synchronized_ "synchronized" +%token alias_ "alias" +%token asm_ "asm" +%token assert_ "assert" +%token body_ "body" +%token break_ "break" +%token case_ "case" +%token cast_ "cast" +%token catch_ "catch" +%token class_ "class" +%token continue_ "continue" +%token debug_ "debug" +%token default_ "default" +%token delegate_ "delegate" +%token delete_ "delete" +%token do_ "do" +%token else_ "else" +%token enum_ "enum" +%token false_ "false" +%token finally_ "finally" +%token foreach_ "foreach" +%token foreach_reverse_ "foreach_reverse" +%token for_ "for" +%token goto_ "goto" +%token if_ "if" +%token import_ "import" +%token in_ "in" +%token interface_ "interface" +%token invariant_ "invariant" +%token is_ "is" +%token lazy_ "lazy" +%token macro_ "macro" +%token mixin_ "mixin" +%token module_ "module" +%token new_ "new" +%token nothrow_ "nothrow" +%token null_ "null" +%token out_ "out" +%token override_ "override" +%token pure_ "pure" +%token ref_ "ref" +%token return_ "return" +%token struct_ "struct" +%token super_ "super" +%token switch_ "switch" +%token template_ "template" +%token this_ "this" +%token throw_ "throw" +%token true_ "true" +%token try_ "try" +%token typedef_ "typedef" +%token typeid_ "typeid" +%token typeof_ "typeof" +%token union_ "union" +%token unittest_ "unittest" +%token version_ "version" +%token volatile_ "volatile" +%token while_ "while" +%token with_ "with" +%token date "__DATE__" +%token eof "__EOF__" +%token time "__TIME__" +%token timestamp "__TIMESTAMP__" +%token vendor "__VENDOR__" +%token compilerVersion "__VERSION__" +%token file "__FILE__" +%token line "__LINE__" +%token comment +%token identifier +%token scriptLine +%token traits +%token parameters +%token vector +%token whitespace +%token specialTokenSequence +%token doubleLiteral +%token floatLiteral +%token idoubleLiteral +%token ifloatLiteral +%token intLiteral +%token longLiteral +%token realLiteral +%token irealLiteral +%token uintLiteral +%token ulongLiteral +%token characterLiteral +%token dstringLiteral +%token stringLiteral +%token wstringLiteral + +%% +Module: ModuleDeclaration DeclDefs + | DeclDefs + +DeclDefs: DeclDef + | DeclDef DeclDefs + +DeclDef: + AttributeSpecifier + | ImportDeclaration + | EnumDeclaration + | ClassDeclaration + | InterfaceDeclaration + | AggregateDeclaration + | Declaration + | Constructor + | Destructor + | UnitTest + | StaticConstructor + | StaticDestructor + | SharedStaticConstructor + | SharedStaticDestructor + | ConditionalDeclaration + | DebugSpecification + | VersionSpecification + | StaticAssert + | TemplateDeclaration + | TemplateMixinDeclaration + | TemplateMixin + | MixinDeclaration + | ";" + ; + +ModuleDeclaration: "module" ModuleFullyQualifiedName + ; + +ModuleFullyQualifiedName: ModuleName + | Packages "." ModuleName + ; + +ModuleName: identifier + ; + +Packages: PackageName + | Packages "." PackageName + ; + +PackageName: identifier + ; + +ImportDeclaration: "import" ImportList ";" + | "static" "import" ImportList ";" + ; + +ImportList: Import + | ImportBindings + | Import "," ImportList + ; + +Import: ModuleFullyQualifiedName + | ModuleAliasIdentifier "=" ModuleFullyQualifiedName + ; + +ImportBindings: + Import : ImportBindList + ; + +ImportBindList: ImportBind + | ImportBind "," ImportBindList + ; + +ImportBind: identifier + | identifier "=" identifier; + +ModuleAliasIdentifier: + identifier + ; + +MixinDeclaration: "mixin" "(" AssignExpression ")" ";" + ; + +Declaration: AliasDeclaration + | AliasThisDeclaration + | Decl + ; + +AliasDeclaration: "alias" BasicType Declarator + | "alias" AliasInitializerList + ; + +AliasInitializerList: AliasInitializer + | AliasInitializer "," AliasInitializerList + ; + +AliasInitializer: identifier "=" Type + ; + +AliasThisDeclaration: "alias" identifier "this" + ; + +Decl: StorageClasses Decl + | BasicType Declarators ";" + | BasicType Declarator FunctionBody + | AutoDeclaration + ; + +Declarators: DeclaratorInitializer + | DeclaratorInitializer "," DeclaratorIdentifierList + ; + +DeclaratorInitializer: Declarator + | Declarator "=" Initializer + ; + +DeclaratorIdentifierList: DeclaratorIdentifier + | DeclaratorIdentifier "," DeclaratorIdentifierList + ; + +DeclaratorIdentifier: identifier + | identifier "=" Initializer + ; + +BasicType: BasicTypeX + | "." IdentifierList + | IdentifierList + | Typeof + | Typeof "." IdentifierList + | "const" "(" Type ")" + | "immutable" "(" Type ")" + | "shared" "(" Type ")" + | "inout" "(" Type ")" + ; + +BasicTypeX: "bool" + | "byte" + | "ubyte" + | "short" + | "ushort" + | "int" + | "uint" + | "long" + | "ulong" + | "char" + | "wchar" + | "dchar" + | "float" + | "double" + | "real" + | "ifloat" + | "idouble" + | "ireal" + | "cfloat" + | "cdouble" + | "creal" + | "void" + ; + +BasicType2: "*" + | "[" "]" + | "[" AssignExpression "]" + | "[" AssignExpression ".." AssignExpression "]" + | "[" Type "]" + | "delegate" Parameters + | "delegate" Parameters MemberFunctionAttributes + | "function" Parameters + | "function" Parameters FunctionAttributes + ; + +Declarator: "(" Declarator ")" + | BasicType2 "(" Declarator ")" DeclaratorSuffixes + | "(" Declarator ")" DeclaratorSuffixes + | BasicType2 "(" Declarator ")" DeclaratorSuffixes + | identifier + | identifier DeclaratorSuffixes + | BasicType2 identifier DeclaratorSuffixes + ; + +DeclaratorSuffixes: DeclaratorSuffix + | DeclaratorSuffix DeclaratorSuffixes + ; + +DeclaratorSuffix: "[" "]" + | "[" AssignExpression "]" + | "[" Type "]" + | Parameters + | TemplateParameters Parameters + | TemplateParameters Parameters MemberFunctionAttributes + | TemplateParameters Parameters MemberFunctionAttributes Constraint + | TemplateParameters Parameters Constraint + | Parameters Constraint + | Parameters MemberFunctionAttributes + | Parameters MemberFunctionAttributes Constraint + ; + +IdentifierList: identifier + | identifier "." IdentifierList + | TemplateInstance + | TemplateInstance "." IdentifierList + ; + +StorageClasses: StorageClass + | StorageClass StorageClasses + ; + +StorageClass: "abstract" + | "auto" + | TypeCtor + | "deprecated" + | "enum" + | "extern" + | "final" + | "nothrow" + | "override" + | "pure" + | "__gshared" + | Property + | "scope" + | "static" + | "synchronized" + ; + +Property: "@" PropertyIdentifier + ; + +PropertyIdentifier: "property" + | "safe" + | "trusted" + | "system" + | "disable" + ; + +TypeCtors: TypeCtor + | TypeCtor TypeCtors + ; + +TypeCtor: "const" + | "immutable" + | "inout" + | "shared" + ; + +Type: TypeCtors BasicType + | BasicType + | BasicType Declarator2 + | TypeCtors BasicType Declarator2 + ; + +Declarator2: + | BasicType2 + | BasicType2 DeclaratorSuffixes + | "(" Declarator2 ")" + | BasicType2 "(" Declarator2 ")" + | "(" Declarator2 ")" DeclaratorSuffixes + | BasicType2 "(" Declarator2 ")" DeclaratorSuffixes + ; + +Parameters: "(" ParameterList ")" + | "(" ")" + ; + +ParameterList: Parameter + | Parameter "," ParameterList + | "..." + ; + +Parameter: BasicType Declarator + | InOut BasicType Declarator + | BasicType Declarator "..." + | InOut BasicType Declarator "..." + | BasicType Declarator "=" DefaultInitializerExpression + | InOut BasicType Declarator "=" DefaultInitializerExpression + | Type + | InOut Type + | Type "..." + | InOut Type "..." + ; + +InOut: InOutX + | InOut InOutX + ; + +InOutX: "auto" + | TypeCtor + | "final" + | "in" + | "lazy" + | "out" + | "ref" + | "scope" + ; + +FunctionAttributes: FunctionAttribute + | FunctionAttribute FunctionAttributes + ; + +FunctionAttribute: "nothrow" + | "pure" + | Property + ; + +MemberFunctionAttributes: MemberFunctionAttribute + | MemberFunctionAttribute MemberFunctionAttributes + ; + +MemberFunctionAttribute: "const" + | "immutable" + | "inout" + | "shared" + | FunctionAttribute + ; + +DefaultInitializerExpression: AssignExpression + | "__FILE__" + | "__MODULE__" + | "__LINE__" + | "__FUNCTION__" + | "__PRETTY_FUNCTION__" + ; + +Initializer: VoidInitializer + | NonVoidInitializer + ; + +NonVoidInitializer: AssignExpression + | ArrayInitializer + | StructInitializer + ; + +ArrayInitializer: "[" "]" + | "[" ArrayMemberInitializations "]" + ; + +ArrayMemberInitializations: ArrayMemberInitialization + | ArrayMemberInitialization "," + | ArrayMemberInitialization "," ArrayMemberInitializations + ; + +ArrayMemberInitialization: NonVoidInitializer + | AssignExpression ":" NonVoidInitializer + ; + +StructInitializer: "{" "}" + | "{" StructMemberInitializers "}" + ; + +StructMemberInitializers: StructMemberInitializer + | StructMemberInitializer "," + | StructMemberInitializer "," StructMemberInitializers + ; + +StructMemberInitializer: NonVoidInitializer + | identifier ":" NonVoidInitializer + +AutoDeclaration: StorageClasses AutoDeclarationX ";" + ; + +AutoDeclarationX: identifier "=" Initializer + | AutoDeclarationX "," identifier "=" Initializer + ; + +Typeof: "typeof" "(" Expression ")" + | "typeof" "(" "return" ")" + ; + +VoidInitializer: "void" + +AttributeSpecifier: Attribute ":" + | Attribute DeclarationBlock + ; + +Attribute: LinkageAttribute + | AlignAttribute + | Pragma + | "deprecated" + | ProtectionAttribute + | "static" + | "extern" + | "final" + | "synchronized" + | "override" + | "abstract" + | "const" + | "auto" + | "scope" + | "__gshared" + | "shared" + | "immutable" + | "inout" + | "@" "disable" + ; + + +DeclarationBlock: DeclDef + | "{" "}" + | "{" DeclDefs "}" + ; + +LinkageAttribute: "extern" "(" LinkageType ")" + ; + +LinkageType: "C" + | "C++" + | "D" + | "Windows" + | "Pascal" + | "System" + ; + +AlignAttribute: "align" + | "align" "(" intLiteral ")" + ; + +ProtectionAttribute: "private" + | "package" + | "protected" + | "public" + | "export" + ; + +StorageClass: UserDefinedAttribute + ; + +UserDefinedAttribute: "@" "(" "ArgumentList" ")" + | "@" identifier /* BUG: Should be CallExpression but CallExpression is not defined by the grammar */ + ; + +Pragma: "pragma" "(" identifier ")" + | "pragma" "(" identifier "," ArgumentList ")" + ; + +Expression: CommaExpression + ; + +CommaExpression: + | AssignExpression + | AssignExpression "," CommaExpression + ; + +AssignExpression: ConditionalExpression + | ConditionalExpression "=" AssignExpression + | ConditionalExpression "+=" AssignExpression + | ConditionalExpression "-=" AssignExpression + | ConditionalExpression "*=" AssignExpression + | ConditionalExpression "/=" AssignExpression + | ConditionalExpression "%=" AssignExpression + | ConditionalExpression "&=" AssignExpression + | ConditionalExpression "|=" AssignExpression + | ConditionalExpression "^=" AssignExpression + | ConditionalExpression "~=" AssignExpression + | ConditionalExpression "<<=" AssignExpression + | ConditionalExpression ">>=" AssignExpression + | ConditionalExpression ">>>=" AssignExpression + | ConditionalExpression "^^=" AssignExpression + ; + +ConditionalExpression: OrOrExpression + | OrOrExpression "?" Expression ":" ConditionalExpression + ; + +OrOrExpression: AndAndExpression + | OrOrExpression "||" AndAndExpression + ; + +AndAndExpression: OrExpression + | AndAndExpression "&&" OrExpression + | CmpExpression + | AndAndExpression "&&" CmpExpression + ; + +OrExpression: XorExpression + | OrExpression "|" XorExpression + ; + +XorExpression: AndExpression + | XorExpression "^" AndExpression + ; + +AndExpression: ShiftExpression + | AndExpression "&" ShiftExpression + ; + +CmpExpression: ShiftExpression + | EqualExpression + | IdentityExpression + | RelExpression + | InExpression + ; + +EqualExpression: ShiftExpression "==" ShiftExpression + | ShiftExpression "!=" ShiftExpression + ; + +IdentityExpression: ShiftExpression "is" ShiftExpression + | ShiftExpression "!is" ShiftExpression + ; + +RelExpression: ShiftExpression "<" ShiftExpression + | ShiftExpression "<=" ShiftExpression + | ShiftExpression ">" ShiftExpression + | ShiftExpression ">=" ShiftExpression + | ShiftExpression "!<>=" ShiftExpression + | ShiftExpression "!<>" ShiftExpression + | ShiftExpression "<>" ShiftExpression + | ShiftExpression "<>=" ShiftExpression + | ShiftExpression "!>" ShiftExpression + | ShiftExpression "!>=" ShiftExpression + | ShiftExpression "!<" ShiftExpression + | ShiftExpression "!<=" ShiftExpression + ; + +InExpression: ShiftExpression "in" ShiftExpression + | ShiftExpression "!in" ShiftExpression + ; + +ShiftExpression: AddExpression + | ShiftExpression "<<" AddExpression + | ShiftExpression ">>" AddExpression + | ShiftExpression ">>>" AddExpression + ; + +AddExpression: MulExpression + | AddExpression "+" MulExpression + | AddExpression "-" MulExpression + | CatExpression + ; + +CatExpression: AddExpression "~" MulExpression + ; + +MulExpression: UnaryExpression + | MulExpression "*" UnaryExpression + | MulExpression "/" UnaryExpression + | MulExpression "%" UnaryExpression + ; + +UnaryExpression: "&" UnaryExpression + | "++" UnaryExpression + | "--" UnaryExpression + | "*" UnaryExpression + | "-" UnaryExpression + | "+" UnaryExpression + | "!" UnaryExpression + | ComplementExpression + | "(" Type ")" "." identifier + | "(" Type ")" "." TemplateInstance + | NewExpression + | DeleteExpression + | CastExpression + | PowExpression + ; + +ComplementExpression: "~" UnaryExpression + ; + +NewExpression: "new" Type "[" AssignExpression "]" + | "new" AllocatorArguments Type "[" AssignExpression "]" + | "new" Type "(" ArgumentList ")" + | "new" AllocatorArguments Type "(" ArgumentList ")" + | "new" Type + | "new" AllocatorArguments Type + | NewAnonClassExpression + ; + +AllocatorArguments: "(" ")" + | "(" ArgumentList ")" + ; + +ArgumentList: AssignExpression + | AssignExpression "," + | AssignExpression "," ArgumentList + ; + +DeleteExpression: "delete" UnaryExpression + ; + +CastExpression: "cast" "(" Type ")" UnaryExpression + | "cast" "(" CastQual ")" UnaryExpression + | "cast" "(" ")" UnaryExpression + ; + +CastQual: "const" + | "const" "shared" + | "shared" "const" + | "inout" + | "inout" "shared" + | "shared" "inout" + | "immutable" + | "shared" + ; + +PowExpression: PostfixExpression + | PostfixExpression "^^" UnaryExpression + ; + +PostfixExpression: PrimaryExpression + | PostfixExpression "." identifier + | PostfixExpression "." TemplateInstance + | PostfixExpression "." NewExpression + | PostfixExpression "++" + | PostfixExpression "--" + | PostfixExpression "(" ")" + | PostfixExpression "(" ArgumentList ")" + | BasicType "(" ")" + | TypeCtors BasicType "(" ")" + | BasicType "(" ArgumentList ")" + | TypeCtors BasicType "(" ArgumentList ")" + | IndexExpression + | SliceExpression + ; + +IndexExpression: PostfixExpression "[" ArgumentList "]" + ; + +SliceExpression: PostfixExpression "[" "]" + | PostfixExpression "[" AssignExpression ".." AssignExpression "]" + ; + +PrimaryExpression: identifier + | "." identifier + | TemplateInstance + | "." TemplateInstance + | "this" + | "super" + | "null" + | "true" + | "false" + | "$" + | "__FILE__" + | "__MODULE__" + | "__LINE__" + | "__FUNCTION__" + | "__PRETTY_FUNCTION__" + | intLiteral + | floatLiteral + | characterLiteral + | stringLiteral + | wstringLiteral + | dstringLiteral + | ArrayLiteral + | AssocArrayLiteral + | Lambda + | FunctionLiteral + | AssertExpression + | MixinExpression + | ImportExpression + | BasicType "." identifier + | Typeof + | TypeidExpression + | IsExpression + | "(" Expression ")" + | TraitsExpression + ; + +StringLiterals: stringLiteral + | stringLiteral StringLiterals + ; + +ArrayLiteral: "[" ArgumentList "]" + ; + + +AssocArrayLiteral: "[" KeyValuePairs "]" + +KeyValuePairs: KeyValuePair + | KeyValuePair "," KeyValuePairs + ; + +KeyValuePair: KeyExpression ":" ValueExpression + ; + +KeyExpression: AssignExpression + ; + +ValueExpression: AssignExpression + ; + +Lambda: identifier "=>" AssignExpression + | ParameterAttributes "=>" AssignExpression + ; + +FunctionLiteral: "function" FunctionBody + | "function" ParameterAttributes FunctionBody + | "function" Type FunctionBody + | "function" Type ParameterAttributes FunctionBody + | "delegate" FunctionBody + | "delegate" ParameterAttributes FunctionBody + | "delegate" Type FunctionBody + | "delegate" Type ParameterAttributes FunctionBody + | ParameterAttributes FunctionBody + | FunctionBody + ; + +ParameterAttributes: Parameters + | Parameters FunctionAttributes + ; + +AssertExpression: "assert" "(" AssignExpression ")" + | "assert" "(" AssignExpression "," AssignExpression ")" + ; + +MixinExpression: "mixin" "(" AssignExpression ")" + ; + +ImportExpression: "import" "(" AssignExpression ")" + ; + +TypeidExpression: "typeid" "(" Type ")" + | "typeid" "(" Expression ")" + ; + +IsExpression: "is" "(" Type ")" + | "is" "(" Type ":" TypeSpecialization ")" + | "is" "(" Type "==" TypeSpecialization ")" + | "is" "(" Type ":" TypeSpecialization "," TemplateParameterList ")" + | "is" "(" Type "==" TypeSpecialization "," TemplateParameterList ")" + | "is" "(" Type identifier ")" + | "is" "(" Type identifier ":" TypeSpecialization ")" + | "is" "(" Type identifier "==" TypeSpecialization ")" + | "is" "(" Type identifier ":" TypeSpecialization "," TemplateParameterList ")" + | "is" "(" Type identifier "==" TypeSpecialization "," TemplateParameterList ")" + ; + +TypeSpecialization: Type + | "struct" + | "union" + | "class" + | "interface" + | "enum" + | "function" + | "delegate" + | "super" + | "const" + | "immutable" + | "inout" + | "shared" + | "return" + | "__parameters" + ; + +Statement: ";" + | NonEmptyStatement + | ScopeBlockStatement + ; + +NoScopeNonEmptyStatement: NonEmptyStatement + | BlockStatement + ; + +NoScopeStatement: ";" + | NonEmptyStatement + | BlockStatement + ; + +NonEmptyOrScopeBlockStatement: NonEmptyStatement + | ScopeBlockStatement + ; + +NonEmptyStatement: NonEmptyStatementNoCaseNoDefault + | CaseStatement + | CaseRangeStatement + | DefaultStatement + ; + +NonEmptyStatementNoCaseNoDefault: LabeledStatement + | ExpressionStatement + | DeclarationStatement + | IfStatement + | WhileStatement + | DoStatement + | ForStatement + | ForeachStatement + | SwitchStatement + | FinalSwitchStatement + | ContinueStatement + | BreakStatement + | ReturnStatement + | GotoStatement + | WithStatement + | SynchronizedStatement + | TryStatement + | ScopeGuardStatement + | ThrowStatement + | AsmStatement + | PragmaStatement + | MixinStatement + | ForeachRangeStatement + | ConditionalStatement + | StaticAssert + | TemplateMixin + | ImportDeclaration + ; + +ScopeStatement: NonEmptyStatement + | BlockStatement + ; + +ScopeBlockStatement: BlockStatement + ; + +LabeledStatement: identifier ":" NoScopeStatement + ; + +BlockStatement: "{" "}" + | "{" StatementList "}" + ; + +StatementList: Statement + | Statement StatementList + ; + +ExpressionStatement: Expression ";" + ; + +DeclarationStatement: Declaration + ; + +IfStatement: "if" "(" IfCondition ")" ThenStatement + | "if" "(" IfCondition ")" ThenStatement "else" ElseStatement + ; + +IfCondition: Expression + | "auto" identifier "=" Expression + | BasicType Declarator "=" Expression + ; + +ThenStatement: ScopeStatement + ; + +ElseStatement: ScopeStatement + ; + +WhileStatement: "while" "(" Expression ")" ScopeStatement + ; + +DoStatement: "do" ScopeStatement "while" "(" Expression ")" ";" + ; + +ForStatement: "for" "(" Initialize ";" ")" ScopeStatement + | "for" "(" Initialize ";" Increment ")" ScopeStatement + | "for" "(" Initialize Test ";" ")" ScopeStatement + | "for" "(" Initialize Test ";" Increment ")" ScopeStatement + ; + +Initialize: ";" + | NoScopeNonEmptyStatement + ; + +Test: Expression + ; + +Increment: Expression + ; + +ForeachStatement: Foreach "(" ForeachTypeList ";" Aggregate ")" NoScopeNonEmptyStatement + ; + +Foreach: "foreach" + | "foreach_reverse" + ; + +ForeachTypeList: ForeachType + | ForeachType "," ForeachTypeList + ; + +ForeachType: BasicType Declarator + | "ref" BasicType Declarator + | identifier + | "ref" identifier + ; + +Aggregate: Expression + ; + +ForeachRangeStatement: Foreach "(" ForeachType ";" LwrExpression ".." UprExpression ")" ScopeStatement + ; + +LwrExpression: Expression + ; + +UprExpression: Expression + ; + +SwitchStatement: "switch" "(" Expression ")" ScopeStatement + ; + +CaseStatement: "case" ArgumentList ":" ScopeStatementList + ; + +CaseRangeStatement: "case" FirstExp ":" ".." "case" LastExp ":" ScopeStatementList + ; + +FirstExp: AssignExpression + ; + +LastExp: AssignExpression + ; + +DefaultStatement: "default" ":" ScopeStatementList + ; + +ScopeStatementList: StatementListNoCaseNoDefault + ; + +StatementListNoCaseNoDefault: StatementNoCaseNoDefault + | StatementNoCaseNoDefault StatementListNoCaseNoDefault + ; + +StatementNoCaseNoDefault: ";" + | NonEmptyStatementNoCaseNoDefault + | ScopeBlockStatement + ; + +FinalSwitchStatement: "final" "switch" "(" Expression ")" ScopeStatement + ; + +ContinueStatement: "continue" ";" + | "continue" identifier ";" + ; + +BreakStatement: "break" ";" + | "break" identifier ";" + ; + +ReturnStatement: "return" ";" + | Expression ";" + ; + +GotoStatement: "goto" identifier ";" + | "goto" "default" ";" + | "goto" "case" ";" + | "goto" "case" Expression ";" + ; + +WithStatement: "with" "(" Expression ")" ScopeStatement + | "with" "(" Symbol ")" ScopeStatement + | "with" "(" TemplateInstance ")" ScopeStatement + ; + +SynchronizedStatement: "synchronized" ScopeStatement + | "synchronized" "(" Expression ")" ScopeStatement + ; + +TryStatement: "try" ScopeStatement Catches + | "try" ScopeStatement Catches FinallyStatement + | "try" ScopeStatement FinallyStatement + ; + +Catches: LastCatch + | Catch + | Catch Catches + ; + +LastCatch: "catch" NoScopeNonEmptyStatement + ; + +Catch: "catch" "(" CatchParameter ")" NoScopeNonEmptyStatement + ; + +CatchParameter: BasicType identifier + ; + +FinallyStatement: "finally" NoScopeNonEmptyStatement + ; +ThrowStatement: "throw" Expression ";" + ; + +ScopeGuardStatement: "scope" "(" "exit" ")" NonEmptyOrScopeBlockStatement + | "scope" "(" "success" ")" NonEmptyOrScopeBlockStatement + | "scope" "(" "failure" ")" NonEmptyOrScopeBlockStatement + ; + +AsmStatement: "asm" "{" "}" +/* asm { AsmInstructionList } +AsmInstructionList: AsmInstruction ";" + AsmInstruction ";" AsmInstructionList*/ + +PragmaStatement: Pragma NoScopeStatement + ; + +MixinStatement: "mixin" "(" AssignExpression ")" ";" + ; + +AggregateDeclaration: "struct" identifier StructBody + | "union" identifier StructBody + | "struct" identifier ";" + | "union" identifier ";" + | StructTemplateDeclaration + | UnionTemplateDeclaration + ; + +StructBody: "{" "}" + | "{" StructBodyDeclarations "}" + ; + +StructBodyDeclarations: StructBodyDeclaration + | StructBodyDeclaration StructBodyDeclarations + ; + +StructBodyDeclaration: DeclDef + | StructAllocator + | StructDeallocator + | StructPostblit + | AliasThis + ; + +StructAllocator: ClassAllocator + ; + +StructDeallocator: ClassDeallocator + ; + +StructPostblit: "this" "(" "this" ")" FunctionBody + ; + +ClassDeclaration: "class" identifier ClassBody + | "class" identifier BaseClassList ClassBody + | ClassTemplateDeclaration + ; + +BaseClassList: ":" SuperClass + | ":" SuperClass "," Interfaces + | ":" Interfaces + ; + +SuperClass: identifier + ; + +Interfaces: Interface + | Interface "," Interfaces + ; + +Interface: identifier + ; + +ClassBody: "{" "}" + | "{" ClassBodyDeclarations "}" + ; + +ClassBodyDeclarations: ClassBodyDeclaration + | ClassBodyDeclaration ClassBodyDeclarations + ; + +ClassBodyDeclaration: DeclDef + | Invariant + | ClassAllocator + | ClassDeallocator + ; + +Constructor: "this" Parameters FunctionBody + | TemplatedConstructor + ; + +Destructor: "~" "this" "(" ")" FunctionBody + ; + +StaticConstructor: "static" "this" "(" ")" FunctionBody + ; + +StaticDestructor: "static" "~" "this" "(" ")" FunctionBody + ; + +SharedStaticConstructor: "shared" "static" "this" "(" ")" FunctionBody + ; + +SharedStaticDestructor: "shared" "static" "~" "this" "(" ")" FunctionBody + ; + +Invariant: "invariant" "(" ")" BlockStatement + ; + +ClassAllocator: "new" Parameters FunctionBody + ; + +ClassDeallocator: "delete" Parameters FunctionBody + ; + +AliasThis: "alias" identifier "this" ";" + ; + +NewAnonClassExpression: "new" "class" + | "new" "class" Interfaces + | "new" "class" SuperClass + | "new" "class" SuperClass Interfaces + | "new" "class" ClassArguments + | "new" "class" ClassArguments Interfaces + | "new" "class" ClassArguments SuperClass + | "new" "class" ClassArguments SuperClass Interfaces + | "new" AllocatorArguments "class" + | "new" AllocatorArguments "class" Interfaces + | "new" AllocatorArguments "class" SuperClass Interfaces + | "new" AllocatorArguments "class" SuperClass + | "new" AllocatorArguments "class" ClassArguments + | "new" AllocatorArguments "class" ClassArguments SuperClass + | "new" AllocatorArguments "class" ClassArguments Interfaces + | "new" AllocatorArguments "class" ClassArguments SuperClass Interfaces + | ClassBody + ; + +ClassArguments: "(" ")" + | "(" ArgumentList ")" + ; + +InterfaceDeclaration: "interface" identifier InterfaceBody + | "interface" identifier BaseInterfaceList InterfaceBody + | InterfaceTemplateDeclaration + ; + +BaseInterfaceList: ":" Interfaces /* BUG: Spec uses InterfaceClasses here */ + ; + +InterfaceBody: "{" "}" + | "{" DeclDefs "}" + ; + + +EnumDeclaration: "enum" EnumTag EnumBody + | "enum" EnumBody + | "enum" EnumTag ":" EnumBaseType EnumBody + | "enum" ":" EnumBaseType EnumBody + ; + +EnumTag: identifier + ; + +EnumBaseType: Type + ; + +EnumBody: EmptyEnumBody + | EnumMembersBody + ; + +EmptyEnumBody: ";" + ; + +EnumMembersBody: "{" EnumMembers "}" + ; + +EnumMembers: EnumMember + | EnumMember "," + | EnumMember "," EnumMembers + ; + +EnumMember: identifier + | identifier "=" AssignExpression + | Type "=" AssignExpression + ; + +FunctionBody: BlockStatement + | BodyStatement + | InStatement BodyStatement + | OutStatement BodyStatement + | InStatement OutStatement BodyStatement + | OutStatement InStatement BodyStatement + ; + +InStatement: "in" BlockStatement + ; + +OutStatement: "out" BlockStatement + | "out" "(" identifier ")" BlockStatement + ; + +BodyStatement: "body" BlockStatement + ; + +TemplateDeclaration: "template" TemplateIdentifier TemplateParameters Constraint + | "template" TemplateIdentifier TemplateParameters + | "{" DeclDefs "}" + ; + +TemplateIdentifier: identifier + ; + +TemplateParameters: "(" ")" + | "(" TemplateParameterList ")" + ; + +TemplateParameterList: TemplateParameter + | TemplateParameter "," + | TemplateParameter "," TemplateParameterList + ; + +TemplateParameter: TemplateTypeParameter + | TemplateValueParameter + | TemplateAliasParameter + | TemplateTupleParameter + | TemplateThisParameter + ; + +TemplateInstance: TemplateIdentifier TemplateArguments + ; + +TemplateArguments: "!" "(" ")" + | "!" "(" TemplateArgumentList ")" + | "!" TemplateSingleArgument + ; + +TemplateArgumentList: TemplateArgument + | TemplateArgument "," + | TemplateArgument "," TemplateArgumentList + ; + +TemplateArgument: Type + | AssignExpression + | Symbol + ; + +Symbol: SymbolTail + | "." SymbolTail + ; + +SymbolTail: identifier + | identifier "." SymbolTail + | TemplateInstance + | TemplateInstance "." SymbolTail + ; + +TemplateSingleArgument: identifier + | BasicTypeX + | characterLiteral + | stringLiteral + | intLiteral + | floatLiteral + | "true" + | "false" + | "null" + | "this" + | "__FILE__" + | "__MODULE__" + | "__LINE__" + | "__FUNCTION__" + | "__PRETTY_FUNCTION__" + ; + +TemplateTypeParameter: identifier + | identifier TemplateTypeParameterSpecialization + | identifier TemplateTypeParameterDefault + | identifier TemplateTypeParameterSpecialization TemplateTypeParameterDefault + ; + +TemplateTypeParameterSpecialization: ":" Type + ; + +TemplateTypeParameterDefault: "=" Type + ; + +TemplateThisParameter: "this" TemplateTypeParameter + ; + +TemplateValueParameter: BasicType Declarator + | BasicType Declarator TemplateValueParameterSpecialization + | BasicType Declarator TemplateValueParameterDefault + | BasicType Declarator TemplateValueParameterSpecialization TemplateValueParameterDefault + ; + +TemplateValueParameterSpecialization: ":" ConditionalExpression + ; + +TemplateValueParameterDefault: "=" "__FILE__" + | "=" "__MODULE__" + | "=" "__LINE__" + | "=" "__FUNCTION__" + | "=" "__PRETTY_FUNCTION__" + | "=" AssignExpression + ; + +TemplateAliasParameter: "alias" identifier + | "alias" identifier TemplateAliasParameterDefault + | "alias" identifier TemplateAliasParameterSpecialization + | "alias" identifier TemplateAliasParameterSpecialization TemplateAliasParameterDefault + | "alias" BasicType Declarator + | "alias" BasicType Declarator TemplateAliasParameterDefault + | "alias" BasicType Declarator TemplateAliasParameterSpecialization + | "alias" BasicType Declarator TemplateAliasParameterSpecialization TemplateAliasParameterDefault + ; + +TemplateAliasParameterSpecialization: ":" Type + | ":" ConditionalExpression + ; + +TemplateAliasParameterDefault: "=" Type + | "=" ConditionalExpression + ; + +TemplateTupleParameter: identifier "..." + ; + +TemplatedConstructor: "this" TemplateParameters Parameters FunctionBody + | "this" TemplateParameters Parameters Constraint FunctionBody + ; + +ClassTemplateDeclaration: "class" identifier "(" TemplateParameterList ")" ClassBody + | "class" identifier "(" TemplateParameterList ")" Constraint ClassBody + | "class" identifier "(" TemplateParameterList ")" BaseClassList ClassBody + | "class" identifier "(" TemplateParameterList ")" Constraint BaseClassList ClassBody + ; + +StructTemplateDeclaration: "struct" identifier "(" TemplateParameterList ")" StructBody + | "struct" identifier "(" TemplateParameterList ")" Constraint StructBody + ; + +UnionTemplateDeclaration: "union" identifier "(" TemplateParameterList ")" StructBody + | "union" identifier "(" TemplateParameterList ")" Constraint StructBody + ; + +InterfaceTemplateDeclaration: "interface" identifier "(" TemplateParameterList ")" InterfaceBody + | "interface" identifier "(" TemplateParameterList ")" BaseInterfaceList InterfaceBody + | "interface" identifier "(" TemplateParameterList ")" Constraint InterfaceBody + | "interface" identifier "(" TemplateParameterList ")" Constraint BaseInterfaceList InterfaceBody + ; + +Constraint: "if" "(" ConstraintExpression ")" + ; + +ConstraintExpression: Expression + ; + +TemplateMixinDeclaration: "mixin" "template" TemplateIdentifier TemplateParameters + | "mixin" "template" TemplateIdentifier TemplateParameters Constraint + | "{" DeclDefs "}" + ; + +TemplateMixin: "mixin" MixinTemplateName";" + | "mixin" MixinTemplateName MixinIdentifier ";" + | "mixin" MixinTemplateName TemplateArguments ";" + | "mixin" MixinTemplateName TemplateArguments MixinIdentifier ";" + ; + +MixinTemplateName: "." QualifiedIdentifierList + | QualifiedIdentifierList + | Typeof "." QualifiedIdentifierList + ; + +QualifiedIdentifierList: identifier + | identifier "." QualifiedIdentifierList + | TemplateInstance "." QualifiedIdentifierList + ; + +MixinIdentifier: identifier + ; + +ConditionalDeclaration: Condition CCDeclarationBlock + | Condition CCDeclarationBlock "else" CCDeclarationBlock + | Condition ":" Declarations + +CCDeclarationBlock: Declaration + | "{" Declarations "}" + | "{" "}" + ; + +Declarations: Declaration + | Declaration Declarations + ; + +ConditionalStatement: Condition NoScopeNonEmptyStatement + | Condition NoScopeNonEmptyStatement "else" NoScopeNonEmptyStatement + ; + +Condition: VersionCondition + | DebugCondition + | StaticIfCondition + ; + +VersionCondition: "version" "(" intLiteral ")" + | "version" "(" identifier ")" + | "version" "(" "unittest" ")" + | "version" "(" "assert" ")" + ; + +VersionSpecification: "version" "=" identifier ";" + "version" "=" intLiteral ";" + ; + +DebugCondition: "debug" + | "debug" "(" intLiteral ")" + | "debug" "(" identifier ")" + ; + +DebugSpecification: "debug" "=" identifier ";" + | "debug" "=" intLiteral ";" + ; + +StaticIfCondition: "static" "if" "(" AssignExpression ")" + ; + +StaticAssert: "static" "assert" "(" AssignExpression ")" ";" + "static" "assert" "(" AssignExpression "," AssignExpression ")" ";" + ; + +TraitsExpression: "__traits" "(" TraitsKeyword "," TraitsArguments ")" + +TraitsKeyword: "isAbstractClass" + | "isArithmetic" + | "isAssociativeArray" + | "isFinalClass" + | "isPOD" + | "isNested" + | "isFloating" + | "isIntegral" + | "isScalar" + | "isStaticArray" + | "isUnsigned" + | "isVirtualFunction" + | "isVirtualMethod" + | "isAbstractFunction" + | "isFinalFunction" + | "isStaticFunction" + | "isRef" + | "isOut" + | "isLazy" + | "hasMember" + | "identifier" + | "getAttributes" + | "getMember" + | "getOverloads" + | "getProtection" + | "getVirtualFunctions" + | "getVirtualMethods" + | "parent" + | "classInstanceSize" + | "allMembers" + | "derivedMembers" + | "isSame" + | "compiles" + ; + +TraitsArguments: TraitsArgument + TraitsArgument "," TraitsArguments + ; + +TraitsArgument: AssignExpression + | Type + ; + +SpecialKeywords: "__FILE__" + | "__MODULE__" + | "__LINE__" + | "__FUNCTION__" + | " __PRETTY_FUNCTION__" + ; + +UnitTest: "unittest" FunctionBody + ; +%% diff --git a/std/d/ast.d b/std/d/ast.d old mode 100644 new mode 100755 index 78dd849..c3c98df --- a/std/d/ast.d +++ b/std/d/ast.d @@ -9,7 +9,32 @@ module std.d.ast; import std.container; import std.d.lexer; -interface ASTNode {} + +interface ASTVisitor +{ + /// + void visit(ASTNode node); + /// + void visit(Module node); + /// + void visit(ModuleDeclaration node); + /// + void visit(CaseStatement node); + /// + void visit(DefaultStatement node); + /// + void visit(CaseRangeStatement node); + /// + void visit(LabeledStatement node); +} + +interface ASTNode +{ + void accept(ASTVisitor visitor;) +} + +immutable string DEFAULT_ACCEPT = q{override void accept(ASTVisitor visitor) { visitor.visit(this); }}; + interface DeclDef : ASTNode {} interface AttributeSpecifier : DeclDef {} interface EnumDeclaration : DeclDef {} @@ -36,12 +61,14 @@ class Module : ASTNode { ModuleDeclaration declaration; DList!(DeclDef) declDefs; + mixin(DEFAULT_ACCEPT); } class ModuleDeclaration : ASTNode { string[] packageName; string moduleName; + mixin(DEFAULT_ACCEPT); } @@ -55,40 +82,86 @@ struct Import interface Statement : ASTNode {} -class EmptyStatement : Statement, NoScopeStatement {} +class EmptyStatement : Statement, NoScopeStatement +{ + mixin(DEFAULT_ACCEPT); +} interface NoScopeNonEmptyStatement : ASTNode {} interface NoScopeStatement : ASTNode {} interface NonEmptyStatement : NoScopeNonEmptyStatement, NoScopeStatement, Statement {} -interface NoScopeBlockStatement : Statement {} -interface NonEmptyOrScopeBlockStatement : ASTNode {} +interface NonEmptyOrScopeBlockStatement : Statement {} //BUG: The standard does not say that NonEmptyOrScopeBlockStatement is a statement interface ScopeBlockStatement : NonEmptyOrScopeBlockStatement {} interface NonEmptyStatementNoCaseNoDefault : NonEmptyStatement {} +class CaseStatement : NonEmptyStatement +{ + mixin(DEFAULT_ACCEPT); +} + +class DefaultStatement : NonEmptyStatement +{ + mixin(DEFAULT_ACCEPT); +} + +class CaseRangeStatement : NonEmptyStatement +{ + mixin(DEFAULT_ACCEPT); +} class LabeledStatement : NonEmptyStatementNoCaseNoDefault { string label; NoScopeStatement statement; + mixin(DEFAULT_ACCEPT); } interface ExpressionStatement : NonEmptyStatementNoCaseNoDefault {} interface DeclarationStatement : NonEmptyStatementNoCaseNoDefault {} -/+ +class BlockStatement : NoScopeNonEmptyStatement, ScopeBlockStatement, NoScopeStatement +{ + Statement[] statements; + mixin(DEFAULT_ACCEPT); +} + /** * $(LINK2 http://dlang.org/statement.html#IfStatement) */ class IfStatement : NonEmptyStatementNoCaseNoDefault { - + mixin(DEFAULT_ACCEPT); +} + +class WhileStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} + +class DoStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} + +class ForStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} + +class ForeachStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} + +class SwitchStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} + +class FinalSwitchStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); } -class WhileStatement : NonEmptyStatementNoCaseNoDefault {} -class DoStatement : NonEmptyStatementNoCaseNoDefault {} -class ForStatement : NonEmptyStatementNoCaseNoDefault {} -class ForeachStatement : NonEmptyStatementNoCaseNoDefault {} -class SwitchStatement : NonEmptyStatementNoCaseNoDefault {} -class FinalSwitchStatement : NonEmptyStatementNoCaseNoDefault {} /** * $(LINK http://dlang.org/statement.html#ContinueStatement) @@ -96,6 +169,7 @@ class FinalSwitchStatement : NonEmptyStatementNoCaseNoDefault {} class ContinueStatement : NonEmptyStatementNoCaseNoDefault { string identifier; + mixin(DEFAULT_ACCEPT); } /** @@ -104,8 +178,14 @@ class ContinueStatement : NonEmptyStatementNoCaseNoDefault class BreakStatement : NonEmptyStatementNoCaseNoDefault { string identifier; + mixin(DEFAULT_ACCEPT); } -class ReturnStatement : NonEmptyStatementNoCaseNoDefault {} + +class ReturnStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} + class GotoStatement : NonEmptyStatementNoCaseNoDefault { enum GotoType @@ -123,19 +203,54 @@ class GotoStatement : NonEmptyStatementNoCaseNoDefault } GotoType type; + + mixin(DEFAULT_ACCEPT); } class WithStatement : NonEmptyStatementNoCaseNoDefault {} -class SynchronizedStatement : NonEmptyStatementNoCaseNoDefault {} -class TryStatement : NonEmptyStatementNoCaseNoDefault {} -class ScopeGuardStatement : NonEmptyStatementNoCaseNoDefault {} -class ThrowStatement : NonEmptyStatementNoCaseNoDefault {} -class AsmStatement : NonEmptyStatementNoCaseNoDefault {} -class PragmaStatement : NonEmptyStatementNoCaseNoDefault {} -class MixinStatement : NonEmptyStatementNoCaseNoDefault {} -class ForeachRangeStatement : NonEmptyStatementNoCaseNoDefault {} -class ConditionalStatement : NonEmptyStatementNoCaseNoDefault {} -class StaticAssert : NonEmptyStatementNoCaseNoDefault, DeclDef {} -class TemplateMixin : NonEmptyStatementNoCaseNoDefault, DeclDef {} +class SynchronizedStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} +class TryStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} +class ScopeGuardStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} +class ThrowStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} +class AsmStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} +class PragmaStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} +class MixinStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} +class ForeachRangeStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} +class ConditionalStatement : NonEmptyStatementNoCaseNoDefault +{ + mixin(DEFAULT_ACCEPT); +} +class StaticAssert : NonEmptyStatementNoCaseNoDefault, DeclDef +{ + mixin(DEFAULT_ACCEPT); +} +class TemplateMixin : NonEmptyStatementNoCaseNoDefault, DeclDef +{ + mixin(DEFAULT_ACCEPT); +} class ImportDeclaration : NonEmptyStatementNoCaseNoDefault, DeclDef { bool isStatic; @@ -143,16 +258,15 @@ class ImportDeclaration : NonEmptyStatementNoCaseNoDefault, DeclDef } -class BlockStatement : NoScopeNonEmptyStatement, ScopeBlockStatement -{ - Statement[] statements; -} + interface Expression : ASTNode {} + class CommaExpression : Expression { AssignExpression left; AssignExpression right; + mixin(DEFAULT_ACCEPT); } class AssignExpression @@ -165,21 +279,23 @@ class AssignExpression { assert ( operator == TokenType.assign - || operator == TokenType.plusEquals - || operator == TokenType.minusEquals - || operator == TokenType.mulEquals - || operator == TokenType.divEquals - || operator == TokenType.modEquals - || operator == TokenType.bitAndEquals - || operator == TokenType.bitOrEquals - || operator == TokenType.xorEquals - || operator == TokenType.catEquals + || operator == TokenType.plusEqual + || operator == TokenType.minusEqual + || operator == TokenType.mulEqual + || operator == TokenType.divEqual + || operator == TokenType.modEqual + || operator == TokenType.bitAndEqual + || operator == TokenType.bitOrEqual + || operator == TokenType.xorEqual + || operator == TokenType.catEqual || operator == TokenType.shiftLeftEqual || operator == TokenType.shiftRightEqual || operator == TokenType.unsignedShiftRightEqual - || operator == TokenType.powEquals + || operator == TokenType.powEqual ); } + + mixin(DEFAULT_ACCEPT); } interface ConditionalExpression : Expression {} @@ -191,6 +307,8 @@ class TernaryExpression : ConditionalExpression Expression middle; /// Null unless this is a ternary ConditionalExpression right; + + mixin(DEFAULT_ACCEPT); } interface OrOrExpression : ConditionalExpression {} @@ -208,6 +326,7 @@ interface UnaryExpression : MulExpression {} class ComplementaryExpression : UnaryExpression { UnaryExpression unary; + mixin(DEFAULT_ACCEPT); } interface NewExpression : UnaryExpression {} interface DeleteExpression : UnaryExpression {} @@ -219,21 +338,64 @@ interface PrimaryExpression : Expression {} class SingleTokenExpression { Token token; + mixin(DEFAULT_ACCEPT); +} +class ThisExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class SuperExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class NullExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class TrueExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class FalseExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class DollarExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class FileExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class LineExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class IntegerExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class FloatExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class CharacterExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class StringExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class IdentifierExpression : SingleTokenExpression +{ + mixin(DEFAULT_ACCEPT); +} +class ArrayExpression : PrimaryExpression +{ + mixin(DEFAULT_ACCEPT); } -class ThisExpression : SingleTokenExpression {} -class SuperExpression : SingleTokenExpression {} -class NullExpression : SingleTokenExpression {} -class TrueExpression : SingleTokenExpression {} -class FalseExpression : SingleTokenExpression {} -class DollarExpression : SingleTokenExpression {} -class FileExpression : SingleTokenExpression {} -class LineExpression : SingleTokenExpression {} -class IntegerExpression : SingleTokenExpression {} -class FloatExpression : SingleTokenExpression {} -class CharacterExpression : SingleTokenExpression {} -class StringExpression : SingleTokenExpression {} -class IdentifierExpression : SingleTokenExpression {} -class ArrayExpression : PrimaryExpression {} @@ -244,159 +406,12 @@ class RelExpression : CmpExpression ShiftExpression left; ShiftExpression right; TokenType operator; + mixin(DEFAULT_ACCEPT); } class Parameter : ASTNode { - - string[] inOut; + TokenType[] inOut; string type; + mixin(DEFAULT_ACCEPT); } - -/+ -// Copyright Brian Schott (Sir Alaran) 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -module basicast; - -import std.d.lexer; - -struct Scope -{ - size_t begin; - size_t end; - Scope* parent; -} - -struct ModuleDeclaration -{ - string[] package_; - string name; -} - -struct Module -{ - ModuleDeclaration moduleDeclaration; - VariableDeclaration[] variables; - FunctionDeclaration[] functions; - Enum[] enums; - Scope*[] scopes; -} - -enum DeclDefType : ubyte -{ - attributeSpecifier, - importDeclaration, - enumDeclaration, - classDeclaration, - interfaceDeclaration, - aggregateDeclaration, - declaration, - constructor, - destructor, - unitTest, - staticConstructor, - staticDestructor, - sharedStaticConstructor, - sharedStaticDestructor, - conditionalDeclaration, - debugSpecification, - versionSpecification, - staticAssert, - templatedeclaration, - templateMixinDeclaration, - templateMixin, - mixinDeclaration, - semicolon -} - -class DeclDef -{ - DeclDefType type; -} - -struct Enum -{ - bool singleValue; - EnumMember[] members; - string baseType; -} - -struct AttributeList -{ -public: - - void set(TokenType attribute) - in - { - assert(isAttribute(attribute)); - } - body - { - attributes ~= attribute; - } - - const(TokenType)[] get() - { - return attributes[]; - } - -private: - - TokenType[] attributes; -} - -struct Parameter -{ - string name; - string type; - string def; -} - -struct FunctionDeclaration -{ - AttributeList attributes; - Parameter[] ctParameters; - Parameter[] rtParameters; - string returnType; - string name; - uint line; -} - -struct VariableDeclaration -{ - AttributeList attributes; - string name; - string type; - uint line; -} - -struct Import -{ - struct ImportSymbol - { - string symbolName; - string alias_; - } - - string alias_; - string moduleName; - string[] packageParts; - ImportSymbol[] symbols; -} - -class ImportDeclaration : DeclDef -{ - Import[] imports; -} - -class Inherits : DeclDef -{ - //FunctionDeclaration[] functions; -} -+/ - - -+/ diff --git a/std/d/entities.d b/std/d/entities.d old mode 100644 new mode 100755 diff --git a/std/d/lexer.d b/std/d/lexer.d old mode 100644 new mode 100755 index 896cf91..483ac2d --- a/std/d/lexer.d +++ b/std/d/lexer.d @@ -1879,7 +1879,7 @@ pure nothrow bool isKeyword(ref const Token t) /** * Returns: true if the token is a built-in type */ -pure nothrow bool isType(const TokenType t) +pure nothrow bool isBasicType(const TokenType t) { return t >= TokenType.bool_ && t <= TokenType.wchar_; } @@ -1887,7 +1887,7 @@ pure nothrow bool isType(const TokenType t) /** * ditto */ -pure nothrow bool isType(ref const Token t) +pure nothrow bool isBasicType(ref const Token t) { return isType(t.type); } @@ -2114,10 +2114,10 @@ enum TokenType: ushort const_, /// $(D_KEYWORD const) final_, /// $(D_KEYWORD final) gshared, /// $(D_KEYWORD __gshared) - immutable_, // immutable - inout_, // inout + immutable_, /// $(D_KEYWORD immutable) + inout_, /// $(D_KEYWORD inout) scope_, /// $(D_KEYWORD scope) - shared_, // shared + shared_, /// $(D_KEYWORD shared) static_, /// $(D_KEYWORD static) synchronized_, /// $(D_KEYWORD synchronized) @@ -2190,7 +2190,7 @@ enum TokenType: ushort line, /// $(D_KEYWORD ___LINE__) comment, /// $(D_COMMENT /** comment */) or $(D_COMMENT // comment) or $(D_COMMENT ///comment) identifier, /// anything else - scriptLine, // Line at the beginning of source file that starts from #! + scriptLine, /// Line at the beginning of source file that starts from #! traits, /// $(D_KEYWORD ___traits) parameters, /// $(D_KEYWORD ___parameters) vector, /// $(D_KEYWORD ___vector) diff --git a/std/d/parser.d b/std/d/parser.d old mode 100644 new mode 100755 index e49e025..706b21d --- a/std/d/parser.d +++ b/std/d/parser.d @@ -10,10 +10,17 @@ import std.d.lexer; import std.d.ast; version(unittest) import std.stdio; +Module parseModule(R)(R tokens) if (is (ElementType!R == Token)) +{ + auto parser = new Parser(); + parser.tokens = tokens.array(); + return parser.parseModule(); +} + +private: + struct Parser { -public: - Module parseModule() { Module m = new Module; @@ -34,8 +41,6 @@ public: return m; } -private: - ModuleDeclaration parseModuleDeclaration() in { @@ -74,46 +79,239 @@ private: { switch (tokens[index].type) { -// case TokenType.identifier: -// if (nextIs(TokenType.colon)) -// return parseLabeledStatement(); -// break; -// case TokenType.this_: -// return parseConstructor(); -// case TokenType.tilde: -// if (nextIs(TokenType.this_)) -// return parseDestructor(); -// break; default: return null; } } -// LabeledStatement parseLabeledStatement() -// in -// { -// assert (tokens[index].type == TokenType.identifier); -// } -// body -// { -// auto ls = new LabeledStatement; -// ls.label = tokens[index++].value; -// ls.statement = parseNoScopeStatement(); -// return ls; -// } -// NoScopeStatement parseNoScopeStatement() -// { -// switch (tokens[index].type) -// { -// case TokenType.semicolon: -// return new EmptyStatement; -// case TokenType.lBrace: -// return parseBlockStatement(); -// default: -// return parseNonEmptyStatement(); -// } -// } + + LabeledStatement parseLabeledStatement() + in + { + assert (tokens[index].type == TokenType.identifier); + } + body + { + auto ls = new LabeledStatement; + ls.label = tokens[index++].value; + ls.statement = parseNoScopeStatement(); + return ls; + } + + NoScopeStatement parseNoScopeStatement() + { + switch (tokens[index].type) + { + case TokenType.semicolon: + return new EmptyStatement; + case TokenType.lBrace: + return parseBlockStatement(); + default: + return parseNonEmptyStatement(); + } + } + + NonEmptyStatement parseNonEmptyStatement() + { + switch (tokens[index].type) + { + case TokenType.case_: + return parseCaseStatement(); + case TokenType.default_: + return parseDefaultStatement(); + default: + return null; + } + } + + CaseStatement parseCaseStatement() + { + return null; + } + + DefaultStatement parseDefaultStatement() + { + return null; + } + + Statement parseStatement() + { + return null; + } + + BlockStatement parseBlockStatement() + { + auto statement = new BlockStatement(); + expect(TokenType.lBrace); + switch (tokens[index].type) + { + case TokenType.rBrace: + break; + default: + statement.statements ~= parseStatement(); + } + return statement; + } + + GotoStatement parseGotoStatement() + { + expect(TokenType.goto_); + auto g = new GotoStatement; + switch (tokens[index].type) + { + case TokenType.identifier: + g.type = GotoStatement.GotoType.identifier; + g.identifier = tokens[index++].value; + break; + case TokenType.default_: + index++; + g.type = GotoStatement.GotoType.default_; + break; + case TokenType.case_: + g.type = GotoStatement.GotoType.case_; + index++; + break; + default: + error("Expected an identifier, \"default\", or \"case\" following \"goto\""); + return null; + } + return g; + } + + ContinueStatement parseContinueStatement() + { + expect(TokenType.continue_); + return parseContinueBreakStatement!(ContinueStatement)(); + } + + BreakStatement parseBreakStatement() + { + expect(TokenType.break_); + return parseContinueBreakStatement!(BreakStatement)(); + } + + statementType parseContinueBreakStatement(alias statementType)() + { + index++; + auto c = new statementType; + switch (tokens[index].type) + { + case TokenType.identifier: + c.identifier = tokens[index++].value; + goto case; + case TokenType.semicolon: + return c; + default: + error("Identifier or semicolon expected"); + return null; + } + + } + + ImportDeclaration parseImportDeclaration(Tokens)(ref Tokens tokens) + in + { + assert(tokens[i] == TokenType.import_); + } + body + { + auto declaration = new ImportDeclaration; + tokens.popFront(); + Import im; + + if (tokens[i].type != TokenType.identifier) + { + tokens.skipPastSemicolon(); + return declaration; + } + + void completeImport() + { + im.moduleName = tokens.moveFront().value; + tokens.popFront(); + declaration.imports ~= im; + } + + void parseImportBindings() + { + loop: while (!tokens.empty) + { + if (tokens[i].type != TokenType.identifier) + break; + switch (tokens.peek().type) + { + case TokenType.assign: + Import.ImportSymbol s; + s.alias_ = tokens.moveFront().value; + tokens.popFront(); + if (tokens.empty || tokens[i].type != TokenType.identifier) + break loop; + s.symbolName = tokens.moveFront().value; + im.symbols ~= s; + if (!tokens.empty()) + { + if (tokens[i].type == TokenType.comma) + tokens.popFront(); + if (tokens[i].type == TokenType.semicolon) + { + tokens.popFront(); + declaration.imports ~= im; + break loop; + } + } + break; + case TokenType.comma: + Import.ImportSymbol s; + s.symbolName = tokens.moveFront().value; + tokens.popFront(); + im.symbols ~= s; + break; + case TokenType.semicolon: + Import.ImportSymbol s; + s.symbolName = tokens.moveFront().value; + tokens.popFront(); + im.symbols ~= s; + declaration.imports ~= im; + break loop; + default: + break loop; + } + } + } + + loop: while (!tokens.empty) + { + switch (tokens.peek().type) + { + case TokenType.dot: + im.packageParts ~= tokens.moveFront().value; + tokens.popFront(); + break; + case TokenType.comma: + completeImport(); + im = Import.init; + break; + case TokenType.semicolon: + completeImport(); + break loop; + case TokenType.colon: + im.moduleName = tokens.moveFront().value; + tokens.popFront(); + parseImportBindings(); + break loop; + case TokenType.assign: + im.alias_ = tokens.moveFront().value; + tokens.popFront(); + break; + default: + tokens.popFront(); + break; + } + } + + return declaration; + } void error(string message) { @@ -186,6 +384,16 @@ private: return peek() && peek().type == t; } + bool startsWith(TokenType types...) + { + for (size_t i = 0; i != types.length; ++i) + { + if (tokens[index + i].type != types[i]) + return false; + } + return true; + } + bool moreTokens() { return index < tokens.length; @@ -196,6 +404,57 @@ private: string fileName; } +unittest +{ + auto source = cast(ubyte[]) q{import std.stdio; + import std.ascii: hexDigits; + import r = std.range; + import foo, bar; + import std.stdio : writefln, foo = writef;}c; + + LexerConfig config; + auto tokens = source.byToken(config).circularBuffer(4); + assert (tokens[i] == "import"); + + auto decl = parseImportDeclaration(tokens); + assert (decl.imports.length == 1); + assert (decl.imports[0].packageParts == ["std"]); + assert (decl.imports[0].moduleName == "stdio"); + assert (tokens[i].value == "import", tokens.front.value); + assert (tokens.peek(3).value == "ascii", tokens.front.value); + + decl = parseImportDeclaration(tokens); + assert (decl.imports.length == 1, "%d".format(decl.imports.length)); + assert (decl.imports[0].packageParts == ["std"]); + assert (decl.imports[0].moduleName == "ascii", decl.imports[0].moduleName); + assert (decl.imports[0].symbols[0].symbolName == "hexDigits", decl.imports[0].symbols[0].symbolName); + assert (decl.imports[0].symbols[0].alias_.length == 0); + + decl = parseImportDeclaration(tokens); + assert (decl.imports.length == 1, "%s".format(decl.imports.length)); + assert (decl.imports[0].moduleName == "range"); + assert (decl.imports[0].packageParts == ["std"]); + assert (decl.imports[0].alias_ == "r"); + + decl = parseImportDeclaration(tokens); + assert (decl.imports.length == 2); + assert (decl.imports[0].packageParts.length == 0); + assert (decl.imports[0].moduleName == "foo"); + assert (decl.imports[1].packageParts.length == 0); + assert (decl.imports[1].moduleName == "bar"); + + decl = parseImportDeclaration(tokens); + assert (decl.imports.length == 1, "%s".format(decl.imports.length)); + assert (decl.imports[0].packageParts == ["std"]); + assert (decl.imports[0].moduleName == "stdio"); + assert (decl.imports[0].symbols.length == 2); + assert (decl.imports[0].symbols[0].symbolName == "writefln"); + assert (decl.imports[0].symbols[1].symbolName == "writef"); + assert (decl.imports[0].symbols[1].alias_ == "foo"); +} + + + // //unittest //{ @@ -320,70 +579,7 @@ private: // } //} // -//GotoStatement parseGotoStatement(Token[] tokens) -//in -//{ -// assert (tokens[i] == TokenType.goto_); -//} -//body -//{ -// tokens.popFront(); -// auto g = new GotoExpression; -// switch (tokens[i].type) -// { -// case TokenType.identifier: -// g.type = GotoStatement.GotoType.identifier; -// g.identifier = tokens.moveFront().value; -// break; -// case TokenType.default_: -// tokens.popFront(); -// g.type = GotoStatement.GotoType.break_; -// case TokenType.case_: -// g.type = GotoStatement.GotoType.case_; -// tokens.popFront(); -// default: -// error(tokens, "Expected an identifier, \"default\", or \"case\" following \"goto\""); -// return null; -// } -//} -// -//ContinueStatement parseContinueStatement(Token[] tokens) -//in -//{ -// assert (tokens[i] == TokenType.continue_); -//} -//body -//{ -// return parseContinueBreakStatement!(R, ContinueStatement)(tokens); -//} -// -//BreakStatement parseBreakStatement(Token[] tokens) -//in -//{ -// assert (tokens[i] == TokenType.break_); -//} -//body -//{ -// return parseBreakStatement!(R, BreakStatement)(tokens); -//} -// -//statementType parseContinueBreakStatement(R, alias statementType)(ref R tokens) -//{ -// tokens.popFront(); -// auto c = new statementType; -// switch (tokens[i].type) -// { -// case TokenType.identifier: -// c.identifier = tokens.moveFront().value; -// goto case; -// case TokenType.semicolon: -// return c; -// default: -// error(tokens, "Identifier or semicolon expected"); -// return null; -// } -// -//} + // // //T parseSingleTokenExpression(TokType, AstType, R)(ref R range) @@ -421,278 +617,15 @@ private: // return expr; //} -//void main(string[] args) {} - /+ -// Copyright Brian Schott (Sir Alaran) 2012. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -module parser; - -import std.d.lexer; -import std.range; -import basicast; -version (unittest) import std.stdio; -version (unittest) import std.string; - -void skipPastSemicolon(Tokens)(ref Tokens tokens) -{ - while (!tokens.empty) - { - if (tokens[i].type == TokenType.semicolon) - { - tokens.popFront(); - return; - } - else - tokens.popFront(); - } -} - -void skipDelimited(Tokens, alias O, alias C)(ref Tokens tokens) -in -{ - assert (tokens[i].type == O); -} -body -{ - tokens.popFront(); - int depth = 1; - while (!tokens.empty) - { - switch (tokens[i].type) - { - case C: - --depth; - if (depth > 0) - goto default; - tokens.popFront(); - return; - case O: - ++depth; - goto default; - default: - tokens.popFront(); - break; - } - } -} - -void skipBraces(Tokens)(ref Tokens tokens) -{ - return skipDelimited!(Tokens, TokenType.lBrace, TokenType.rBrace)(tokens); -} - -void skipParens(Tokens)(ref Tokens tokens) -{ - return skipDelimited!(Tokens, TokenType.lParen, TokenType.rParen)(tokens); -} - -void skipBrackets(Tokens)(ref Tokens tokens) -{ - return skipDelimited!(Tokens, TokenType.lBracket, TokenType.rBracket)(tokens); -} - -string delimiterContent(Tokens, alias O, alias C)(ref Tokens tokens) -{ - tokens.popFront(); - int depth = 1; - auto app = appender!(char[])(); - loop: while (!tokens.empty) - { - switch (tokens[i].type) - { - case C: - --depth; - if (depth > 0) - goto default; - tokens.popFront(); - break loop; - case O: - ++depth; - goto default; - default: - app.put(tokens.moveFront().value); - break; - } - } - return cast(string) app.data; -} - -string bracketContent(Tokens)(ref Tokens tokens) -{ - return "[" ~ delimiterContent!(Tokens, TokenType.lBracket, TokenType.rBracket)(tokens) ~ "]"; -} - -string parenContent(Tokens)(ref Tokens tokens) -{ - return "(" ~ delimiterContent!(Tokens, TokenType.lParen, TokenType.rParen)(tokens) ~ ")"; -} - -string braceContent(Tokens)(ref Tokens tokens) -{ - return "{" ~ delimiterContent!(Tokens, TokenType.lBrace, TokenType.rBrace)(tokens) ~ "}"; -} bool isIdentifierOrBasicType(const TokenType type) { return isType(type) || type == TokenType.identifier; } -ImportDeclaration parseImportDeclaration(Tokens)(ref Tokens tokens) -in -{ - assert(tokens[i] == TokenType.import_); -} -body -{ - auto declaration = new ImportDeclaration; - tokens.popFront(); - Import im; - if (tokens[i].type != TokenType.identifier) - { - tokens.skipPastSemicolon(); - return declaration; - } - - void completeImport() - { - im.moduleName = tokens.moveFront().value; - tokens.popFront(); - declaration.imports ~= im; - } - - void parseImportBindings() - { - loop: while (!tokens.empty) - { - if (tokens[i].type != TokenType.identifier) - break; - switch (tokens.peek().type) - { - case TokenType.assign: - Import.ImportSymbol s; - s.alias_ = tokens.moveFront().value; - tokens.popFront(); - if (tokens.empty || tokens[i].type != TokenType.identifier) - break loop; - s.symbolName = tokens.moveFront().value; - im.symbols ~= s; - if (!tokens.empty()) - { - if (tokens[i].type == TokenType.comma) - tokens.popFront(); - if (tokens[i].type == TokenType.semicolon) - { - tokens.popFront(); - declaration.imports ~= im; - break loop; - } - } - break; - case TokenType.comma: - Import.ImportSymbol s; - s.symbolName = tokens.moveFront().value; - tokens.popFront(); - im.symbols ~= s; - break; - case TokenType.semicolon: - Import.ImportSymbol s; - s.symbolName = tokens.moveFront().value; - tokens.popFront(); - im.symbols ~= s; - declaration.imports ~= im; - break loop; - default: - break loop; - } - } - } - - loop: while (!tokens.empty) - { - switch (tokens.peek().type) - { - case TokenType.dot: - im.packageParts ~= tokens.moveFront().value; - tokens.popFront(); - break; - case TokenType.comma: - completeImport(); - im = Import.init; - break; - case TokenType.semicolon: - completeImport(); - break loop; - case TokenType.colon: - im.moduleName = tokens.moveFront().value; - tokens.popFront(); - parseImportBindings(); - break loop; - case TokenType.assign: - im.alias_ = tokens.moveFront().value; - tokens.popFront(); - break; - default: - tokens.popFront(); - break; - } - } - - return declaration; -} - -unittest -{ - auto source = cast(ubyte[]) q{import std.stdio; - import std.ascii: hexDigits; - import r = std.range; - import foo, bar; - import std.stdio : writefln, foo = writef;}c; - - LexerConfig config; - auto tokens = source.byToken(config).circularBuffer(4); - assert (tokens[i] == "import"); - - auto decl = parseImportDeclaration(tokens); - assert (decl.imports.length == 1); - assert (decl.imports[0].packageParts == ["std"]); - assert (decl.imports[0].moduleName == "stdio"); - assert (tokens[i].value == "import", tokens.front.value); - assert (tokens.peek(3).value == "ascii", tokens.front.value); - - decl = parseImportDeclaration(tokens); - assert (decl.imports.length == 1, "%d".format(decl.imports.length)); - assert (decl.imports[0].packageParts == ["std"]); - assert (decl.imports[0].moduleName == "ascii", decl.imports[0].moduleName); - assert (decl.imports[0].symbols[0].symbolName == "hexDigits", decl.imports[0].symbols[0].symbolName); - assert (decl.imports[0].symbols[0].alias_.length == 0); - - decl = parseImportDeclaration(tokens); - assert (decl.imports.length == 1, "%s".format(decl.imports.length)); - assert (decl.imports[0].moduleName == "range"); - assert (decl.imports[0].packageParts == ["std"]); - assert (decl.imports[0].alias_ == "r"); - - decl = parseImportDeclaration(tokens); - assert (decl.imports.length == 2); - assert (decl.imports[0].packageParts.length == 0); - assert (decl.imports[0].moduleName == "foo"); - assert (decl.imports[1].packageParts.length == 0); - assert (decl.imports[1].moduleName == "bar"); - - decl = parseImportDeclaration(tokens); - assert (decl.imports.length == 1, "%s".format(decl.imports.length)); - assert (decl.imports[0].packageParts == ["std"]); - assert (decl.imports[0].moduleName == "stdio"); - assert (decl.imports[0].symbols.length == 2); - assert (decl.imports[0].symbols[0].symbolName == "writefln"); - assert (decl.imports[0].symbols[1].symbolName == "writef"); - assert (decl.imports[0].symbols[1].alias_ == "foo"); -} string parseType(Tokens)(ref Tokens tokens) { @@ -1096,9 +1029,8 @@ body return decl; } ++/ void main(string[] args) { } - -+/