예제 #1
0
        public void DeclDef(DBlockNode module)
        {
            if (IsAttributeSpecifier) {
                do
                    AttributeSpecifier (module);
                while(IsAttributeSpecifier);

                var tkind = t.Kind;
                if(tkind == Semicolon || tkind == CloseCurlyBrace || tkind == Colon)
                    return;
            }

            if (laKind == Semicolon)
            {
                Step();
                return;
            }

            switch (laKind)
            {
                case Import:
                    module.Add(ImportDeclaration(module));
                    break;
                case This:
                    module.Add(Constructor(module, module is DClassLike && ((DClassLike)module).ClassType == DTokens.Struct));
                    break;
                case Tilde:
                    if (Lexer.CurrentPeekToken.Kind != This)
                        goto default;
                    module.Add(Destructor());
                    break;
                case Invariant:
                    module.Add(_Invariant());
                    break;
                case Unittest:
                    Step();
                    var dbs = new DMethod(DMethod.MethodType.Unittest);
                    ApplyAttributes(dbs);
                    dbs.Location = t.Location;
                    FunctionBody(dbs);
                    dbs.EndLocation = t.EndLocation;
                    module.Add(dbs);
                    break;
                /*
                 * VersionSpecification:
                 *		version = Identifier ;
                 *		version = IntegerLiteral ;
                 *
                 * DebugSpecification:
                 *		debug = Identifier ;
                 *		debug = IntegerLiteral ;
                 */
                case Version:
                case Debug:
                    if (Peek(1).Kind == Assign)
                    {
                        DebugSpecification ds = null;
                        VersionSpecification vs = null;

                        if (laKind == Version)
                            vs = new VersionSpecification {
                                Location = la.Location,
                                Attributes = GetCurrentAttributeSet_Array()
                            };
                        else
                            ds = new DebugSpecification {
                                Location = la.Location,
                                Attributes = GetCurrentAttributeSet_Array()
                            };

                        Step();
                        Step();

                        if (laKind == Literal)
                        {
                            Step();
                            if (t.LiteralFormat != LiteralFormat.Scalar)
                                SynErr(t.Kind, "Integer literal expected!");
                            try
                            {
                                if (vs != null)
                                    vs.SpecifiedNumber = Convert.ToInt32(t.LiteralValue);
                                else
                                    ds.SpecifiedDebugLevel = Convert.ToInt32(t.LiteralValue);
                            }
                            catch
                            {
                            }
                        }
                        else if (laKind == Identifier)
                        {
                            Step();
                            if (vs != null)
                                vs.SpecifiedId = t.Value;
                            else
                                ds.SpecifiedId = t.Value;
                        }
                        else if (ds == null)
                            Expect(Identifier);

                        Expect(Semicolon);

                        ((AbstractStatement)ds ?? vs).EndLocation = t.EndLocation;

                        module.Add(vs as StaticStatement ?? ds);
                    }
                    else
                        DeclarationCondition(module);
                    break;
                case Static:
                    if (Lexer.CurrentPeekToken.Kind == If)
                        goto case Version;
                    goto default;
                case Assert:
                    Step();
                    CheckForStorageClasses(module);
                    if (!Modifier.ContainsAttribute(DeclarationAttributes, Static))
                        SynErr(Static, "Static assert statements must be explicitly marked as static");

                    var ass = new StaticAssertStatement {
                        Attributes = GetCurrentAttributeSet_Array(),
                        Location = t.Location
                    };

                    if (Expect(OpenParenthesis))
                    {
                        ass.AssertedExpression = AssignExpression();
                        if (laKind == (Comma))
                        {
                            Step();
                            ass.Message = AssignExpression();
                        }
                        if (Expect(CloseParenthesis))
                            Expect(Semicolon);
                    }

                    ass.EndLocation = t.EndLocation;

                    module.Add(ass);
                    break;
                case Mixin:
                    if (Peek(1).Kind == Template)
                        module.Add(TemplateDeclaration(module));

                    //TemplateMixin
                    else if (Lexer.CurrentPeekToken.Kind == Identifier)
                    {
                        var tmx = TemplateMixin(module);
                        if (tmx.MixinId == null)
                            module.Add(tmx);
                        else
                            module.Add(new NamedTemplateMixinNode(tmx));
                    }

                    //MixinDeclaration
                    else if (Lexer.CurrentPeekToken.Kind == OpenParenthesis)
                        module.Add(MixinDeclaration(module, null));
                    else
                    {
                        Step();
                        SynErr(Identifier);
                    }
                    break;
                case OpenCurlyBrace:
                    AttributeBlock(module);
                    break;
                // Class Allocators
                // Note: Although occuring in global scope, parse it anyway but declare it as semantic nonsense;)
                case New:
                    Step();

                    var dm = new DMethod(DMethod.MethodType.Allocator) { Location = t.Location };
                    ApplyAttributes(dm);

                    dm.Parameters = Parameters(dm);
                    FunctionBody(dm);
                    dm.EndLocation = t.EndLocation;
                    module.Add(dm);
                    break;
                case Delete:
                    Step();

                    var ddm = new DMethod(DMethod.MethodType.Deallocator) { Location = t.Location };
                    ddm.Name = "delete";
                    ApplyAttributes(ddm);

                    ddm.Parameters = Parameters(ddm);
                    FunctionBody(ddm);
                    ddm.EndLocation = t.EndLocation;
                    module.Add(ddm);
                    break;
                default:
                    var decls = Declaration(module);
                    if(module != null && decls!=null)
                        module.AddRange(decls);
                    break;
            }
        }
