Work in progress

This is actually a D2 grammar, and it's also written in a somewhat strange style. In a parody of horrible 1990s web design, I present to you this animated GIF explaining the situation.

http://jfbillingsley.com/dspec/attachments/wiki/Grammar/underconstruction.gif

/* The main starting point is the Module */
Module: ModuleDecl Declaration*

/* This describes the module and gives the name */
ModuleDecl: module ModuleName

/* The syntax for the module name */
ModuleName: ModuleName . Identifier
            Identifier

/* The syntax for basically everything else */
Declaration: ConditionalCompilationDecl
             ProgramDeclaration

/* This declaration describes a compile time condition */
ConditionalCompilationDecl: CompilationCondition \:
                            CompilationCondition DeclarationBlock [ else DeclarationBlock ]

/* There are three types of compile time conditions */
CompilationCondition: VersionCondition
                      DebugCondition
                      StaticIfCondition

/* The version condition */
VersionCondition: version \( IntegerLiteral \)
                  version \( Identifier \)

/* This is for a conditional debug */
DebugCondition: debug \( IntegerLiteral \)
                debug \( Identifier \)
                debug

/* The more traditional if-else condition */
StaticIfCondition: static if \( AssignExpr \)

/* Now for the traditional declarations */
ProgramDeclaration: AttributeSpecifier
                    StaticAssert
                    TypeDeclaration
                    ImportDeclaration
                    EnumDeclaration
                    TemplateMixin
                    TemplateDeclaration
                    FunctionTemplateDeclaration
                    ClassTemplateDeclaration
                    InterfaceTemplateDeclaration
                    StructTemplateDeclaration
                    ClassDeclaration
                    InterfaceDeclaration
                    AggregateDeclaration
                    Constructor
                    Destructor
                    Invariant
                    UnitTest
                    StaticConstructor
                    StaticDestructor
                    MixinDeclaration
                    DebugSpecification
                    VersionSpecification
                    ;

/* For attribute blocks */
/* example: `public:` or `exter (C) { ... }` */
AttributeSpecifier: Attribute+ \: Declaration*
                    Attribute+ DeclarationBlock

/* There are five categories of attributes */
Attribute: StorageClassAttribute
           ProtectionAttribute
           LinkageAttribute
           AlignAttribute
           Pragma

/* These attributes dictate the storage semantics */
StorageClassAttribute: synchronized
                       deprecated
                       static
                       final
                       override
                       abstract
                       const
                       auto
                       scope

/* These attributes dictate the access permissions of member items */
ProtectionAttribute: private
                     package
                     protected
                     public
                     export

/* These attributes consider external linking */
LinkageAttribute: extern \( Identifier \)
                  extern \( C\+\+ \)
                  extern

/* These attributes change byte packing considerations */
AlignAttribute: align \( IntegerLiteral \)
                align

/* A pragma may be used as an attribute */
Pragma: pragma \( Identifier [ , Expression ] \)

/* This is a block of Declarations */
DeclarationBlock: { Declaration* }
                  Declaration

/* A static assert will be judged at compile time */
StaticAssert: static assert \( AssignExpr [ , AssignExpr ] \) ;

/* This declaration is for typing data */
TypeDeclaration: TypedefAlias Attribute* [ Identifier = AssignExpr ] TypeDeclarationPost
                 Attribute+ TypeDeclarationPost
                 Attribute+ Identifier = AssignExpr ( , Identifier = AssignExpr )* ;
                 TypeDeclarationPost

/* Some spillover from the above description */
TypeDeclarationPost: BasicType Declarator FunctionBody
                     BasicType Declarator [ = Initializer ] (, IdentifierInitializer )* ;

/* This will, for example, be used for initializing a variable */
IdentifierInitializer: Identifier [ = Initializer ]

/* What you can initialize with */
Initializer: void
             NonVoidInitializer

/* You can initialize with some values */
NonVoidInitializer: AssignExpr
                    ArrayInitializer
                    StructInitializer

