| 8 | | (* The main starting point is the Module *) |
| 9 | | Module = ModuleDecl [ { Declaration } ] ; |
| 10 | | |
| 11 | | (* This describes the module and gives the name *) |
| 12 | | ModuleDecl = 'module' ModuleName ; |
| 13 | | |
| 14 | | (* The syntax for the module name *) |
| 15 | | ModuleName = ModuleName '.' Identifier |
| 16 | | | Identifier ; |
| 17 | | |
| 18 | | (* The syntax for basically everything else *) |
| 19 | | Declaration = ConditionalCompilationDecl |
| 20 | | | ProgramDeclaration ; |
| 21 | | |
| 22 | | (* This declaration describes a compile time condition *) |
| 23 | | ConditionalCompilationDecl = CompilationCondition ':' |
| 24 | | | CompilationCondition DeclarationBlock [ 'else' DeclarationBlock ] ; |
| 25 | | |
| 26 | | (* There are three types of compile time conditions *) |
| 27 | | CompilationCondition = VersionCondition |
| 28 | | | DebugCondition |
| 29 | | | StaticIfCondition ; |
| 30 | | |
| 31 | | (* The version condition *) |
| 32 | | VersionCondition = 'version' '(' IntegerLiteral ')' |
| 33 | | | 'version' '(' Identifier ')' ; |
| 34 | | |
| 35 | | (* This is for a conditional debug *) |
| 36 | | DebugCondition = 'debug' '(' IntegerLiteral ')' |
| 37 | | | 'debug' '(' Identifier ')' |
| 38 | | | 'debug' ; (* that is, for 'debug: ' *) |
| 39 | | |
| 40 | | (* The more traditional if-else condition *) |
| 41 | | StaticIfCondition = 'static' 'if' '(' AssignExpr ')' ; |
| 42 | | |
| 43 | | (* Now for the traditional declarations *) |
| 44 | | ProgramDeclaration = AttributeSpecifier |
| 45 | | | StaticAssert |
| 46 | | | TypeDeclaration |
| 47 | | | ImportDeclaration |
| 48 | | | EnumDeclaration |
| 49 | | | TemplateMixin |
| 50 | | | TemplateDeclaration |
| 51 | | | FunctionTemplateDeclaration |
| 52 | | | ClassTemplateDeclaration |
| 53 | | | InterfaceTemplateDeclaration |
| 54 | | | StructTemplateDeclaration |
| 55 | | | ClassDeclaration |
| 56 | | | InterfaceDeclaration |
| 57 | | | AggregateDeclaration |
| 58 | | | Constructor |
| 59 | | | Destructor |
| 60 | | | Invariant |
| 61 | | | UnitTest |
| 62 | | | StaticConstructor |
| 63 | | | StaticDestructor |
| 64 | | | MixinDeclaration |
| 65 | | | DebugSpecification |
| 66 | | | VersionSpecification |
| 67 | | | ';' ; |
| 68 | | |
| 69 | | (* For attribute blocks *) |
| 70 | | (* example: `public:` or `extern(C) { /* ... */ }` *) |
| 71 | | AttributeSpecifier = { Attribute } ':' [ { Declaration } ] |
| 72 | | | { Attribute } DeclarationBlock ; |
| 73 | | |
| 74 | | (* There are five categories of attributes *) |
| 75 | | Attribute = StorageClassAttribute |
| 76 | | | ProtectionAttribute |
| 77 | | | LinkageAttribute |
| 78 | | | AlignAttribute |
| 79 | | | Pragma ; |
| 80 | | |
| 81 | | (* These attributes dictate the storage semantics *) |
| 82 | | StorageClassAttribute = 'synchronized' |
| 83 | | | 'deprecated' |
| 84 | | | 'static' |
| 85 | | | 'final' |
| 86 | | | 'override' |
| 87 | | | 'abstract' |
| 88 | | | 'const' |
| 89 | | | 'auto' |
| 90 | | | 'scope' ; |
| 91 | | |
| 92 | | (* These attributes dictate the access permissions of member items *) |
| 93 | | ProtectionAttribute = 'private' |
| 94 | | | 'package' |
| 95 | | | 'protected' |
| 96 | | | 'public' |
| 97 | | | 'export' ; |
| 98 | | |
| 99 | | (* These attributes consider external linking *) |
| 100 | | LinkageAttribute = 'extern' '(' Identifier ')' |
| 101 | | | 'extern' '(' 'C++' ')' |
| 102 | | | 'extern' ; |
| 103 | | |
| 104 | | (* These attributes change byte packing considerations *) |
| 105 | | AlignAttribute = 'align' '(' IntegerLiteral ')' |
| 106 | | | 'align' ; |
| 107 | | |
| 108 | | (* A pragma may be used as an attribute *) |
| 109 | | Pragma = 'pragma' '(' Identifier [ ',' Expression ] ')' ; |
| 110 | | |
| 111 | | (* This is a block of Declarations *) |
| 112 | | DeclarationBlock = '{' [ { Declaration } ] '}' |
| 113 | | | Declaration ; |
| 114 | | |
| 115 | | (* A static assert will be judged at compile time *) |
| 116 | | StaticAssert = 'static' 'assert' '(' AssignExpr [ ',' AssignExpr ] ')' ';' ; |
| 117 | | |
| 118 | | (* This declaration is for typing data *) |
| 119 | | TypeDeclaration = TypedefAlias [ Attributes ] [ Identifier '=' AssignExpr ] TypeDeclarationPost |
| 120 | | | Attributes TypeDeclarationPost |
| 121 | | | Attributes Identifier '=' AssignExpr [ { ',' Identifier '=' AssignExpr } ] ; |
| 122 | | | TypeDeclarationPost ; |
| 123 | | |
| 124 | | (* Some spillover from the above description *) |
| 125 | | TypeDeclarationPost = BasicType Declarator FunctionBody |
| 126 | | | BasicType Declarator [ '=' Initializer ] [ { ',' IdentifierInitializer } ] ';' ; |
| 127 | | |
| 128 | | (* This will, for example, be used for initializing a variable *) |
| 129 | | IdentifierInitializer = Identifier [ '=' Initializer ] ; |
| 130 | | |
| 131 | | (* What you can initialize with *) |
| 132 | | Initializer = 'void' |
| 133 | | | NonVoidInitializer ; |
| 134 | | |
| 135 | | (* You can initialize with some values *) |
| 136 | | NonVoidInitializer = AssignExpr |
| 137 | | | ArrayInitializer |
| 138 | | | StructInitializer ; |
| 139 | | |
| 140 | | (* Initializing arrays with this syntax *) |
| 141 | | ArrayInitializer = '[' [ ArrayStructMemberInitializer [ { ',' ArrayStructMemberInitializer } ] ] ']' ; |
| 142 | | |
| 143 | | (* Initializing structs has this syntax *) |
| 144 | | StructInitializer = '{' [ ArrayStructMemberInitializer [ { ',' ArrayStructMemberInitializer } ] ] '}' ; |
| 145 | | |
| 146 | | (* What you can initialize struct and array members *) |
| 147 | | ArrayStructMemberInitializer = NonVoidInitializer |
| 148 | | | Identifier ':' NonVoidInitializer ; |
| 149 | | |
| 150 | | (* Defines 'typedef' and 'alias' keywords within the grammar *) |
| 151 | | TypedefAlias = 'typedef' |
| 152 | | | 'alias' ; |
| 153 | | |
| 154 | | (* For importing modules into the current module *) |
| 155 | | ImportDeclaration = 'import' ImportList ';' ; |
| 156 | | |
| 157 | | (* You may list more than one import *) |
| 158 | | ImportList = Import [ { ',' Import } ] |
| 159 | | | Import ImportBindList ; |
| 160 | | |
| 161 | | (* You import my selecting a valid module name *) |
| 162 | | (* Optionally you can namespace this module to a specific identifier *) |
| 163 | | Import = [ Identifier '=' ] ModuleName ; |
| 164 | | |
| 165 | | (* You can also pull only particular names from a module *) |
| 166 | | ImportBindList = ':' ImportBind [ { ',' ImportBind } ] ; |
| 167 | | |
| 168 | | (* You can rename these items *) |
| 169 | | ImportBind = [ Identifier '=' ] Identifier ; |
| 170 | | |
| 171 | | (* The definition for an enum *) |
| 172 | | EnumDeclaration = 'enum' [ Identifier ] [ Type ] EnumBody ; |
| 173 | | |
| 174 | | (* The body of an enum contains many comma separated members *) |
| 175 | | (* An optional last comma is allowed *) |
| 176 | | EnumBody = '{' EnumMember [ { ',' EnumMember } ] [ ',' ] '}' |
| 177 | | | ';' ; |
| 178 | | |
| 179 | | (* Each enum member is a simple identifier *) |
| 180 | | (* Optionally, you can assign a value for this member *) |
| 181 | | EnumMember = Identifier [ '=' AssignExpr ] ; |
| 182 | | |
| 183 | | (* The definition for a mixin template *) |
| 184 | | TemplateMixin = 'mixin' Identifier [ '!' '(' [ TemplateArgumentList ] ')' ] [ Identifier ] ; |
| 185 | | |
| 186 | | (* Template argument list *) |
| 187 | | TemplateArgumentList = TemplateArgument [ { ',' TemplateArgument } ] ; |
| 188 | | |
| 189 | | (* The definition for a template *) |
| 190 | | TemplateDeclaration = 'template' Identifier '(' [ TemplateParameterList ] ')' TemplateBody ; |
| 191 | | |
| 192 | | (* The template parameter list *) |
| 193 | | TemplateParameterList = TemplateParameter [ { ',' TemplateParameter } ] ; |
| 194 | | |
| 195 | | (* There are four different template parameter types *) |
| 196 | | TemplateParameter = TemplateAliasParameter |
| 197 | | | TemplateTupleParameter |
| 198 | | | TemplateValueParameter |
| 199 | | | TemplateTypeParameter ; |
| 200 | | |
| 201 | | (* An alias parameter *) |
| 202 | | TemplateAliasParameter = 'alias' Identifier [ ':' Type ] [ '=' Type ] ; |
| 203 | | |
| 204 | | (* A tuple *) |
| 205 | | TemplateTupleParameter = Identifier '...' ; |
| 206 | | |
| 207 | | (* A basic value *) |
| 208 | | TemplateValueParameter = BasicType Declarator [ ':' ConditionalExpr ] [ '=' ConditionalExpr ] ; |
| 209 | | |
| 210 | | (* A generic type *) |
| 211 | | TemplateTypeParameter = Identifier [ ':' Type ] [ '=' Type ] ; |
| 212 | | |
| 213 | | (* The body of a template *) |
| 214 | | TemplateBody = '{' [ { Declaration } ] '}' ; |
| 215 | | |
| 216 | | (* The basic types and a identifier list *) |
| 217 | | BasicType = BasicTypeNoIdList |
| 218 | | | [ '.' ] IdentifierList ; |
| 219 | | |
| 220 | | (* The basic types that can be used in various places *) |
| 221 | | BasicTypeNoIdList = 'bool' | 'byte' | 'ubyte' | 'short' | 'ushort' | 'int' | 'uint' | 'long' | 'ulong' |
| 222 | | | 'char' | 'wchar' | 'dchar' | 'float' | 'double' | 'real' | 'ifloat' | 'idouble' |
| 223 | | | 'ireal' | 'cfloat' | 'cdouble' | 'creal' | 'void' |
| 224 | | | Typeof [ IdentifierList ] |
| 225 | | | TypeConstructor '(' Type ')' ; |
| 226 | | |
| 227 | | (* some extra attributes for types *) |
| 228 | | TypeConstructor = 'const' |
| 229 | | | 'invariant' ; |
| 230 | | |
| 231 | | (* The definition of typeof *) |
| 232 | | Typeof = 'typeof' '(' Expression ')' ; |
| 233 | | |
| 234 | | (* What constitutes a type *) |
| 235 | | Type = BasicType [ DeclaratorPost ] ; |
| 236 | | |
| 237 | | (* Traversing an identifier list *) |
| 238 | | IdentifierList = ( Identifier | TemplateInstance ) [ { ( '.' Identifier | '.' TemplateInstance ) } ] ; |
| 239 | | |
| 240 | | (* Declarator *) |
| 241 | | Declarator = DeclaratorType [ Declarator ] |
| 242 | | | Identifier [ { DeclaratorSuffix } ] |
| 243 | | | '(' Declarator ')' [ { DeclaratorSuffix } ] ; |
| 244 | | |
| 245 | | DeclaratorPost = DeclaratorType [ DeclaratorPost ] |
| 246 | | | '(' Declarator2 ')' [ { DeclaratorSuffix } ] ; |
| 247 | | |
| 248 | | DeclaratorType = '*' |
| 249 | | | '[' ']' |
| 250 | | | '[' Expression ']' |
| 251 | | | '[' Type ']' |
| 252 | | | '[' AssignExpr '..' AssignExpr ']' |
| 253 | | | 'delegate' '(' [ ParameterList ] ')' |
| 254 | | | 'function' '(' [ ParameterList ] ')' ; |
| 255 | | |
| 256 | | DeclaratorSuffix = '[' ']' |
| 257 | | | '[' Expression ']' |
| 258 | | | '[' Type ']' |
| 259 | | | '(' [ ParameterList ] ')' ; |
| 260 | | |
| 261 | | (* For parameters of functions *) |
| 262 | | ParameterList = Parameter [ '...' ] [ { ',' Parameter [ '...' ] } ] ; |
| 263 | | |
| 264 | | (* The definition of a parameter *) |
| 265 | | Parameter = [ InOut ] [ ParameterStorageClass ] BasicType [ Declarator ] [ '=' AssignExpr ] ; |
| 266 | | |
| 267 | | (* Parameters may have these extra attributes *) |
| 268 | | ParameterStorageClass = 'const' |
| 269 | | | 'invariant' |
| 270 | | | 'final' |
| 271 | | | 'scope' |
| 272 | | | 'static' ; |
| 273 | | |
| 274 | | (* The passing constraints for parameters *) |
| 275 | | InOut = 'inout' |
| 276 | | | 'in' |
| 277 | | | 'out' |
| 278 | | | 'ref' |
| 279 | | | 'lazy' ; |
| 280 | | |
| 281 | | (* The Type declaration for a template instance *) |
| 282 | | TemplateInstance = Identifier '!' '(' [ TemplateArgumentList ] ')' ; |
| 283 | | |
| 284 | | (* The declaration of a function template *) |
| 285 | | FunctionTemplateDeclaration = ( BasicType | Type ) Identifier '(' TemplateParameterList ')' '(' [ ParameterList ] ')' FunctionBody ; |
| 286 | | |
| 287 | | (* The body of a function or a template function *) |
| 288 | | FunctionBody = [ InStatement ] OutStatement BodyStatement |
| 289 | | | [ OutStatement ] InStatement BodyStatement |
| 290 | | | BodyStatement ; |
| 291 | | |
| 292 | | (* The definition of the in statement *) |
| 293 | | InStatement = 'in' BlockStatement ; |
| 294 | | |
| 295 | | (* The definition of the out statement *) |
| 296 | | OutStatement = 'out' [ '(' Identifier ')' ] BlockStatement ; |
| 297 | | |
| 298 | | (* The body statement, which is the normal function body *) |
| 299 | | BodyStatement = [ 'body' ] BlockStatement ; |
| 300 | | |
| 301 | | (* For defining a class template *) |
| 302 | | ClassTemplateDeclaration = 'class' Identifier '(' [ TemplateParameterList ] ')' [ ':' BaseClassList ] ClassBody ; |
| 303 | | |
| 304 | | (* The list of inherited classes *) |
| 305 | | BaseClassList = BaseClass [ ',' BaseClass ] ; |
| 306 | | |
| 307 | | (* An item in the inherited class list *) |
| 308 | | BaseClass = [ Protection ] IdentifierList ; |
| 309 | | |
| 310 | | (* The protection attributes available for constraining inherited classes *) |
| 311 | | Protection = 'private' | 'protected' | 'public' | 'export' ; |
| 312 | | |
| 313 | | (* The body of a class *) |
| 314 | | ClassBody = '{' [ { ClassBodyDeclaration } ] '}' ; |
| 315 | | |
| 316 | | (* Each declaration at the class body level *) |
| 317 | | ClassBodyDeclaration = Declaration |
| 318 | | | ClassAllocator |
| 319 | | | ClassDeallocator ; |
| 320 | | |
| 321 | | (* For overriding at memory allocation, that is at call to new *) |
| 322 | | ClassAllocator = 'new' '(' [ ParameterList ] ')' FunctionBody ; |
| 323 | | |
| 324 | | (* For overriding at memory deallocation, that is at call to delete *) |
| 325 | | ClassDeallocator = 'delete' '(' [ ParameterList ] ')' FunctionBody ; |
| 326 | | |
| 327 | | (* For defining an interface template *) |
| 328 | | InterfaceTemplateDeclaration = 'interface' Identifier '(' [ TemplateParameterList ] ')' [ ':' BaseInterfaceList ] InterfaceBody ; |
| 329 | | |
| 330 | | (* For all inherited interfaces *) |
| 331 | | BaseInterfaceList = BaseInterface [ ',' BaseInterface ] ; |
| 332 | | |
| 333 | | (* Each item in the list of inherited interfaces *) |
| 334 | | BaseInterface = [ Protection ] IdentifierList ; |
| 335 | | |
| 336 | | (* The body of an interface *) |
| 337 | | InterfaceBody = '{' [ { Declaration } ] '}' ; |
| 338 | | |
| 339 | | (* For defining a struct template *) |
| 340 | | StructTemplateDeclaration = 'struct' Identifier '(' [ TemplateParameterList ] ')' StructBody ; |
| 341 | | |
| 342 | | (* The body of a struct or struct template *) |
| 343 | | StructBody = '{' [ { StructBodyDeclaration } ] '}' [ ';' ] ; |
| 344 | | |
| 345 | | (* Each declaration allowed within a struct body *) |
| 346 | | StructBodyDeclaration = Declaration |
| 347 | | | StructAllocator |
| 348 | | | StructDeallocator ; |
| 349 | | |
| 350 | | (* For overriding at memory allocation, that is upon new *) |
| 351 | | StructAllocator = ClassAllocator ; |
| 352 | | |
| 353 | | (* For overriding at memory deallocation, that is upon delete *) |
| 354 | | StructDeallocator = ClassDeallocator; |
| 355 | | |
| 356 | | (* For defining a class *) |
| 357 | | ClassDeclaration = 'class' Identifier [ BassClassList ] ClassBody ; |
| 358 | | |
| 359 | | (* For defining an interface *) |
| 360 | | InterfaceDeclaration = 'interface' Identifier [ BaseInterfaceList ] InterfaceBody ; |
| 361 | | |
| 362 | | (* For defining a struct or union *) |
| 363 | | AggregateDeclaration = Tag [ Identifier ] StructBody |
| 364 | | | Tag [ Identifier ] ';' ; |
| 365 | | |
| 366 | | (* Aggregates can be either structs or unions *) |
| 367 | | Tag = 'struct' |
| 368 | | | 'union' |
| 369 | | |
| 370 | | (* For defining a constructor *) |
| 371 | | Constructor = 'this' '(' [ ParameterList ] ')' ( FunctionBody | ';' ) ; |
| 372 | | |
| 373 | | (* For defining a destructor *) |
| 374 | | Destructor = '~' 'this' '(' ')' ( FunctionBody | ';' ) ; |
| 375 | | |
| 376 | | (* For invariant scoping *) |
| 377 | | Invariant = 'invariant' [ '(' ')' ] BlockStatement ; |
| 378 | | |
| 379 | | (* A scope *) |
| 380 | | BlockStatement = '{' [ { Statement } ] '}' ; |
| 381 | | |
| 382 | | (* For normal statements *) |
| 383 | | Statement = NonEmptyStatement |
| 384 | | | BlockStatement ; |
| 385 | | |
| 386 | | (* For statements that have some code *) |
| 387 | | NonEmptyStatement = ProgramDeclaration |
| 388 | | | NonEmptyNonDeclaration ; |
| 389 | | |
| 390 | | (* For defining the unittest region *) |
| 391 | | UnitTest = 'unittest' FunctionBody ; |
| 392 | | |
| 393 | | (* For defining a static constructor *) |
| 394 | | StaticConstructor = 'static' 'this' '(' ')' FunctionBody ; |
| 395 | | |
| 396 | | (* For defining a static destructor *) |
| 397 | | StaticDestructor = 'static' '~' 'this' '(' ')' FunctionBody ; |
| 398 | | |
| 399 | | (* For using a mixin *) |
| 400 | | MixinDeclaration = 'mixin' '(' Expression ')' ';' |
| 401 | | |
| 402 | | (* For setting a new debug *) |
| 403 | | DebugSpecification = 'debug' '=' ( Identifier | IntegerLiteral ) ; |
| 404 | | |
| 405 | | (* For setting a version flag *) |
| 406 | | VersionSpecification = 'version' '=' ( Identifier | IntegerLiteral ) ; |
| 407 | | |
| 408 | | (* These are statements that have code, but do not have declarations that affect the current scope *) |
| 409 | | NonEmptyNonDeclaration = LabeledStatement |
| 410 | | | ExpressionStatement |
| 411 | | | IfStatement |
| 412 | | | ConditionalStatement |
| 413 | | | WhileStatement |
| 414 | | | DoStatement |
| 415 | | | ForStatement |
| 416 | | | ForeachStatement |
| 417 | | | ForeachRangeStatement |
| 418 | | | SwitchStatement |
| 419 | | | CaseStatement |
| 420 | | | DefaultStatement |
| 421 | | | ContinueStatement |
| 422 | | | BreakStatement |
| 423 | | | ReturnStatement |
| 424 | | | GotoStatement |
| 425 | | | WithStatement |
| 426 | | | SynchronizedStatement |
| 427 | | | TryStatement |
| 428 | | | ScopeGuardStatement |
| 429 | | | ThrowStatement |
| 430 | | | VolatileStatement |
| 431 | | | AsmStatement |
| 432 | | | PragmaStatement ; |
| 433 | | |
| 434 | | (* For defining labels *) |
| 435 | | LabeledStatement = Identifier ':' NoScopeStatement ; |
| 436 | | |
| 437 | | (* These statements do not change scope *) |
| 438 | | NoScopeStatement = NonEmptyStatement |
| 439 | | | BlockStatement ; |
| 440 | | |
| 441 | | (* This statement represents an expression *) |
| 442 | | ExpressionStatement = Expression ';' ; |
| 443 | | |
| 444 | | (* The definition of an expression *) |
| 445 | | Expression = AssignExpr [ { ',' AssignExpr } ] ; |
| 446 | | |
| 447 | | (* This statement is the if-else conditional statement *) |
| 448 | | IfStatement = 'if' '(' IfCondition ')' ScopeStatement [ 'else' ScopeStatement ] ; |
| 449 | | |
| 450 | | (* Conditions allowed in an if statement *) |
| 451 | | IfCondition = Expression |
| 452 | | | 'auto' Identifier '=' Expression |
| 453 | | | BasicType Declarator '=' Expression ; |
| 454 | | |
| 455 | | (* This statement will have its own scope *) |
| 456 | | ScopeStatement = NonEmptyStatement |
| 457 | | | Statement ; |
| 458 | | |
| 459 | | (* This statement is based upon a condition *) |
| 460 | | ConditionalStatement = Condition Statement [ 'else' Statement ] ; |
| 461 | | |
| 462 | | (* For defining a while statement *) |
| 463 | | WhileStatement = 'while' '(' Expression ')' ScopeStatement ; |
| 464 | | |
| 465 | | (* For defining a do statement *) |
| 466 | | DoStatement = 'do' ScopeStatement 'while' '(' Expression ')' ; |
| 467 | | |
| 468 | | (* For defining a for statement *) |
| 469 | | ForStatement = 'for' '(' NoScopeNonEmptyStatement [ Expression ] ';' [ Expression ] ')' ScopeStatement ; |
| 470 | | |
| 471 | | (* For statements that do not change scope and are not empty *) |
| 472 | | NoScopeNonEmptyStatement = NonEmptyStatement |
| 473 | | | BlockStatement ; |
| 474 | | |
| 475 | | (* For defining a foreach statement *) |
| 476 | | ForeachStatement = Foreach '(' ForeachTypeList ';' Expression ')' ScopeStatement ; |
| 477 | | |
| 478 | | (* There are two types of foreach loops *) |
| 479 | | (* Each works the same syntactically *) |
| 480 | | Foreach = 'foreach' |
| 481 | | | 'foreach_reverse' ; |
| 482 | | |
| 483 | | (* For defining the types that will be set on the iteration *) |
| 484 | | ForeachTypeList = ForeachType [ { ',' ForeachType } ] ; |
| 485 | | |
| 486 | | (* Defines what is allowed as a type within the list that contains the values to be pulled from the iteration *) |
| 487 | | ForeachType = [ ( 'inout' | 'ref' ) ] [ Type ] Identifier ; |
| 488 | | |
| 489 | | (* For defining a foreach that uses a range *) |
| 490 | | ForeachRangeStatement = Foreach '(' ForeachType ';' AssignExpr '..' AssignExpr ')' ScopeStatement ; |
| 491 | | |
| 492 | | (* For defining a switch statement *) |
| 493 | | SwitchStatement = 'switch' '(' Expression ')' BlockStatement ; |
| 494 | | |
| 495 | | (* For defining a case of a switch statement *) |
| 496 | | CaseStatement = 'case' Expression ':' ; |
| 497 | | |
| 498 | | (* For defining the default case of a switch statement *) |
| 499 | | DefaultStatement = 'default' ':' ; |
| 500 | | |
| 501 | | (* For defining the continue statement *) |
| 502 | | ContinueStatement = 'continue' [ Identifier ] ';' ; |
| 503 | | |
| 504 | | (* For defining the break statement *) |
| 505 | | BreakStatement = 'break' [ Identifier ] ';' ; |
| 506 | | |
| 507 | | (* For defining the return statement *) |
| 508 | | ReturnStatement = 'return' [ Expression ] ';' ; |
| 509 | | |
| 510 | | (* For defining the goto statement *) |
| 511 | | GotoStatement = 'goto' Identifier ';' |
| 512 | | | 'goto' 'default' ';' |
| 513 | | | 'goto' 'case' [ Expression ] ';' ; |
| 514 | | |
| 515 | | (* For defining the with statement *) |
| 516 | | WithStatement = 'with' '(' Expression ')' ScopeStatement |
| 517 | | | 'with' '(' TemplateInstance ')' ScopeStatement ; |
| 518 | | |
| 519 | | (* For defining the synchronized statement *) |
| 520 | | SynchronizedStatement = 'synchronized' NoDeclScopeStatement |
| 521 | | | 'synchronized' '(' Expression ')' ScopeStatement ; |
| 522 | | |
| 523 | | (* These statements are not declarations but do change scope *) |
| 524 | | NoDeclScopeStatement = NonEmptyNoDeclStatement |
| 525 | | | BlockStatement ; |
| 526 | | |
| 527 | | (* For defining try blocks *) |
| 528 | | TryStatement = 'try' ScopeStatement [ CatchList ] [ FinallyStatement ] ; |
| 529 | | |
| 530 | | (* For defining the types of catch blocks allowed for the try *) |
| 531 | | CatchList = [ { 'catch' '(' Parameter ')' NoScopeNonEmptyStatement } ] [ 'catch' NoScopeNonEmptyStatement ] ; |
| 532 | | |
| 533 | | (* For defining the finally block of a try *) |
| 534 | | FinallyStatement = 'finally' NoScopeNonEmptyStatement ; |
| 535 | | |
| 536 | | (* For defining the scope statement *) |
| 537 | | ScopeGuardStatement = 'scope' '(' Identifier ')' Statement ; |
| 538 | | |
| 539 | | (* For defining the throw statement *) |
| 540 | | ThrowStatement = 'throw' Expression ';' ; |
| 541 | | |
| 542 | | (* For defining the volatile statement *) |
| 543 | | VolatileStatement = 'volatile' Statement |
| 544 | | | 'volatile' ';' ; |
| 545 | | |
| 546 | | (* For defining asm blocks *) |
| 547 | | AsmStatement = 'asm' '{' [ { AsmInstruction } ] '}' ; |
| 548 | | |
| 549 | | AsmInstruction = ; (* TODO *) |
| 550 | | |
| 551 | | (* For defining the pragma statement *) |
| 552 | | PragmaStatement = Pragma ; |
| 553 | | |
| 554 | | (* For defining expressions that contain assignment *) |
| 555 | | AssignExpr = ConditionalExpression |
| 556 | | | ConditionalExpression '=' AssignExpr |
| 557 | | | ConditionalExpression '+=' AssignExpr |
| 558 | | | ConditionalExpression '-=' AssignExpr |
| 559 | | | ConditionalExpression '*=' AssignExpr |
| 560 | | | ConditionalExpression '/=' AssignExpr |
| 561 | | | ConditionalExpression '%=' AssignExpr |
| 562 | | | ConditionalExpression '&=' AssignExpr |
| 563 | | | ConditionalExpression '|=' AssignExpr |
| 564 | | | ConditionalExpression '^=' AssignExpr |
| 565 | | | ConditionalExpression '~=' AssignExpr |
| 566 | | | ConditionalExpression '<<=' AssignExpr |
| 567 | | | ConditionalExpression '>>=' AssignExpr |
| 568 | | | ConditionalExpression '>>>=' AssignExpr ; |
| 569 | | |
| 570 | | (* For defining expressions that have a ternary operation *) |
| 571 | | ConditionalExpression = LogicalOrExpression [ '?' Expression ':' ConditionalExpression ] ; |
| 572 | | |
| 573 | | (* For defining expressions that have a logical or operation *) |
| 574 | | LogicalOrExpression = [ LogicalOrExpression '||' ] LogicalAndExpression ; |
| 575 | | |
| 576 | | (* For defining expressions that have a logical and operation *) |
| 577 | | LogicalAndExpression = [ LogicalAndExpression '&&' ] OrExpression ; |
| 578 | | |
| 579 | | (* For defining expressions that have a bitwise or operation *) |
| 580 | | OrExpression = [ OrExpression '|' ] XorExpression ; |
| 581 | | |
| 582 | | (* For defining expressions that have a bitwise xor operation *) |
| 583 | | XorExpression = [ XorExpression '^' ] AndExpression ; |
| 584 | | |
| 585 | | (* For defining expressions that have a bitwise and operation *) |
| 586 | | AndExpression = [ AndExpression '&' ] CmpExpression ; |
| 587 | | |
| 588 | | (* For defining expressions that make a comparison *) |
| 589 | | CmpExpression = ShiftExpression |
| 590 | | | ShiftExpression '==' ShiftExpression |
| 591 | | | ShiftExpression '!=' ShiftExpression |
| 592 | | | ShiftExpression 'is' ShiftExpression |
| 593 | | | ShiftExpression '!is' ShiftExpression |
| 594 | | | ShiftExpression '<' ShiftExpression |
| 595 | | | ShiftExpression '<=' ShiftExpression |
| 596 | | | ShiftExpression '>' ShiftExpression |
| 597 | | | ShiftExpression '>=' ShiftExpression |
| 598 | | | ShiftExpression '!<>=' ShiftExpression |
| 599 | | | ShiftExpression '!<>' ShiftExpression |
| 600 | | | ShiftExpression '<>' ShiftExpression |
| 601 | | | ShiftExpression '<>=' ShiftExpression |
| 602 | | | ShiftExpression '!>' ShiftExpression |
| 603 | | | ShiftExpression '!>=' ShiftExpression |
| 604 | | | ShiftExpression '!<' ShiftExpression |
| 605 | | | ShiftExpression '!<=' ShiftExpression |
| 606 | | | ShiftExpression 'in' ShiftExpression ; |
| 607 | | |
| 608 | | (* For defining expressions that perform a shift operation *) |
| 609 | | ShiftExpression = AddExpression |
| 610 | | | ShiftExpression '<<' AddExpression |
| 611 | | | ShiftExpression '>>' AddExpression |
| 612 | | | ShiftExpression '>>>' AddExpression ; |
| 613 | | |
| 614 | | (* For defining expressions that perform an add operation *) |
| 615 | | AddExpression = MulExpression |
| 616 | | | AddExpression '+' MulExpression |
| 617 | | | AddExpression '-' MulExpression |
| 618 | | | CatExpression ; |
| 619 | | |
| 620 | | (* For defining expressions that perform a concatenate operation *) |
| 621 | | CatExpression = AddExpression '~' MulExpression ; |
| 622 | | |
| 623 | | (* For defining expressions that perform a multiplication operation *) |
| 624 | | MulExpression = UnaryExpression |
| 625 | | | MulExpression '*' UnaryExpression |
| 626 | | | MulExpression '/' UnaryExpression |
| 627 | | | MulExpression '%' UnaryExpression ; |
| 628 | | |
| 629 | | (* For defining expressions that perform a unary operation *) |
| 630 | | UnaryExpression = PostfixExpression |
| 631 | | | '&' UnaryExpression |
| 632 | | | '++' UnaryExpression |
| 633 | | | '--' UnaryExpression |
| 634 | | | '*' UnaryExpression |
| 635 | | | '-' UnaryExpression |
| 636 | | | '+' UnaryExpression |
| 637 | | | '!' UnaryExpression |
| 638 | | | '~' UnaryExpression |
| 639 | | | '(' Type ')' '.' Identifier |
| 640 | | | NewExpression |
| 641 | | | 'delete' UnaryExpression |
| 642 | | | 'cast' '(' Type ')' UnaryExpression ; |
| 643 | | |
| 644 | | (* For defining anything left *) |
| 645 | | PostfixExpression = IntegerLiteral |
| 646 | | | FloatLiteral |
| 647 | | | '$' |
| 648 | | | 'null' |
| 649 | | | 'true' |
| 650 | | | 'false' |
| 651 | | | AssertExpression |
| 652 | | | MixinExpression |
| 653 | | | IsExpression |
| 654 | | | PostfixExpressionList ; |
| 655 | | |
| 656 | | (* Further syntax *) |
| 657 | | PostfixExpressionList = PrimaryExpression |
| 658 | | | PostfixExpressionList '.' Identifier |
| 659 | | | PostfixExpressionList '.' TemplateInstance |
| 660 | | | PostfixExpressionList '++' |
| 661 | | | PostfixExpressionList '--' |
| 662 | | | PostfixExpressionList '(' ArgumentList ')' |
| 663 | | | PostfixExpressionList '[' ArgumentList ']' |
| 664 | | | PostfixExpressionList '[' AssignExpr '..' AssignExpr ']' ; |
| 665 | | |
| 666 | | (* These contain expressions that are of lowest precedence *) |
| 667 | | PrimaryExpression = [ '.' ] Identifier |
| 668 | | | [ '.' ] TemplateInstance |
| 669 | | | 'this' |
| 670 | | | 'super' |
| 671 | | | CharacterLiteral |
| 672 | | | StringLiteral |
| 673 | | | ArrayLiteral |
| 674 | | | AssocArrayLiteral |
| 675 | | | FunctionLiteral |
| 676 | | | ImportExpression |
| 677 | | | BasicTypeNoIdList |
| 678 | | | 'typeid' '(' Type ')' |
| 679 | | | '(' Expression ')' |
| 680 | | | TraitsExpression ; |
| 681 | | |
| 682 | | (* For defining array literals *) |
| 683 | | ArrayLiteral = '[' [ { Expression } ] ']' ; |
| 684 | | |
| 685 | | (* For defining associative array literals *) |
| 686 | | AssocArrayLiteral = '[' KeyValuePair [ { ',' KeyValuePair } ] ']' ; |
| 687 | | |
| 688 | | (* For defining members of associative array literals *) |
| 689 | | KeyValuePair = ConditionalExpression ':' ConditionalExpression ; |
| 690 | | |
| 691 | | (* For defining function literals *) |
| 692 | | FunctionLiteral = 'function' [ Type ] '(' [ ParameterList ] ')' FunctionBody |
| 693 | | | 'function' [ Type ] FunctionBody |
| 694 | | | 'delegate' [ Type ] '(' [ ParameterList ] ')' FunctionBody |
| 695 | | | 'delegate' [ Type ] FunctionBody |
| 696 | | | '(' [ ParameterList ] ')' FunctionBody |
| 697 | | | FunctionBody ; |
| 698 | | |
| 699 | | (* For defining assert expressions *) |
| 700 | | AssertExpression = 'assert' '(' AssignExpr [ ',' AssignExpr ] ')' ; |
| 701 | | |
| 702 | | (* For defining import expressions *) |
| 703 | | ImportExpression = 'import' '(' AssignExpr ')' ; |
| 704 | | |
| 705 | | (* For defining traits expressions *) |
| 706 | | TraitsExpression = '__traits' '(' Identifier ',' TraitsArgument [ { ',' TraitsArgument } ] ')' ; |
| 707 | | |
| 708 | | (* An argument for a traits expression *) |
| 709 | | TraitsArgument = AssignExpr |
| 710 | | | Type ; |
| 711 | | |
| 712 | | (* For defining the new expression *) |
| 713 | | NewExpression = NewArguments Type '[' AssignExpr ']' |
| 714 | | | NewArguments Type '(' [ Expression ] ')' |
| 715 | | | NewArguments Type |
| 716 | | | NewArguments 'class' [ '(' [ Expression ] ')' ] [ ':' BaseClassList ] '{' [ { Declaration } ] '}' ; |
| 717 | | |
| 718 | | (* Common syntax for new *) |
| 719 | | NewArguments = 'new' [ '(' [ Expression ] ')' ] ; |
| 720 | | |
| 721 | | (* For defining the mixin expression *) |
| 722 | | MixinExpression = 'mixin' '(' AssignExpr ')' ; |
| 723 | | |
| 724 | | (* For defining the is expression *) |
| 725 | | IsExpression = IsNotIs '(' Type ')' |
| 726 | | | IsNotIs '(' Type ':' TypeSpecialization ')' |
| 727 | | | IsNotIs '(' Type '==' TypeSpecialization ')' |
| 728 | | | IsNotIs '(' Type Identifier ')' |
| 729 | | | IsNotIs '(' Type Identifier ':' TypeSpecialization [ ',' TemplateParameterList ] ')' |
| 730 | | | IsNotIs '(' Type Identifier '==' TypeSpecialization [ ',' TemplateParameterList ] ')' |
| 731 | | |
| 732 | | (* Particular specializations that can be used within the is expression *) |
| 733 | | TypeSpecialization = Type |
| 734 | | | 'typedef' |
| 735 | | | 'struct' |
| 736 | | | 'union' |
| 737 | | | 'class' |
| 738 | | | 'interface' |
| 739 | | | 'enum' |
| 740 | | | 'function' |
| 741 | | | 'delegate' |
| 742 | | | 'super' |
| 743 | | | 'return' |
| 744 | | |
| | 8 | #!html |
| | 9 | <pre> |
| | 10 | /* The main starting point is the Module */ |
| | 11 | Module: ModuleDecl Declaration* |
| | 12 | |
| | 13 | /* This describes the module and gives the name */ |
| | 14 | ModuleDecl: module ModuleName |
| | 15 | |
| | 16 | /* The syntax for the module name */ |
| | 17 | ModuleName: ModuleName . Identifier |
| | 18 | Identifier |
| | 19 | |
| | 20 | /* The syntax for basically everything else */ |
| | 21 | Declaration: ConditionalCompilationDecl |
| | 22 | ProgramDeclaration |
| | 23 | |
| | 24 | /* This declaration describes a compile time condition */ |
| | 25 | ConditionalCompilationDecl: CompilationCondition \: |
| | 26 | CompilationCondition DeclarationBlock [ else DeclarationBlock ] |
| | 27 | |
| | 28 | /* There are three types of compile time conditions */ |
| | 29 | CompilationCondition: VersionCondition |
| | 30 | DebugCondition |
| | 31 | StaticIfCondition |
| | 32 | |
| | 33 | /* The version condition */ |
| | 34 | VersionCondition: version \( IntegerLiteral \) |
| | 35 | version \( Identifier \) |
| | 36 | |
| | 37 | /* This is for a conditional debug */ |
| | 38 | DebugCondition: debug \( IntegerLiteral \) |
| | 39 | debug \( Identifier \) |
| | 40 | debug |
| | 41 | |
| | 42 | /* The more traditional if-else condition */ |
| | 43 | StaticIfCondition: static if \( AssignExpr \) |
| | 44 | |
| | 45 | /* Now for the traditional declarations */ |
| | 46 | ProgramDeclaration: AttributeSpecifier |
| | 47 | StaticAssert |
| | 48 | TypeDeclaration |
| | 49 | ImportDeclaration |
| | 50 | EnumDeclaration |
| | 51 | TemplateMixin |
| | 52 | TemplateDeclaration |
| | 53 | FunctionTemplateDeclaration |
| | 54 | ClassTemplateDeclaration |
| | 55 | InterfaceTemplateDeclaration |
| | 56 | StructTemplateDeclaration |
| | 57 | ClassDeclaration |
| | 58 | InterfaceDeclaration |
| | 59 | AggregateDeclaration |
| | 60 | Constructor |
| | 61 | Destructor |
| | 62 | Invariant |
| | 63 | UnitTest |
| | 64 | StaticConstructor |
| | 65 | StaticDestructor |
| | 66 | MixinDeclaration |
| | 67 | DebugSpecification |
| | 68 | VersionSpecification |
| | 69 | ; |
| | 70 | |
| | 71 | /* For attribute blocks */ |
| | 72 | /* example: `public:` or `exter (C) { ... }` */ |
| | 73 | AttributeSpecifier: Attribute+ \: Declaration* |
| | 74 | Attribute+ DeclarationBlock |
| | 75 | |
| | 76 | /* There are five categories of attributes */ |
| | 77 | Attribute: StorageClassAttribute |
| | 78 | ProtectionAttribute |
| | 79 | LinkageAttribute |
| | 80 | AlignAttribute |
| | 81 | Pragma |
| | 82 | |
| | 83 | /* These attributes dictate the storage semantics */ |
| | 84 | StorageClassAttribute: synchronized |
| | 85 | deprecated |
| | 86 | static |
| | 87 | final |
| | 88 | override |
| | 89 | abstract |
| | 90 | const |
| | 91 | auto |
| | 92 | scope |
| | 93 | |
| | 94 | /* These attributes dictate the access permissions of member items */ |
| | 95 | ProtectionAttribute: private |
| | 96 | package |
| | 97 | protected |
| | 98 | public |
| | 99 | export |
| | 100 | |
| | 101 | /* These attributes consider external linking */ |
| | 102 | LinkageAttribute: extern \( Identifier \) |
| | 103 | extern \( C\+\+ \) |
| | 104 | extern |
| | 105 | |
| | 106 | /* These attributes change byte packing considerations */ |
| | 107 | AlignAttribute: align \( IntegerLiteral \) |
| | 108 | align |
| | 109 | |
| | 110 | /* A pragma may be used as an attribute */ |
| | 111 | Pragma: pragma \( Identifier [ , Expression ] \) |
| | 112 | |
| | 113 | /* This is a block of Declarations */ |
| | 114 | DeclarationBlock: { Declaration* } |
| | 115 | Declaration |
| | 116 | |
| | 117 | /* A static assert will be judged at compile time */ |
| | 118 | StaticAssert: static assert \( AssignExpr [ , AssignExpr ] \) ; |
| | 119 | |
| | 120 | /* This declaration is for typing data */ |
| | 121 | TypeDeclaration: TypedefAlias Attribute* [ Identifier = AssignExpr ] TypeDeclarationPost |
| | 122 | Attribute+ TypeDeclarationPost |
| | 123 | Attribute+ Identifier = AssignExpr ( , Identifier = AssignExpr )* ; |
| | 124 | TypeDeclarationPost |
| | 125 | |
| | 126 | /* Some spillover from the above description */ |
| | 127 | TypeDeclarationPost: BasicType Declarator FunctionBody |
| | 128 | BasicType Declarator [ = Initializer ] (, IdentifierInitializer )* ; |
| | 129 | |
| | 130 | /* This will, for example, be used for initializing a variable */ |
| | 131 | IdentifierInitializer: Identifier [ = Initializer ] |
| | 132 | |
| | 133 | /* What you can initialize with */ |
| | 134 | Initializer: void |
| | 135 | NonVoidInitializer |
| | 136 | |
| | 137 | /* You can initialize with some values */ |
| | 138 | NonVoidInitializer: AssignExpr |
| | 139 | ArrayInitializer |
| | 140 | StructInitializer |
| | 141 | |
| | 142 | /* Initializing arrays with this syntax */ |
| | 143 | ArrayInitializer: \[ [ ArrayStructMemberInitializer ( , ArrayStructMemberInitializer )* ] \] |
| | 144 | |
| | 145 | /* Initializing structs has this syntax */ |
| | 146 | StructInitializer: { [ ArrayStructMemberInitializer ( , ArrayStructMemberInitializer )* ] } |
| | 147 | |
| | 148 | /* What you can initialize struct and array members */ |
| | 149 | ArrayStructMemberInitializer: NonVoidInitializer |
| | 150 | Identifier \: NonVoidInitializer |
| | 151 | |
| | 152 | /* Defines typedef and alias keywords within the grammar */ |
| | 153 | TypedefAlias: typedef |
| | 154 | alias |
| | 155 | |
| | 156 | /* For importing modules into the current module */ |
| | 157 | ImportDeclaration: import ImportList ; |
| | 158 | |
| | 159 | /* You may list more than one import */ |
| | 160 | ImportList: Import ( , Import )* |
| | 161 | Import ImportBindList |
| | 162 | |
| | 163 | /* You import my selecting a valid module name */ |
| | 164 | /* Optionally you can namespace this module to a specific identifier */ |
| | 165 | Import: [ Identifier = ] ModuleName |
| | 166 | |
| | 167 | /* You can also pull only particular names from a module */ |
| | 168 | ImportBindList: \: ImportBind ( , ImportBind )* |
| | 169 | |
| | 170 | /* You can rename these items */ |
| | 171 | ImportBind: [ Identifier = ] Identifier |
| | 172 | |
| | 173 | /* The definition for an enum */ |
| | 174 | EnumDeclaration: enum [ Identifier ] [ Type ] EnumBody |
| | 175 | |
| | 176 | /* The body of an enum contains many comma separated members */ |
| | 177 | /* An optional last comma is allowed */ |
| | 178 | EnumBody: { EnumMember ( , EnumMember )* [ , ] } |
| | 179 | ; |
| | 180 | |
| | 181 | /* Each enum member is a simple identifier */ |
| | 182 | /* Optionally, you can assign a value for this member */ |
| | 183 | EnumMember: Identifier [ = AssignExpr ] |
| | 184 | |
| | 185 | /* The definition for a mixin template */ |
| | 186 | TemplateMixin: mixin Identifier [ ! \( [ TemplateArgumentList ] \) ] [ Identifier ] |
| | 187 | |
| | 188 | /* Template argument list */ |
| | 189 | TemplateArgumentList: TemplateArgument ( , TemplateArgument )* |
| | 190 | |
| | 191 | /* The definition for a template */ |
| | 192 | TemplateDeclaration: template Identifier \( [ TemplateParameterList ] \) TemplateBody |
| | 193 | |
| | 194 | /* The template parameter list */ |
| | 195 | TemplateParameterList: TemplateParameter ( , TemplateParameter )* |
| | 196 | |
| | 197 | /* There are four different template parameter types */ |
| | 198 | TemplateParameter: TemplateAliasParameter |
| | 199 | TemplateTupleParameter |
| | 200 | TemplateValueParameter |
| | 201 | TemplateTypeParameter |
| | 202 | |
| | 203 | /* An alias parameter */ |
| | 204 | TemplateAliasParameter: alias Identifier [ \: Type ] [ = Type ] |
| | 205 | |
| | 206 | /* A tuple */ |
| | 207 | TemplateTupleParameter: Identifier ... |
| | 208 | |
| | 209 | /* A basic value */ |
| | 210 | TemplateValueParameter: BasicType Declarator [ \: ConditionalExpr ] [ = ConditionalExpr ] |
| | 211 | |
| | 212 | /* A generic type */ |
| | 213 | TemplateTypeParameter: Identifier [ \: Type ] [ = Type ] |
| | 214 | |
| | 215 | /* The body of a template */ |
| | 216 | TemplateBody: { ( Declaration )* } |
| | 217 | |
| | 218 | /* The basic types and a identifier list */ |
| | 219 | BasicType: BasicTypeNoIdList |
| | 220 | [ . ] IdentifierList |
| | 221 | |
| | 222 | /* The basic types that can be used in various places */ |
| | 223 | BasicTypeNoIdList: ( bool byte ubyte short ushort int uint long ulong |
| | 224 | char wchar dchar float double real ifloat idouble |
| | 225 | ireal cfloat cdouble creal void |
| | 226 | Typeof [ IdentifierList ] |
| | 227 | TypeConstructor \( Type \) ) |
| | 228 | |
| | 229 | /* some extra attributes for types */ |
| | 230 | TypeConstructor: const |
| | 231 | invariant |
| | 232 | |
| | 233 | /* The definition of typeof */ |
| | 234 | Typeof: typeof \( Expression \) |
| | 235 | |
| | 236 | /* What constitutes a type */ |
| | 237 | Type: BasicType [ DeclaratorPost ] |
| | 238 | |
| | 239 | /* Traversing an identifier list */ |
| | 240 | IdentifierList: ( Identifier TemplateInstance ) ( ( . Identifier . TemplateInstance ) )* |
| | 241 | |
| | 242 | /* Declarator */ |
| | 243 | Declarator: DeclaratorType [ Declarator ] |
| | 244 | Identifier ( DeclaratorSuffix )* |
| | 245 | \( Declarator \) ( DeclaratorSuffix )* |
| | 246 | |
| | 247 | DeclaratorPost: DeclaratorType [ DeclaratorPost ] |
| | 248 | \( Declarator2 \) ( DeclaratorSuffix )* |
| | 249 | |
| | 250 | DeclaratorType: \* |
| | 251 | \[ \] |
| | 252 | \[ Expression \] |
| | 253 | \[ Type \] |
| | 254 | \[ AssignExpr .. AssignExpr \] |
| | 255 | delegate \( [ ParameterList ] \) |
| | 256 | function \( [ ParameterList ] \) |
| | 257 | |
| | 258 | DeclaratorSuffix: \[ \] |
| | 259 | \[ Expression \] |
| | 260 | \[ Type \] |
| | 261 | \( [ ParameterList ] \) |
| | 262 | |
| | 263 | /* For parameters of functions */ |
| | 264 | ParameterList: Parameter [ ... ] ( , Parameter [ ... ] )* |
| | 265 | |
| | 266 | /* The definition of a parameter */ |
| | 267 | Parameter: [ InOut ] [ ParameterStorageClass ] BasicType [ Declarator ] [ = AssignExpr ] |
| | 268 | |
| | 269 | /* Parameters may have these extra attributes */ |
| | 270 | ParameterStorageClass: const |
| | 271 | invariant |
| | 272 | final |
| | 273 | scope |
| | 274 | static |
| | 275 | |
| | 276 | /* The passing constraints for parameters */ |
| | 277 | InOut: inout |
| | 278 | in |
| | 279 | out |
| | 280 | ref |
| | 281 | lazy |
| | 282 | |
| | 283 | /* The Type declaration for a template instance */ |
| | 284 | TemplateInstance: Identifier ! \( [ TemplateArgumentList ] \) |
| | 285 | |
| | 286 | /* The declaration of a function template */ |
| | 287 | FunctionTemplateDeclaration: ( BasicType Type ) Identifier \( TemplateParameterList \) \( [ ParameterList ] \) FunctionBody |
| | 288 | |
| | 289 | /* The body of a function or a template function */ |
| | 290 | FunctionBody: [ InStatement ] OutStatement BodyStatement |
| | 291 | [ OutStatement ] InStatement BodyStatement |
| | 292 | BodyStatement |
| | 293 | |
| | 294 | /* The definition of the in statement */ |
| | 295 | InStatement: in BlockStatement |
| | 296 | |
| | 297 | /* The definition of the out statement */ |
| | 298 | OutStatement: out [ \( Identifier \) ] BlockStatement |
| | 299 | |
| | 300 | /* The body statement, which is the normal function body */ |
| | 301 | BodyStatement: [ body ] BlockStatement |
| | 302 | |
| | 303 | /* For defining a class template */ |
| | 304 | ClassTemplateDeclaration: class Identifier \( [ TemplateParameterList ] \) [ \: BaseClassList ] ClassBody |
| | 305 | |
| | 306 | /* The list of inherited classes */ |
| | 307 | BaseClassList: BaseClass [ , BaseClass ] |
| | 308 | |
| | 309 | /* An item in the inherited class list */ |
| | 310 | BaseClass: [ Protection ] IdentifierList |
| | 311 | |
| | 312 | /* The protection attributes available for constraining inherited classes */ |
| | 313 | Protection: private |
| | 314 | protected |
| | 315 | public |
| | 316 | export |
| | 317 | |
| | 318 | /* The body of a class */ |
| | 319 | ClassBody: { ( ClassBodyDeclaration )* } |
| | 320 | |
| | 321 | /* Each declaration at the class body level */ |
| | 322 | ClassBodyDeclaration: Declaration |
| | 323 | ClassAllocator |
| | 324 | ClassDeallocator |
| | 325 | |
| | 326 | /* For overriding at memory allocation, that is at call to new */ |
| | 327 | ClassAllocator: new \( [ ParameterList ] \) FunctionBody |
| | 328 | |
| | 329 | /* For overriding at memory deallocation, that is at call to delete */ |
| | 330 | ClassDeallocator: delete \( [ ParameterList ] \) FunctionBody |
| | 331 | |
| | 332 | /* For defining an interface template */ |
| | 333 | InterfaceTemplateDeclaration: interface Identifier \( [ TemplateParameterList ] \) [ \: BaseInterfaceList ] InterfaceBody |
| | 334 | |
| | 335 | /* For all inherited interfaces */ |
| | 336 | BaseInterfaceList: BaseInterface [ , BaseInterface ] |
| | 337 | |
| | 338 | /* Each item in the list of inherited interfaces */ |
| | 339 | BaseInterface: [ Protection ] IdentifierList |
| | 340 | |
| | 341 | /* The body of an interface */ |
| | 342 | InterfaceBody: { Declaration* } |
| | 343 | |
| | 344 | /* For defining a struct template */ |
| | 345 | StructTemplateDeclaration: struct Identifier \( [ TemplateParameterList ] \) StructBody |
| | 346 | |
| | 347 | /* The body of a struct or struct template */ |
| | 348 | StructBody: { StructBodyDeclaration* } [ ; ] |
| | 349 | |
| | 350 | /* Each declaration allowed within a struct body */ |
| | 351 | StructBodyDeclaration: Declaration |
| | 352 | StructAllocator |
| | 353 | StructDeallocator |
| | 354 | |
| | 355 | /* For overriding at memory allocation, that is upon new */ |
| | 356 | StructAllocator: ClassAllocator |
| | 357 | |
| | 358 | /* For overriding at memory deallocation, that is upon delete */ |
| | 359 | StructDeallocator: ClassDeallocator |
| | 360 | |
| | 361 | /* For defining a class */ |
| | 362 | ClassDeclaration: class Identifier [ BassClassList ] ClassBody |
| | 363 | |
| | 364 | /* For defining an interface */ |
| | 365 | InterfaceDeclaration: interface Identifier [ BaseInterfaceList ] InterfaceBody |
| | 366 | |
| | 367 | /* For defining a struct or union */ |
| | 368 | AggregateDeclaration: Tag [ Identifier ] StructBody |
| | 369 | Tag [ Identifier ] ; |
| | 370 | |
| | 371 | /* Aggregates can be either structs or unions */ |
| | 372 | Tag: struct |
| | 373 | union |
| | 374 | |
| | 375 | /* For defining a constructor */ |
| | 376 | Constructor: this \( [ ParameterList ] \) ( FunctionBody ; ) |
| | 377 | |
| | 378 | /* For defining a destructor */ |
| | 379 | Destructor: ~ this \( \) ( FunctionBody ; ) |
| | 380 | |
| | 381 | /* For invariant scoping */ |
| | 382 | Invariant: invariant [ \( \) ] BlockStatement |
| | 383 | |
| | 384 | /* A scope */ |
| | 385 | BlockStatement: { Statement* } |
| | 386 | |
| | 387 | /* For normal statements */ |
| | 388 | Statement: NonEmptyStatement |
| | 389 | BlockStatement |
| | 390 | |
| | 391 | /* For statements that have some code */ |
| | 392 | NonEmptyStatement: ProgramDeclaration |
| | 393 | NonEmptyNonDeclaration |
| | 394 | |
| | 395 | /* For defining the unittest region */ |
| | 396 | UnitTest: unittest FunctionBody |
| | 397 | |
| | 398 | /* For defining a static constructor */ |
| | 399 | StaticConstructor: static this \( \) FunctionBody |
| | 400 | |
| | 401 | /* For defining a static destructor */ |
| | 402 | StaticDestructor: static ~ this \( \) FunctionBody |
| | 403 | |
| | 404 | /* For using a mixin */ |
| | 405 | MixinDeclaration: mixin \( Expression \) ; |
| | 406 | |
| | 407 | /* For setting a new debug */ |
| | 408 | DebugSpecification: debug = ( Identifier IntegerLiteral ) |
| | 409 | |
| | 410 | /* For setting a version flag */ |
| | 411 | VersionSpecification: version = ( Identifier IntegerLiteral ) |
| | 412 | |
| | 413 | /* These are statements that have code, but do not have declarations that affect the current scope */ |
| | 414 | NonEmptyNonDeclaration: LabeledStatement |
| | 415 | ExpressionStatement |
| | 416 | IfStatement |
| | 417 | ConditionalStatement |
| | 418 | WhileStatement |
| | 419 | DoStatement |
| | 420 | ForStatement |
| | 421 | ForeachStatement |
| | 422 | ForeachRangeStatement |
| | 423 | SwitchStatement |
| | 424 | CaseStatement |
| | 425 | DefaultStatement |
| | 426 | ContinueStatement |
| | 427 | BreakStatement |
| | 428 | ReturnStatement |
| | 429 | GotoStatement |
| | 430 | WithStatement |
| | 431 | SynchronizedStatement |
| | 432 | TryStatement |
| | 433 | ScopeGuardStatement |
| | 434 | ThrowStatement |
| | 435 | VolatileStatement |
| | 436 | AsmStatement |
| | 437 | PragmaStatement |
| | 438 | |
| | 439 | /* For defining labels */ |
| | 440 | LabeledStatement: Identifier \: NoScopeStatement |
| | 441 | |
| | 442 | /* These statements do not change scope */ |
| | 443 | NoScopeStatement: NonEmptyStatement |
| | 444 | BlockStatement |
| | 445 | |
| | 446 | /* This statement represents an expression */ |
| | 447 | ExpressionStatement: Expression ; |
| | 448 | |
| | 449 | /* The definition of an expression */ |
| | 450 | Expression: AssignExpr ( , AssignExpr )* |
| | 451 | |
| | 452 | /* This statement is the if-else conditional statement */ |
| | 453 | IfStatement: if \( IfCondition \) ScopeStatement [ else ScopeStatement ] |
| | 454 | |
| | 455 | /* Conditions allowed in an if statement */ |
| | 456 | IfCondition: Expression |
| | 457 | auto Identifier = Expression |
| | 458 | BasicType Declarator = Expression |
| | 459 | |
| | 460 | /* This statement will have its own scope */ |
| | 461 | ScopeStatement: NonEmptyStatement |
| | 462 | Statement |
| | 463 | |
| | 464 | /* This statement is based upon a condition */ |
| | 465 | ConditionalStatement: Condition Statement [ else Statement ] |
| | 466 | |
| | 467 | /* For defining a while statement */ |
| | 468 | WhileStatement: while \( Expression \) ScopeStatement |
| | 469 | |
| | 470 | /* For defining a do statement */ |
| | 471 | DoStatement: do ScopeStatement while \( Expression \) |
| | 472 | |
| | 473 | /* For defining a for statement */ |
| | 474 | ForStatement: for \( NoScopeNonEmptyStatement [ Expression ] ; [ Expression ] \) ScopeStatement |
| | 475 | |
| | 476 | /* For statements that do not change scope and are not empty */ |
| | 477 | NoScopeNonEmptyStatement: NonEmptyStatement |
| | 478 | BlockStatement |
| | 479 | |
| | 480 | /* For defining a foreach statement */ |
| | 481 | ForeachStatement: Foreach \( ForeachTypeList ; Expression \) ScopeStatement |
| | 482 | |
| | 483 | /* There are two types of foreach loops */ |
| | 484 | /* Each works the same syntactically */ |
| | 485 | Foreach: foreach |
| | 486 | foreach_reverse |
| | 487 | |
| | 488 | /* For defining the types that will be set on the iteration */ |
| | 489 | ForeachTypeList: ForeachType ( , ForeachType )* |
| | 490 | |
| | 491 | /* Defines what is allowed as a type within the list that contains the values to be pulled from the iteration */ |
| | 492 | ForeachType: [ ( inout ref ) ] [ Type ] Identifier |
| | 493 | |
| | 494 | /* For defining a foreach that uses a range */ |
| | 495 | ForeachRangeStatement: Foreach \( ForeachType ; AssignExpr .. AssignExpr \) ScopeStatement |
| | 496 | |
| | 497 | /* For defining a switch statement */ |
| | 498 | SwitchStatement: switch \( Expression \) BlockStatement |
| | 499 | |
| | 500 | /* For defining a case of a switch statement */ |
| | 501 | CaseStatement: case Expression \: |
| | 502 | |
| | 503 | /* For defining the default case of a switch statement */ |
| | 504 | DefaultStatement: default \: |
| | 505 | |
| | 506 | /* For defining the continue statement */ |
| | 507 | ContinueStatement: continue [ Identifier ] ; |
| | 508 | |
| | 509 | /* For defining the break statement */ |
| | 510 | BreakStatement: break [ Identifier ] ; |
| | 511 | |
| | 512 | /* For defining the return statement */ |
| | 513 | ReturnStatement: return [ Expression ] ; |
| | 514 | |
| | 515 | /* For defining the goto statement */ |
| | 516 | GotoStatement: goto Identifier ; |
| | 517 | goto default ; |
| | 518 | goto case [ Expression ] ; |
| | 519 | |
| | 520 | /* For defining the with statement */ |
| | 521 | WithStatement: with \( Expression \) ScopeStatement |
| | 522 | with \( TemplateInstance \) ScopeStatement |
| | 523 | |
| | 524 | /* For defining the synchronized statement */ |
| | 525 | SynchronizedStatement: synchronized NoDeclScopeStatement |
| | 526 | synchronized \( Expression \) ScopeStatement |
| | 527 | |
| | 528 | /* These statements are not declarations but do change scope */ |
| | 529 | NoDeclScopeStatement: NonEmptyNoDeclStatement |
| | 530 | BlockStatement |
| | 531 | |
| | 532 | /* For defining try blocks */ |
| | 533 | TryStatement: try ScopeStatement [ CatchList ] [ FinallyStatement ] |
| | 534 | |
| | 535 | /* For defining the types of catch blocks allowed for the try */ |
| | 536 | CatchList: ( catch \( Parameter \) NoScopeNonEmptyStatement )* [ catch NoScopeNonEmptyStatement ] |
| | 537 | |
| | 538 | /* For defining the finally block of a try */ |
| | 539 | FinallyStatement: finally NoScopeNonEmptyStatement |
| | 540 | |
| | 541 | /* For defining the scope statement */ |
| | 542 | ScopeGuardStatement: scope \( Identifier \) Statement |
| | 543 | |
| | 544 | /* For defining the throw statement */ |
| | 545 | ThrowStatement: throw Expression ; |
| | 546 | |
| | 547 | /* For defining the volatile statement */ |
| | 548 | VolatileStatement: volatile Statement |
| | 549 | volatile ; |
| | 550 | |
| | 551 | /* For defining asm blocks */ |
| | 552 | AsmStatement: asm { ( AsmInstruction )* } |
| | 553 | |
| | 554 | AsmInstruction: /* TODO */ |
| | 555 | |
| | 556 | /* For defining the pragma statement */ |
| | 557 | PragmaStatement: Pragma |
| | 558 | |
| | 559 | /* For defining expressions that contain assignment */ |
| | 560 | AssignExpr: ConditionalExpression |
| | 561 | ConditionalExpression = AssignExpr |
| | 562 | ConditionalExpression \+= AssignExpr |
| | 563 | ConditionalExpression -= AssignExpr |
| | 564 | ConditionalExpression \*= AssignExpr |
| | 565 | ConditionalExpression /= AssignExpr |
| | 566 | ConditionalExpression %= AssignExpr |
| | 567 | ConditionalExpression &= AssignExpr |
| | 568 | ConditionalExpression |= AssignExpr |
| | 569 | ConditionalExpression ^= AssignExpr |
| | 570 | ConditionalExpression ~= AssignExpr |
| | 571 | ConditionalExpression <<= AssignExpr |
| | 572 | ConditionalExpression >>= AssignExpr |
| | 573 | ConditionalExpression >>>= AssignExpr |
| | 574 | |
| | 575 | /* For defining expressions that have a ternary operation */ |
| | 576 | ConditionalExpression: LogicalOrExpression [ ? Expression \: ConditionalExpression ] |
| | 577 | |
| | 578 | /* For defining expressions that have a logical or operation */ |
| | 579 | LogicalOrExpression: [ LogicalOrExpression || ] LogicalAndExpression |
| | 580 | |
| | 581 | /* For defining expressions that have a logical and operation */ |
| | 582 | LogicalAndExpression: [ LogicalAndExpression && ] OrExpression |
| | 583 | |
| | 584 | /* For defining expressions that have a bitwise or operation */ |
| | 585 | OrExpression: [ OrExpression | ] XorExpression |
| | 586 | |
| | 587 | /* For defining expressions that have a bitwise xor operation */ |
| | 588 | XorExpression: [ XorExpression ^ ] AndExpression |
| | 589 | |
| | 590 | /* For defining expressions that have a bitwise and operation */ |
| | 591 | AndExpression: [ AndExpression & ] CmpExpression |
| | 592 | |
| | 593 | /* For defining expressions that make a comparison */ |
| | 594 | CmpExpression: ShiftExpression |
| | 595 | ShiftExpression == ShiftExpression |
| | 596 | ShiftExpression != ShiftExpression |
| | 597 | ShiftExpression is ShiftExpression |
| | 598 | ShiftExpression !is ShiftExpression |
| | 599 | ShiftExpression < ShiftExpression |
| | 600 | ShiftExpression <= ShiftExpression |
| | 601 | ShiftExpression > ShiftExpression |
| | 602 | ShiftExpression >= ShiftExpression |
| | 603 | ShiftExpression !<>= ShiftExpression |
| | 604 | ShiftExpression !<> ShiftExpression |
| | 605 | ShiftExpression <> ShiftExpression |
| | 606 | ShiftExpression <>= ShiftExpression |
| | 607 | ShiftExpression !> ShiftExpression |
| | 608 | ShiftExpression !>= ShiftExpression |
| | 609 | ShiftExpression !< ShiftExpression |
| | 610 | ShiftExpression !<= ShiftExpression |
| | 611 | ShiftExpression in ShiftExpression |
| | 612 | |
| | 613 | /* For defining expressions that perform a shift operation */ |
| | 614 | ShiftExpression: AddExpression |
| | 615 | ShiftExpression << AddExpression |
| | 616 | ShiftExpression >> AddExpression |
| | 617 | ShiftExpression >>> AddExpression |
| | 618 | |
| | 619 | /* For defining expressions that perform an add operation */ |
| | 620 | AddExpression: MulExpression |
| | 621 | AddExpression \+ MulExpression |
| | 622 | AddExpression - MulExpression |
| | 623 | CatExpression |
| | 624 | |
| | 625 | /* For defining expressions that perform a concatenate operation */ |
| | 626 | CatExpression: AddExpression ~ MulExpression |
| | 627 | |
| | 628 | /* For defining expressions that perform a multiplication operation */ |
| | 629 | MulExpression: UnaryExpression |
| | 630 | MulExpression \* UnaryExpression |
| | 631 | MulExpression / UnaryExpression |
| | 632 | MulExpression % UnaryExpression |
| | 633 | |
| | 634 | /* For defining expressions that perform a unary operation */ |
| | 635 | UnaryExpression: PostfixExpression |
| | 636 | & UnaryExpression |
| | 637 | \+\+ UnaryExpression |
| | 638 | -- UnaryExpression |
| | 639 | \* UnaryExpression |
| | 640 | - UnaryExpression |
| | 641 | \+ UnaryExpression |
| | 642 | ! UnaryExpression |
| | 643 | ~ UnaryExpression |
| | 644 | \( Type \) . Identifier |
| | 645 | NewExpression |
| | 646 | delete UnaryExpression |
| | 647 | cast \( Type \) UnaryExpression |
| | 648 | |
| | 649 | /* For defining anything left */ |
| | 650 | PostfixExpression: IntegerLiteral |
| | 651 | FloatLiteral |
| | 652 | $ |
| | 653 | null |
| | 654 | true |
| | 655 | false |
| | 656 | AssertExpression |
| | 657 | MixinExpression |
| | 658 | IsExpression |
| | 659 | PostfixExpressionList |
| | 660 | |
| | 661 | /* Further syntax */ |
| | 662 | PostfixExpressionList: PrimaryExpression |
| | 663 | PostfixExpressionList . Identifier |
| | 664 | PostfixExpressionList . TemplateInstance |
| | 665 | PostfixExpressionList \+\+ |
| | 666 | PostfixExpressionList -- |
| | 667 | PostfixExpressionList \( ArgumentList \) |
| | 668 | PostfixExpressionList \[ ArgumentList \] |
| | 669 | PostfixExpressionList \[ AssignExpr .. AssignExpr \] |
| | 670 | |
| | 671 | /* These contain expressions that are of lowest precedence */ |
| | 672 | PrimaryExpression: [ . ] Identifier |
| | 673 | [ . ] TemplateInstance |
| | 674 | this |
| | 675 | super |
| | 676 | CharacterLiteral |
| | 677 | StringLiteral |
| | 678 | ArrayLiteral |
| | 679 | AssocArrayLiteral |
| | 680 | FunctionLiteral |
| | 681 | ImportExpression |
| | 682 | BasicTypeNoIdList |
| | 683 | typeid \( Type \) |
| | 684 | \( Expression \) |
| | 685 | TraitsExpression |
| | 686 | |
| | 687 | /* For defining array literals */ |
| | 688 | ArrayLiteral: \[ Expression* \] |
| | 689 | |
| | 690 | /* For defining associative array literals */ |
| | 691 | AssocArrayLiteral: \[ KeyValuePair ( , KeyValuePair )* \] |
| | 692 | |
| | 693 | /* For defining members of associative array literals */ |
| | 694 | KeyValuePair: ConditionalExpression \: ConditionalExpression |
| | 695 | |
| | 696 | /* For defining function literals */ |
| | 697 | FunctionLiteral: function [ Type ] \( [ ParameterList ] \) FunctionBody |
| | 698 | function [ Type ] FunctionBody |
| | 699 | delegate [ Type ] \( [ ParameterList ] \) FunctionBody |
| | 700 | delegate [ Type ] FunctionBody |
| | 701 | \( [ ParameterList ] \) FunctionBody |
| | 702 | FunctionBody |
| | 703 | |
| | 704 | /* For defining assert expressions */ |
| | 705 | AssertExpression: assert \( AssignExpr [ , AssignExpr ] \) |
| | 706 | |
| | 707 | /* For defining import expressions */ |
| | 708 | ImportExpression: import \( AssignExpr \) |
| | 709 | |
| | 710 | /* For defining traits expressions */ |
| | 711 | TraitsExpression: __traits \( Identifier , TraitsArgument ( , TraitsArgument )* \) |
| | 712 | |
| | 713 | /* An argument for a traits expression */ |
| | 714 | TraitsArgument: AssignExpr |
| | 715 | Type |
| | 716 | |
| | 717 | /* For defining the new expression */ |
| | 718 | NewExpression: NewArguments Type \[ AssignExpr \] |
| | 719 | NewArguments Type \( [ Expression ] \) |
| | 720 | NewArguments Type |
| | 721 | NewArguments class [ \( [ Expression ] \) ] [ \: BaseClassList ] { Declaration* } |
| | 722 | |
| | 723 | /* Common syntax for new */ |
| | 724 | NewArguments: new [ \( [ Expression ] \) ] |
| | 725 | |
| | 726 | /* For defining the mixin expression */ |
| | 727 | MixinExpression: mixin \( AssignExpr \) |
| | 728 | |
| | 729 | /* For defining the is expression */ |
| | 730 | IsExpression: IsNotIs \( Type \) |
| | 731 | IsNotIs \( Type \: TypeSpecialization \) |
| | 732 | IsNotIs \( Type == TypeSpecialization \) |
| | 733 | IsNotIs \( Type Identifier \) |
| | 734 | IsNotIs \( Type Identifier \: TypeSpecialization [ , TemplateParameterList ] \) |
| | 735 | IsNotIs \( Type Identifier == TypeSpecialization [ , TemplateParameterList ] \) |
| | 736 | |
| | 737 | /* Particular specializations that can be used within the is expression */ |
| | 738 | TypeSpecialization: Type |
| | 739 | typedef |
| | 740 | struct |
| | 741 | union |
| | 742 | class |
| | 743 | interface |
| | 744 | enum |
| | 745 | function |
| | 746 | delegate |
| | 747 | super |
| | 748 | return |
| | 749 | </pre> |