예제 #2
0
        IMetaDeclarationBlock AttributeBlock(DBlockNode module)
        {
            int popCount = DeclarationAttributes.Count;

            /*
             * If there are attributes given, put their references into the meta block.
             * Also, pop them from the declarationAttributes stack on to the block attributes so they will be assigned to all child items later on.
             */

            IMetaDeclarationBlock metaDeclBlock;

            if (popCount != 0)
                metaDeclBlock = new AttributeMetaDeclarationBlock(DeclarationAttributes.ToArray()) { BlockStartLocation = la.Location };
            else
                metaDeclBlock = new MetaDeclarationBlock { BlockStartLocation = la.Location };

            while (DeclarationAttributes.Count > 0)
                BlockAttributes.Push(DeclarationAttributes.Pop());

            ClassBody(module, true, false);

            // Pop the previously pushed attributes back off the stack
            for (int i = popCount; i > 0; i--)
                BlockAttributes.Pop();

            // Store the meta block
            metaDeclBlock.EndLocation = t.EndLocation;
            if(module!=null)
                module.Add(metaDeclBlock);
            return metaDeclBlock;
        }
예제 #3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="module"></param>
        /// <param name="previouslyParsedAttribute"></param>
        /// <param name="RequireDeclDef">If no colon and no open curly brace is given as lookahead, a DeclDef may be parsed otherwise, if parameter is true.</param>
        /// <returns></returns>
        IMetaDeclaration AttributeTrail(DBlockNode module, DAttribute previouslyParsedAttribute, bool RequireDeclDef = false)
        {
            if (laKind == Colon)
            {
                Step();
                PushAttribute(previouslyParsedAttribute, true);

                AttributeMetaDeclarationSection metaDecl = null;
                //TODO: Put all remaining block/decl(?) attributes into the section definition..
                if(module!=null)
                    module.Add(metaDecl = new AttributeMetaDeclarationSection(previouslyParsedAttribute) { EndLocation = t.EndLocation });
                return metaDecl;
            }
            else
                PushAttribute(previouslyParsedAttribute, false);

            if (laKind == OpenCurlyBrace)
                return AttributeBlock(module);
            else
            {
                if (IsEOF && module != null && previouslyParsedAttribute != null) // To enable attribute completion, add dummy node
                    module.Add (new DVariable{ Attributes = new List<DAttribute>{ previouslyParsedAttribute } });

                if (RequireDeclDef)
                    DeclDef(module);
                return new AttributeMetaDeclaration(previouslyParsedAttribute) { EndLocation = previouslyParsedAttribute.EndLocation };
            }
        }