/* Initializing arrays with this syntax */
ArrayInitializer: \[ [ ArrayStructMemberInitializer ( , ArrayStructMemberInitializer )* ] \]

/* Initializing structs has this syntax */
StructInitializer: { [ ArrayStructMemberInitializer ( , ArrayStructMemberInitializer )* ] }

/* What you can initialize struct and array members */
ArrayStructMemberInitializer: NonVoidInitializer
                              Identifier \: NonVoidInitializer

/* Defines typedef and alias keywords within the grammar */
TypedefAlias: typedef
              alias

/* For importing modules into the current module */
ImportDeclaration: import ImportList ;

/* You may list more than one import */
ImportList: Import ( , Import )*
            Import ImportBindList

/* You import my selecting a valid module name */
/* Optionally you can namespace this module to a specific identifier */
Import: [ Identifier = ] ModuleName

/* You can also pull only particular names from a module */
ImportBindList: \: ImportBind ( , ImportBind )*

/* You can rename these items */
ImportBind: [ Identifier = ] Identifier

/* The definition for an enum */
EnumDeclaration: enum [ Identifier ] [ Type ] EnumBody

/* The body of an enum contains many comma separated members */
/* An optional last comma is allowed */
EnumBody: { EnumMember ( , EnumMember )* [ , ] }
          ;

/* Each enum member is a simple identifier */
/* Optionally, you can assign a value for this member */
EnumMember: Identifier [ = AssignExpr ]

/* The definition for a mixin template */
TemplateMixin: mixin Identifier [ ! \( [ TemplateArgumentList ] \) ] [ Identifier ]

/* Template argument list */
TemplateArgumentList: TemplateArgument ( , TemplateArgument )*

/* The definition for a template */
TemplateDeclaration: template Identifier \( [ TemplateParameterList ] \) TemplateBody

/* The template parameter list */
TemplateParameterList: TemplateParameter ( , TemplateParameter )*

/* There are four different template parameter types */
TemplateParameter: TemplateAliasParameter
                   TemplateTupleParameter
                   TemplateValueParameter
                   TemplateTypeParameter

/* An alias parameter */
TemplateAliasParameter: alias Identifier [ \: Type ] [ = Type ]

/* A tuple */
TemplateTupleParameter: Identifier ...

/* A basic value */
TemplateValueParameter: BasicType Declarator [ \: ConditionalExpr ] [ = ConditionalExpr ]

/* A generic type */
TemplateTypeParameter: Identifier [ \: Type ] [ = Type ]

/* The body of a template */
TemplateBody: { ( Declaration )* }

/* The basic types and a identifier list */
BasicType: BasicTypeNoIdList
           [ . ] IdentifierList

/* The basic types that can be used in various places */
BasicTypeNoIdList: ( bool  byte  ubyte  short  ushort  int  uint  long  ulong
                    char  wchar  dchar  float  double  real  ifloat  idouble
                    ireal  cfloat  cdouble  creal  void
                    Typeof [ IdentifierList ]
                    TypeConstructor \( Type \) )

/* some extra attributes for types */
TypeConstructor: const
                 invariant

/* The definition of typeof */
Typeof: typeof \( Expression \)

/* What constitutes a type */
Type: BasicType [ DeclaratorPost ]

/* Traversing an identifier list */
IdentifierList: ( Identifier  TemplateInstance ) ( ( . Identifier  . TemplateInstance ) )*

/* Declarator */
Declarator: DeclaratorType [ Declarator ]
            Identifier ( DeclaratorSuffix )*
            \( Declarator \) ( DeclaratorSuffix )*

DeclaratorPost: DeclaratorType [ DeclaratorPost ]
                \( Declarator2 \) ( DeclaratorSuffix )*

DeclaratorType: \*
                \[ \]
                \[ Expression \]
                \[ Type \]
                \[ AssignExpr .. AssignExpr \]
                delegate \( [ ParameterList ] \)
                function \( [ ParameterList ] \)