예제 #4
0
        void DeclDef(DBlockNode module)
        {
            //AttributeSpecifier
            while (IsAttributeSpecifier())
            {
                AttributeSpecifier(module);

                if (t.Kind == Colon || laKind == CloseCurlyBrace || IsEOF)
                    return;
            }

            if (laKind == Semicolon)
            {
                LastParsedObject = null;
                Step();
                return;
            }

            //ImportDeclaration
            if (laKind == Import)
                module.Add(ImportDeclaration(module));

            //Constructor
            else if (laKind == (This))
                module.Add(Constructor(module, module is DClassLike ? ((DClassLike)module).ClassType == DTokens.Struct : false));

            //Destructor
            else if (laKind == (Tilde) && Lexer.CurrentPeekToken.Kind == (This))
                module.Add(Destructor());

            //Invariant
            else if (laKind == (Invariant))
                module.Add(_Invariant());

            //UnitTest
            else if (laKind == (Unittest))
            {
                Step();
                var dbs = new DMethod(DMethod.MethodType.Unittest);
                ApplyAttributes(dbs);
                LastParsedObject = dbs;
                dbs.Location = t.Location;
                FunctionBody(dbs);
                dbs.EndLocation = t.EndLocation;
                module.Add(dbs);
            }

            /*
             * VersionSpecification:
             *		version = Identifier ;
             *		version = IntegerLiteral ;
             *
             * DebugSpecification:
             *		debug = Identifier ;
             *		debug = IntegerLiteral ;
             */
            else if ((laKind == Version || laKind == Debug) && Peek(1).Kind == Assign)
            {
                DebugSpecification ds = null;
                VersionSpecification vs = null;

                if (laKind == Version)
                    LastParsedObject = vs = new VersionSpecification { Location = la.Location, Attributes = GetCurrentAttributeSet_Array() };
                else
                    LastParsedObject = ds = new DebugSpecification { Location = la.Location, Attributes = GetCurrentAttributeSet_Array() };

                Step();
                Step();

                if (laKind == Literal)
                {
                    Step();
                    if (t.LiteralFormat != LiteralFormat.Scalar)
                        SynErr(t.Kind, "Integer literal expected!");
                    try
                    {
                        if (vs != null)
                            vs.SpecifiedNumber = Convert.ToInt32(t.LiteralValue);
                        else
                            ds.SpecifiedDebugLevel = Convert.ToInt32(t.LiteralValue);
                    }
                    catch { }
                }
                else if (laKind == Identifier)
                {
                    Step();
                    if (vs != null)
                        vs.SpecifiedId = t.Value;
                    else
                        ds.SpecifiedId = t.Value;
                }
                else if (ds == null)
                    Expect(Identifier);

                Expect(Semicolon);

                if (vs == null)
                    ds.EndLocation = t.EndLocation;
                else
                    vs.EndLocation = t.EndLocation;

                module.Add(vs as StaticStatement ?? ds);
            }

            else if (laKind == Version || laKind == Debug || (laKind == Static && Lexer.CurrentPeekToken.Kind == If))
                DeclarationCondition(module);

            //StaticAssert
            else if (laKind == (Assert))
            {
                Step();

                if (!Modifier.ContainsAttribute(DeclarationAttributes, Static))
                    SynErr(Static, "Static assert statements must be explicitly marked as static");

                var ass = new StaticAssertStatement { Attributes = GetCurrentAttributeSet_Array(), Location = t.Location };

                if (Expect(OpenParenthesis))
                {
                    ass.AssertedExpression = AssignExpression();
                    if (laKind == (Comma))
                    {
                        Step();
                        ass.Message = AssignExpression();
                    }
                    if(Expect(CloseParenthesis))
                        Expect(Semicolon);
                }

                ass.EndLocation = t.EndLocation;

                module.Add(ass);
            }

            //TemplateMixinDeclaration
            else if (laKind == Mixin)
            {
                if (Peek(1).Kind == Template)
                    module.Add(TemplateDeclaration(module));

                //TemplateMixin
                else if (Lexer.CurrentPeekToken.Kind == Identifier)
                {
                    var tmx = TemplateMixin(module);
                    if(tmx.MixinId==null)
                        module.Add(tmx);
                    else
                        module.Add(new NamedTemplateMixinNode(tmx));
                }

                //MixinDeclaration
                else if (Lexer.CurrentPeekToken.Kind == OpenParenthesis)
                    module.Add(MixinDeclaration(module,null));
                else
                {
                    Step();
                    SynErr(Identifier);
                }
            }

            // {
            else if (laKind == (OpenCurlyBrace))
                AttributeBlock(module);

            // Class Allocators
            // Note: Although occuring in global scope, parse it anyway but declare it as semantic nonsense;)
            else if (laKind == (New))
            {
                Step();

                var dm = new DMethod(DMethod.MethodType.Allocator) { Location = t.Location };
                ApplyAttributes(dm);

                dm.Parameters = Parameters(dm);
                FunctionBody(dm);
                dm.EndLocation = t.EndLocation;
                module.Add(dm);
            }

            // Class Deallocators
            else if (laKind == Delete)
            {
                Step();

                var dm = new DMethod(DMethod.MethodType.Deallocator) { Location = t.Location };
                dm.Name = "delete";
                ApplyAttributes(dm);

                dm.Parameters = Parameters(dm);
                FunctionBody(dm);
                dm.EndLocation = t.EndLocation;
                module.Add(dm);
            }

            // else:
            else
            {
                var decls = Declaration(module);
                if(module != null && decls!=null)
                    module.AddRange(decls);
            }
        }
예제 #5
0
        void DeclDef(DBlockNode module)
        {
            //AttributeSpecifier
            while (IsAttributeSpecifier())
            {
                AttributeSpecifier();

                if (t.Kind == Colon)
                    return;
            }

            if (laKind == Semicolon)
            {
                LastParsedObject = null;
                Step();
                return;
            }

            //ImportDeclaration
            if (laKind == Import)
                module.Add(ImportDeclaration());

            //Constructor
            else if (laKind == (This))
                module.Add(Constructor(module is DClassLike ? ((DClassLike)module).ClassType == DTokens.Struct : false));

            //Destructor
            else if (laKind == (Tilde) && Lexer.CurrentPeekToken.Kind == (This))
                module.Add(Destructor());

            //Invariant
            else if (laKind == (Invariant))
                module.Add(_Invariant());

            //UnitTest
            else if (laKind == (Unittest))
            {
                Step();
                var dbs = new DMethod(DMethod.MethodType.Unittest);
                LastParsedObject = dbs;
                dbs.Location = t.Location;
                FunctionBody(dbs);
                dbs.EndLocation = t.EndLocation;
                module.Add(dbs);
            }

            /*
             * VersionSpecification:
             *		version = Identifier ;
             *		version = IntegerLiteral ;
             *
             * DebugSpecification:
             *		debug = Identifier ;
             *		debug = IntegerLiteral ;
             */
            else if ((laKind == Version || laKind == Debug) && Peek(1).Kind == Assign)
            {
                Step();

                var ass = new VersionDebugSpecification
                {
                    Token = t.Kind,
                    Location = t.Location
                };
                LastParsedObject = ass;

                Step();

                if (laKind == Literal)
                {
                    Step();
                    ass.SpecifiedValue = new IdentifierExpression(t.LiteralValue, t.LiteralFormat)
                        {
                            Location = t.Location,
                            EndLocation = t.EndLocation
                        };
                }
                else if (Expect(Identifier))
                    ass.SpecifiedValue = new IdentifierExpression(t.LiteralValue, t.LiteralFormat)
                    {
                        Location = t.Location,
                        EndLocation = t.EndLocation
                    };

                Expect(Semicolon);

                ass.EndLocation = t.EndLocation;

                module.Add(ass);
            }

            else if (laKind == Version || laKind == Debug || laKind == If)
            {
                Step();

                var c = new DeclarationCondition(t.Kind);
                LastParsedObject = c;

                /*
                 * http://www.d-programming-language.org/version.html#VersionSpecification
                 * VersionCondition:
                 *		version ( IntegerLiteral )
                 *		version ( Identifier )
                 *		version ( unittest )
                 */
                if (c.IsVersionCondition && Expect(OpenParenthesis))
                {
                    if (laKind == Unittest)
                    {
                        Step();
                        c.Condition = new TokenExpression(Unittest) { Location = t.Location, EndLocation = t.EndLocation };
                    }
                    else if (laKind == Literal)
                    {
                        Step();
                        c.Condition = new IdentifierExpression(t.LiteralValue, t.LiteralFormat)
                        {
                            Location = t.Location,
                            EndLocation = t.EndLocation
                        };
                    }
                    else if (Expect(Identifier))
                        c.Condition = new IdentifierExpression(t.Value, t.LiteralFormat)
                        {
                            Location = t.Location,
                            EndLocation = t.EndLocation
                        };

                    if (Expect(CloseParenthesis))
                        TrackerVariables.ExpectingIdentifier = false;
                }

                /*
                 * DebugCondition:
                 *		debug
                 *		debug ( IntegerLiteral )
                 *		debug ( Identifier )
                 */
                else if (c.IsDebugCondition)
                {
                    if (laKind == OpenParenthesis)
                    {
                        Step();

                        if (laKind == Literal)
                        {
                            Step();
                            c.Condition = new IdentifierExpression(t.LiteralValue, t.LiteralFormat)
                            {
                                Location = t.Location,
                                EndLocation = t.EndLocation
                            };
                        }
                        else if (Expect(Identifier))
                            c.Condition = new IdentifierExpression(t.Value, t.LiteralFormat)
                            {
                                Location = t.Location,
                                EndLocation = t.EndLocation
                            };

                        Expect(CloseParenthesis);
                    }
                }

                /*
                 * StaticIfCondition:
                 *		static if ( AssignExpression )
                 */
                else if (c.IsStaticIfCondition && Expect(OpenParenthesis))
                {
                    if (DAttribute.ContainsAttribute(DeclarationAttributes, Static))
                        DeclarationAttributes.Clear();
                    else
                        SynErr(Static, "Conditional declaration checks must be static");

                    c.Condition = AssignExpression();

                    Expect(CloseParenthesis);
                }

                if (laKind == Colon)
                {
                    Step();
                    PushAttribute(c, true);
                    return;
                }
                else if (laKind == OpenCurlyBrace)
                {
                    BlockAttributes.Push(c);

                    ClassBody(module, true, false);

                    BlockAttributes.Pop();
                }
                else
                {
                    DeclarationAttributes.Push(c);

                    DeclDef(module);
                }

                if (laKind == Else)
                {
                    Step();

                    c = c.Clone() as DeclarationCondition;
                    c.Negate();

                    if (laKind == OpenCurlyBrace)
                    {
                        BlockAttributes.Push(c);

                        ClassBody(module, true, false);

                        BlockAttributes.Pop();
                    }
                    else
                    {
                        DeclarationAttributes.Push(c);

                        DeclDef(module);
                    }
                }
            }

            //StaticAssert
            else if (laKind == (Assert))
            {
                Step();

                if (DAttribute.ContainsAttribute(DeclarationAttributes, Static))
                {
                    //HACK: Assume that there's only our 'static' attribute applied to the 'if'-statement
                    DeclarationAttributes.Clear();
                }
                else
                    SynErr(Static, "Static assert statements must be explicitly marked as static");

                if (Expect(OpenParenthesis))
                {
                    AssignExpression();
                    if (laKind == (Comma))
                    {
                        Step();
                        AssignExpression();
                    }
                    Expect(CloseParenthesis);
                }
                Expect(Semicolon);
            }

            //TemplateMixinDeclaration
            else if (laKind == Mixin)
            {
                if (Peek(1).Kind == Template)
                    module.Add(TemplateDeclaration(module));

                //TemplateMixin
                else if (Lexer.CurrentPeekToken.Kind == Identifier)
                    module.Add(TemplateMixin());

                //MixinDeclaration
                else if (Lexer.CurrentPeekToken.Kind == OpenParenthesis)
                    module.Add(MixinDeclaration());
                else
                {
                    Step();
                    SynErr(Identifier);
                }
            }

            // {
            else if (laKind == (OpenCurlyBrace))
            {
                int popCount = DeclarationAttributes.Count;
                while (DeclarationAttributes.Count > 0)
                    BlockAttributes.Push(DeclarationAttributes.Pop());

                ClassBody(module, true, false);

                for (int i = popCount; i > 0; i--)
                    BlockAttributes.Pop();
            }

            // Class Allocators
            // Note: Although occuring in global scope, parse it anyway but declare it as semantic nonsense;)
            else if (laKind == (New))
            {
                Step();

                var dm = new DMethod(DMethod.MethodType.Allocator) { Location=t.Location };
                ApplyAttributes(dm);

                dm.Parameters = Parameters(dm);
                FunctionBody(dm);
                dm.EndLocation = t.EndLocation;
                module.Add(dm);
            }

            // Class Deallocators
            else if (laKind == Delete)
            {
                Step();

                var dm = new DMethod(DMethod.MethodType.Deallocator) { Location=t.Location };
                dm.Name = "delete";
                ApplyAttributes(dm);

                dm.Parameters = Parameters(dm);
                FunctionBody(dm);
                dm.EndLocation = t.EndLocation;
                module.Add(dm);
            }

            // else:
            else
                module.AddRange(Declaration(module));
        }