DeclaratorSuffix: \[ \]
                  \[ Expression \]
                  \[ Type \]
                  \( [ ParameterList ] \)

/* For parameters of functions */
ParameterList: Parameter [ ... ] ( , Parameter [ ... ] )*

/* The definition of a parameter */
Parameter: [ InOut ] [ ParameterStorageClass ] BasicType [ Declarator ] [ = AssignExpr ]

/* Parameters may have these extra attributes */
ParameterStorageClass: const
                       invariant
                       final
                       scope
                       static

/* The passing constraints for parameters */
InOut: inout
       in
       out
       ref
       lazy

/* The Type declaration for a template instance */
TemplateInstance: Identifier ! \( [ TemplateArgumentList ] \)

/* The declaration of a function template */
FunctionTemplateDeclaration: ( BasicType  Type ) Identifier \( TemplateParameterList \) \( [ ParameterList ] \) FunctionBody

/* The body of a function or a template function */
FunctionBody: [ InStatement ] OutStatement BodyStatement
              [ OutStatement ] InStatement BodyStatement
              BodyStatement

/* The definition of the in statement */
InStatement: in BlockStatement

/* The definition of the out statement */
OutStatement: out [ \( Identifier \) ] BlockStatement

/* The body statement, which is the normal function body */
BodyStatement: [ body ] BlockStatement

/* For defining a class template */
ClassTemplateDeclaration: class Identifier \( [ TemplateParameterList ] \) [ \: BaseClassList ] ClassBody

/* The list of inherited classes */
BaseClassList: BaseClass [ , BaseClass ]

/* An item in the inherited class list */
BaseClass: [ Protection ] IdentifierList

/* The protection attributes available for constraining inherited classes */
Protection: private
            protected
            public
            export

/* The body of a class */
ClassBody: { ( ClassBodyDeclaration )* }

/* Each declaration at the class body level */
ClassBodyDeclaration: Declaration
                      ClassAllocator
                      ClassDeallocator

/* For overriding at memory allocation, that is at call to new */
ClassAllocator: new \( [ ParameterList ] \) FunctionBody

/* For overriding at memory deallocation, that is at call to delete */
ClassDeallocator: delete \( [ ParameterList ] \) FunctionBody

/* For defining an interface template */
InterfaceTemplateDeclaration: interface Identifier \( [ TemplateParameterList ] \) [ \: BaseInterfaceList ] InterfaceBody

/* For all inherited interfaces */
BaseInterfaceList: BaseInterface [ , BaseInterface ]

/* Each item in the list of inherited interfaces */
BaseInterface: [ Protection ] IdentifierList

/* The body of an interface */
InterfaceBody: { Declaration* }

/* For defining a struct template */
StructTemplateDeclaration: struct Identifier \( [ TemplateParameterList ] \) StructBody

/* The body of a struct or struct template */
StructBody: { StructBodyDeclaration* } [ ; ]

/* Each declaration allowed within a struct body */
StructBodyDeclaration: Declaration
                       StructAllocator
                       StructDeallocator

/* For overriding at memory allocation, that is upon new */
StructAllocator: ClassAllocator

/* For overriding at memory deallocation, that is upon delete */
StructDeallocator: ClassDeallocator

/* For defining a class */
ClassDeclaration: class Identifier [ BassClassList ] ClassBody

/* For defining an interface */
InterfaceDeclaration: interface Identifier [ BaseInterfaceList ] InterfaceBody

/* For defining a struct or union */
AggregateDeclaration: Tag [ Identifier ] StructBody
                      Tag [ Identifier ] ;

/* Aggregates can be either structs or unions */
Tag: struct
     union

/* For defining a constructor */
Constructor: this \( [ ParameterList ] \) ( FunctionBody  ; )

/* For defining a destructor */
Destructor: ~ this \( \) ( FunctionBody  ; )

/* For invariant scoping */
Invariant: invariant [ \( \) ] BlockStatement

/* A scope */
BlockStatement: { Statement* }

/* For normal statements */
Statement: NonEmptyStatement
           BlockStatement

/* For statements that have some code */
NonEmptyStatement: ProgramDeclaration
                   NonEmptyNonDeclaration

/* For defining the unittest region */
UnitTest: unittest FunctionBody

/* For defining a static constructor */
StaticConstructor: static this \( \) FunctionBody

/* For defining a static destructor */
StaticDestructor: static ~ this \( \) FunctionBody

/* For using a mixin */
MixinDeclaration: mixin \( Expression \) ;

/* For setting a new debug */
DebugSpecification: debug = ( Identifier  IntegerLiteral )

/* For setting a version flag */
VersionSpecification: version = ( Identifier  IntegerLiteral )

/* These are statements that have code, but do not have declarations that affect the current scope */
NonEmptyNonDeclaration: LabeledStatement
                        ExpressionStatement
                        IfStatement
                        ConditionalStatement
                        WhileStatement
                        DoStatement
                        ForStatement
                        ForeachStatement
                        ForeachRangeStatement
                        SwitchStatement
                        CaseStatement
                        DefaultStatement
                        ContinueStatement
                        BreakStatement
                        ReturnStatement
                        GotoStatement
                        WithStatement
                        SynchronizedStatement
                        TryStatement
                        ScopeGuardStatement
                        ThrowStatement
                        VolatileStatement
                        AsmStatement
                        PragmaStatement

/* For defining labels */
LabeledStatement: Identifier \: NoScopeStatement

/* These statements do not change scope */
NoScopeStatement: NonEmptyStatement
                  BlockStatement

/* This statement represents an expression */
ExpressionStatement: Expression ;

/* The definition of an expression */
Expression: AssignExpr ( , AssignExpr )*

/* This statement is the if-else conditional statement */
IfStatement: if \( IfCondition \) ScopeStatement [ else ScopeStatement ]

/* Conditions allowed in an if statement */
IfCondition: Expression
             auto Identifier = Expression
             BasicType Declarator = Expression

/* This statement will have its own scope */
ScopeStatement: NonEmptyStatement
                Statement

/* This statement is based upon a condition */
ConditionalStatement: Condition Statement [ else Statement ]

/* For defining a while statement */
WhileStatement: while \( Expression \) ScopeStatement

/* For defining a do statement */
DoStatement: do ScopeStatement while \( Expression \)

/* For defining a for statement */
ForStatement: for \( NoScopeNonEmptyStatement [ Expression ] ; [ Expression ] \) ScopeStatement

/* For statements that do not change scope and are not empty */
NoScopeNonEmptyStatement: NonEmptyStatement
                          BlockStatement

/* For defining a foreach statement */
ForeachStatement: Foreach \( ForeachTypeList ; Expression \) ScopeStatement

/* There are two types of foreach loops */
/* Each works the same syntactically */ 
Foreach: foreach
         foreach_reverse

/* For defining the types that will be set on the iteration */
ForeachTypeList: ForeachType ( , ForeachType )*

/* Defines what is allowed as a type within the list that contains the values to be pulled from the iteration */
ForeachType: [ ( inout  ref ) ] [ Type ] Identifier

/* For defining a foreach that uses a range */
ForeachRangeStatement: Foreach \( ForeachType ; AssignExpr .. AssignExpr \) ScopeStatement

/* For defining a switch statement */
SwitchStatement: switch \( Expression \) BlockStatement

/* For defining a case of a switch statement */
CaseStatement: case Expression \:

/* For defining the default case of a switch statement */
DefaultStatement: default \:

/* For defining the continue statement */
ContinueStatement: continue [ Identifier ] ;

/* For defining the break statement */
BreakStatement: break [ Identifier ] ;

/* For defining the return statement */
ReturnStatement: return [ Expression ] ;

/* For defining the goto statement */
GotoStatement: goto Identifier ;
               goto default ;
               goto case [ Expression ] ;