예제 #6
0
		IMetaDeclarationBlock AttributeBlock(DBlockNode module)
		{
			/*
			 * If there are attributes given, put their references into the meta block.
			 * Also, pop them from the declarationAttributes stack on to the block attributes so they will be assigned to all child items later on.
			 */

			IMetaDeclarationBlock metaDeclBlock;

			if (DeclarationAttributes.Count != 0)
				metaDeclBlock = new AttributeMetaDeclarationBlock(DeclarationAttributes.ToArray()) { BlockStartLocation = la.Location };
			else
				metaDeclBlock = new MetaDeclarationBlock { BlockStartLocation = la.Location };

			var stk_backup = BlockAttributes;
			BlockAttributes = new Stack<DAttribute>();
			foreach (var attr in stk_backup)
			{
				if (attr is Modifier)
				{
					switch ((attr as Modifier).Token)
					{
						case DTokens.Virtual:
						case DTokens.Final:
							continue;
					}
				}
				else if (attr is BuiltInAtAttribute)
				{
					switch ((attr as BuiltInAtAttribute).Kind)
					{
						case BuiltInAtAttribute.BuiltInAttributes.Safe:
						case BuiltInAtAttribute.BuiltInAttributes.System:
						case BuiltInAtAttribute.BuiltInAttributes.Trusted:
							continue;
					}
				}

				BlockAttributes.Push(attr);
			}


			while (DeclarationAttributes.Count > 0)
				BlockAttributes.Push(DeclarationAttributes.Pop());

			ClassBody(module, true, false);

			BlockAttributes = stk_backup;

			// Store the meta block
			metaDeclBlock.EndLocation = t.EndLocation;
			if(module!=null)
				module.Add(metaDeclBlock);
			return metaDeclBlock;
		}