/* For defining the with statement */
WithStatement: with \( Expression \) ScopeStatement
               with \( TemplateInstance \) ScopeStatement

/* For defining the synchronized statement */
SynchronizedStatement: synchronized NoDeclScopeStatement
                       synchronized \( Expression \) ScopeStatement

/* These statements are not declarations but do change scope */
NoDeclScopeStatement: NonEmptyNoDeclStatement
                      BlockStatement

/* For defining try blocks */
TryStatement: try ScopeStatement [ CatchList ] [ FinallyStatement ]

/* For defining the types of catch blocks allowed for the try */
CatchList: ( catch \( Parameter \) NoScopeNonEmptyStatement )* [ catch NoScopeNonEmptyStatement ]

/* For defining the finally block of a try */
FinallyStatement: finally NoScopeNonEmptyStatement

/* For defining the scope statement */
ScopeGuardStatement: scope \( Identifier \) Statement

/* For defining the throw statement */
ThrowStatement: throw Expression ;

/* For defining the volatile statement */
VolatileStatement: volatile Statement
                   volatile ;

/* For defining asm blocks */
AsmStatement: asm { ( AsmInstruction )* }

AsmInstruction: /* TODO */

/* For defining the pragma statement */
PragmaStatement: Pragma

/* For defining expressions that contain assignment */
AssignExpr: ConditionalExpression
            ConditionalExpression = AssignExpr
            ConditionalExpression \+= AssignExpr
            ConditionalExpression -= AssignExpr
            ConditionalExpression \*= AssignExpr
            ConditionalExpression /= AssignExpr
            ConditionalExpression %= AssignExpr
            ConditionalExpression &= AssignExpr
            ConditionalExpression |= AssignExpr
            ConditionalExpression ^= AssignExpr
            ConditionalExpression ~= AssignExpr
            ConditionalExpression <<= AssignExpr
            ConditionalExpression >>= AssignExpr
            ConditionalExpression >>>= AssignExpr

/* For defining expressions that have a ternary operation */
ConditionalExpression: LogicalOrExpression [ ? Expression \: ConditionalExpression ]

/* For defining expressions that have a logical or operation */
LogicalOrExpression: [ LogicalOrExpression || ] LogicalAndExpression

/* For defining expressions that have a logical and operation */
LogicalAndExpression: [ LogicalAndExpression && ] OrExpression

/* For defining expressions that have a bitwise or operation */
OrExpression: [ OrExpression | ] XorExpression

/* For defining expressions that have a bitwise xor operation */
XorExpression: [ XorExpression ^ ] AndExpression

/* For defining expressions that have a bitwise and operation */
AndExpression: [ AndExpression & ] CmpExpression

/* For defining expressions that make a comparison */
CmpExpression: ShiftExpression
               ShiftExpression == ShiftExpression
               ShiftExpression != ShiftExpression
               ShiftExpression is ShiftExpression
               ShiftExpression !is ShiftExpression
               ShiftExpression < ShiftExpression
               ShiftExpression <= ShiftExpression
               ShiftExpression > ShiftExpression
               ShiftExpression >= ShiftExpression
               ShiftExpression !<>= ShiftExpression
               ShiftExpression !<> ShiftExpression
               ShiftExpression <> ShiftExpression
               ShiftExpression <>= ShiftExpression
               ShiftExpression !> ShiftExpression
               ShiftExpression !>= ShiftExpression
               ShiftExpression !< ShiftExpression
               ShiftExpression !<= ShiftExpression
               ShiftExpression in ShiftExpression

/* For defining expressions that perform a shift operation */
ShiftExpression: AddExpression
                 ShiftExpression << AddExpression
                 ShiftExpression >> AddExpression
                 ShiftExpression >>> AddExpression

/* For defining expressions that perform an add operation */
AddExpression: MulExpression
               AddExpression \+ MulExpression
               AddExpression - MulExpression
               CatExpression

/* For defining expressions that perform a concatenate operation */
CatExpression: AddExpression ~ MulExpression

/* For defining expressions that perform a multiplication operation */
MulExpression: UnaryExpression
               MulExpression \* UnaryExpression
               MulExpression / UnaryExpression
               MulExpression % UnaryExpression

/* For defining expressions that perform a unary operation */
UnaryExpression: PostfixExpression
                 & UnaryExpression
                 \+\+ UnaryExpression
                 -- UnaryExpression
                 \* UnaryExpression
                 - UnaryExpression
                 \+ UnaryExpression
                 ! UnaryExpression
                 ~ UnaryExpression
                 \( Type \) . Identifier
                 NewExpression
                 delete UnaryExpression
                 cast \( Type \) UnaryExpression

/* For defining anything left */
PostfixExpression: IntegerLiteral
                   FloatLiteral
                   $
                   null
                   true
                   false
                   AssertExpression
                   MixinExpression
                   IsExpression
                   PostfixExpressionList

/* Further syntax */
PostfixExpressionList: PrimaryExpression
                       PostfixExpressionList . Identifier
                       PostfixExpressionList . TemplateInstance
                       PostfixExpressionList \+\+
                       PostfixExpressionList --
                       PostfixExpressionList \( ArgumentList \)
                       PostfixExpressionList \[ ArgumentList \]
                       PostfixExpressionList \[ AssignExpr .. AssignExpr \]

/* These contain expressions that are of lowest precedence */
PrimaryExpression: [ . ] Identifier
                   [ . ] TemplateInstance
                   this
                   super
                   CharacterLiteral
                   StringLiteral
                   ArrayLiteral
                   AssocArrayLiteral
                   FunctionLiteral
                   ImportExpression
                   BasicTypeNoIdList
                   typeid \( Type \)
                   \( Expression \)
                   TraitsExpression

/* For defining array literals */
ArrayLiteral: \[ Expression* \]

/* For defining associative array literals */
AssocArrayLiteral: \[ KeyValuePair ( , KeyValuePair )* \]

/* For defining members of associative array literals */
KeyValuePair: ConditionalExpression \: ConditionalExpression

/* For defining function literals */
FunctionLiteral: function [ Type ] \( [ ParameterList ] \) FunctionBody
                 function [ Type ] FunctionBody
                 delegate [ Type ] \( [ ParameterList ] \) FunctionBody
                 delegate [ Type ] FunctionBody
                 \( [ ParameterList ] \) FunctionBody
                 FunctionBody

/* For defining assert expressions */
AssertExpression: assert \( AssignExpr [ , AssignExpr ] \)

/* For defining import expressions */
ImportExpression: import \( AssignExpr \)

/* For defining traits expressions */
TraitsExpression: __traits \( Identifier , TraitsArgument ( , TraitsArgument )* \)

/* An argument for a traits expression */
TraitsArgument: AssignExpr
                Type

/* For defining the new expression */
NewExpression: NewArguments Type \[ AssignExpr \]
               NewArguments Type \( [ Expression ] \)
               NewArguments Type
               NewArguments class [ \( [ Expression ] \) ] [ \: BaseClassList ] { Declaration* }

/* Common syntax for new */
NewArguments: new [ \( [ Expression ] \) ]

/* For defining the mixin expression */
MixinExpression: mixin \( AssignExpr \)

/* For defining the is expression */
IsExpression: IsNotIs \( Type \)
              IsNotIs \( Type \: TypeSpecialization \)
              IsNotIs \( Type == TypeSpecialization \)
              IsNotIs \( Type Identifier \)
              IsNotIs \( Type Identifier \: TypeSpecialization [ , TemplateParameterList ] \)
              IsNotIs \( Type Identifier == TypeSpecialization [ , TemplateParameterList ] \)

/* Particular specializations that can be used within the is expression */
TypeSpecialization: Type
                    typedef
                    struct
                    union
                    class
                    interface
                    enum
                    function
                    delegate
                    super
                    return

Attachments