예제 #7
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="module"></param>
		/// <param name="previouslyParsedAttribute"></param>
		/// <param name="RequireDeclDef">If no colon and no open curly brace is given as lookahead, a DeclDef may be parsed otherwise, if parameter is true.</param>
		/// <returns></returns>
		IMetaDeclaration AttributeSpecifier(DBlockNode module, DAttribute previouslyParsedAttribute, bool RequireDeclDef = false)
		{
			DAttribute[] attrs;

			if (laKind == Colon)
			{
				Step();
				PushAttribute(previouslyParsedAttribute, true);

				attrs = new DAttribute[1 + DeclarationAttributes.Count];
				DeclarationAttributes.CopyTo(attrs, 0);
				DeclarationAttributes.Clear();
				attrs[attrs.Length - 1] = previouslyParsedAttribute;

				AttributeMetaDeclarationSection metaDecl = null;
				//TODO: Put all remaining block/decl(?) attributes into the section definition..
				if(module!=null)
					module.Add(metaDecl = new AttributeMetaDeclarationSection(attrs) { EndLocation = t.EndLocation });
				return metaDecl;
			}
			else 
				PushAttribute(previouslyParsedAttribute, false);

			if (laKind == OpenCurlyBrace)
				return AttributeBlock(module);
			else
			{
				if (IsEOF && module != null && previouslyParsedAttribute != null) // To enable attribute completion, add dummy node
					module.Add (new DVariable{ Attributes = new List<DAttribute>{ previouslyParsedAttribute } });

				if (RequireDeclDef)
				{
					DeclDef(module);

					attrs = new DAttribute[1 + DeclarationAttributes.Count];
					DeclarationAttributes.CopyTo(attrs, 0);
					DeclarationAttributes.Clear();
					attrs[attrs.Length - 1] = previouslyParsedAttribute;

					return new AttributeMetaDeclaration(attrs) { EndLocation = previouslyParsedAttribute.EndLocation };
				}
			}

			return null;
		}
예제 #8
0
		public void DeclDef(DBlockNode module)
		{
			if (IsAttributeSpecifier) {
				do
					AttributeSpecifier (module);
				while(IsAttributeSpecifier);

				var tkind = t.Kind;
				if(tkind == Semicolon || tkind == CloseCurlyBrace || tkind == Colon)
					return;
			}

			if (laKind == Semicolon)
			{
				Step();
				return;
			}

			switch (laKind)
			{
				case DTokens.Module:
					var mod = module as DModule;

					var ddoc = GetComments ();
					var ms = ModuleDeclaration ();
					ms.ParentNode = module;
					ddoc += CheckForPostSemicolonComment ();

					if (mod != null) {
						if (mod.StaticStatements.Count != 0 ||
						    mod.Children.Count != 0)
							SynErr (DTokens.Module, "Module declaration must stand at a module's beginning.");
							
						mod.OptionalModuleStatement = ms;
						mod.Description = ddoc;

						if (ms.ModuleName!=null)
							mod.ModuleName = ms.ModuleName.ToString();
					} else
						SynErr (DTokens.Module, "Module statements only allowed in module scope.");

					module.Add (ms);
					break;
				case Import:
					module.Add(ImportDeclaration(module));
					break;
				case This:
					module.Add(Constructor(module, module is DClassLike && ((DClassLike)module).ClassType == DTokens.Struct));
					break;
				case Tilde:
					if (Lexer.CurrentPeekToken.Kind != This)
						goto default;
					module.Add(Destructor());
					break;
				case Invariant:
					module.Add(_Invariant());
					break;
				case Unittest:
					Step();
					var dbs = new DMethod(DMethod.MethodType.Unittest);
					ApplyAttributes(dbs);
					dbs.Location = t.Location;
					FunctionBody(dbs);
					module.Add(dbs);
					break;
				/*
				 * VersionSpecification: 
				 *		version = Identifier ; 
				 *		version = IntegerLiteral ;
				 * 
				 * DebugSpecification: 
				 *		debug = Identifier ; 
				 *		debug = IntegerLiteral ;
				 */
				case Version:
				case Debug:
					if (Peek(1).Kind == Assign)
					{
						DebugSpecification ds = null;
						VersionSpecification vs = null;

						if (laKind == Version)
							vs = new VersionSpecification {
								Location = la.Location,
								Attributes = GetCurrentAttributeSet_Array()
							};
						else
							ds = new DebugSpecification {
								Location = la.Location,
								Attributes = GetCurrentAttributeSet_Array()
							};

						Step();
						Step();

						if (laKind == Literal) {
							Step ();
							if (t.LiteralFormat != LiteralFormat.Scalar)
								SynErr (t.Kind, "Integer literal expected!");
							try {
								if (vs != null)
									vs.SpecifiedNumber = Convert.ToUInt64 (t.LiteralValue);
								else
									ds.SpecifiedDebugLevel = Convert.ToUInt64 (t.LiteralValue);
							} catch {
							}
						} else if (laKind == Identifier) {
							Step ();
							if (vs != null)
								vs.SpecifiedId = t.Value;
							else
								ds.SpecifiedId = t.Value;
						} else if (IsEOF) {
							if (vs != null)
								vs.SpecifiedId = DTokens.IncompleteId;
							else
								ds.SpecifiedId = DTokens.IncompleteId;
						}
						else if (ds == null)
							Expect(Identifier);

						Expect(Semicolon);

						((AbstractStatement)ds ?? vs).EndLocation = t.EndLocation;

						module.Add(vs as StaticStatement ?? ds);
					}
					else
						DeclarationCondition(module);
					break;
				case Static:
					if (Lexer.CurrentPeekToken.Kind == If)
						goto case Version;
					goto default;
				case Assert:
					Step();
					CheckForStorageClasses(module);
					if (!Modifier.ContainsAttribute(DeclarationAttributes, Static))
						SynErr(Static, "Static assert statements must be explicitly marked as static");

					module.Add(ParseStaticAssertStatement(module));
					Expect(Semicolon);
					break;
				case Mixin:
					switch(Peek(1).Kind)
					{
						case Template:
							module.Add (TemplateDeclaration (module));
							break;
						
						case DTokens.__vector:
						case DTokens.Typeof:
						case Dot:
						case Identifier://TemplateMixin
							var tmx = TemplateMixin (module);
							if (tmx.MixinId == null)
								module.Add (tmx);
							else
								module.Add (new NamedTemplateMixinNode (tmx));
							break;

						case OpenParenthesis:
							module.Add (MixinDeclaration (module, null));
							break;
						default:
							Step ();
							SynErr (Identifier);
							break;
					}
					break;
				case OpenCurlyBrace:
					AttributeBlock(module);
					break;
				// Class Allocators
				// Note: Although occuring in global scope, parse it anyway but declare it as semantic nonsense;)
				case New:
					Step();

					var dm = new DMethod(DMethod.MethodType.Allocator) { Location = t.Location };
					ApplyAttributes(dm);

					Parameters(dm);
					FunctionBody(dm);
					module.Add(dm);
					break;
				case Delete:
					Step();

					var ddm = new DMethod(DMethod.MethodType.Deallocator) { Location = t.Location };
					ddm.Name = "delete";
					ApplyAttributes(ddm);

					Parameters(ddm);
					FunctionBody(ddm);
					module.Add(ddm);
					break;
				default:
					var decls = Declaration(module);
					if(module != null && decls!=null)
						module.AddRange(decls);
					break;
			}
		}