1 /// Author: Aziz Köksal
2 /// License: GPL3
3 /// $(Maturity very high)
4 module dil.parser.Parser;
5 
6 import dil.lexer.Lexer,
7        dil.lexer.IdTable,
8        dil.lexer.Tables;
9 import dil.ast.Node,
10        dil.ast.Declarations,
11        dil.ast.Statements,
12        dil.ast.Expressions,
13        dil.ast.Types,
14        dil.ast.Parameters;
15 import dil.i18n.Messages;
16 import dil.Diagnostics,
17        dil.Enums,
18        dil.SourceText,
19        dil.Unicode;
20 import common;
21 
22 /// The Parser produces a full parse tree by examining
23 /// the list of tokens provided by the Lexer.
24 class Parser
25 {
26   Lexer lexer; /// Used to lex the source code.
27   Token* token; /// Current non-whitespace token.
28   Token* prevToken; /// Previous non-whitespace token.
29 
30   Diagnostics diag;     /// Collects error messages.
31   ParserError[] errors; /// Array of parser error messages.
32 
33   ImportDecl[] imports; /// ImportDeclarations in the source text.
34 
35   /// Attributes are evaluated in the parsing phase.
36   /// TODO: will be removed. SemanticPass1 takes care of attributes.
37   LinkageType linkageType;
38   Protection protection; /// ditto
39   StorageClass storageClass; /// ditto
40   uint alignSize; /// ditto
41 
42 
43   private alias T = S2T; /// Used often in this class.
44   private alias Type = TypeNode;
45 
46   /// Constructs a Parser object.
47   /// Params:
48   ///   srcText = The UTF-8 source code.
49   ///   tables = For the Lexer.
50   ///   diag = Used for collecting error messages.
51   this(SourceText srcText, LexerTables tables, Diagnostics diag = null)
52   {
53     this.diag = diag ? diag : new Diagnostics();
54     this.lexer = new Lexer(srcText, tables, diag);
55   }
56 
57   /// Moves to the first non-whitespace token.
58   protected void init()
59   {
60     lexer.scanAll();
61     token = lexer.firstToken.prev;
62     nT();
63     prevToken = token;
64   }
65 
66   /// Moves to the next token.
67   void nT()
68   {
69     prevToken = token;
70     do
71       token++;
72     while (token.isWhitespace); // Skip whitespace.
73   }
74 
75   /// Starts the parser and returns the parsed Declarations.
76   CompoundDecl start()
77   {
78     init();
79     auto begin = token;
80     auto decls = new CompoundDecl;
81     if (tokenIs!"module")
82       decls ~= parseModuleDecl();
83     decls.addOptChildren(parseDeclarationDefinitions());
84     set(decls, begin);
85     return decls;
86   }
87 
88   /// Starts the parser and returns the parsed Expression.
89   Expression start2()
90   {
91     init();
92     return parseExpression();
93   }
94 
95   // Members related to the method tryToParse().
96   uint trying; /// Greater than 0 if Parser is in tryToParse().
97   uint errorCount; /// Used to track nr. of errors while being in tryToParse().
98 
99   /// This method executes the delegate parseMethod and when an error occurs
100   /// the state of the lexer and parser is restored.
101   /// Returns: The return value of parseMethod().
102   RetType tryToParse(RetType)(RetType delegate() parseMethod, out bool success)
103   {
104     // Save members.
105     auto oldToken     = this.token;
106     auto oldPrevToken = this.prevToken;
107     auto oldCount     = this.errorCount;
108 
109     ++trying;
110     auto result = parseMethod();
111     --trying;
112     // Check if an error occurred.
113     if (errorCount != oldCount)
114     { // Restore members.
115       token       = oldToken;
116       prevToken   = oldPrevToken;
117       errorCount  = oldCount;
118     }
119     else
120       success = true;
121     return result;
122   }
123 
124   /// Causes the current call to tryToParse() to fail.
125   void fail_tryToParse()
126   {
127     assert(trying);
128     errorCount++;
129   }
130 
131   /// Backtracks the Parser to the given token(s).
132   void backtrackTo(Token* newtok, Token* newprev = null)
133   {
134     this.token = newtok;
135     this.prevToken = newprev ? newprev : newtok.prevNWS();
136   }
137 
138   /// Sets the begin and end tokens of a syntax tree node.
139   Class set(Class)(Class node, Token* begin)
140   {
141     assert(node !is null);
142     node.setTokens(begin, this.prevToken);
143     return node;
144   }
145 
146   /// Sets the begin and end tokens of a syntax tree node.
147   Class set(Class)(Class node, Token* begin, Token* end)
148   {
149     assert(node !is null);
150     node.setTokens(begin, end);
151     return node;
152   }
153 
154   /// Returns true if set() has been called on a node.
155   static bool isNodeSet(const Node node)
156   {
157     assert(node !is null);
158     return node.begin !is null && node.end !is null;
159   }
160 
161   /// Returns true if the current token is of kind T!str.
162   bool tokenIs(string str)()
163   {
164     return token.kind == T!str;
165   }
166 
167   /// Returns true if the next token is of kind T!str.
168   bool nextIs(string str)()
169   {
170     return peekNext() == T!str;
171   }
172 
173   /// Returns the token kind of the next token.
174   TOK peekNext()
175   {
176     Token* next = token;
177     do
178       lexer.peek(next);
179     while (next.isWhitespace); // Skip whitespace
180     return next.kind;
181   }
182 
183   /// Returns the token that comes after t.
184   Token* peekAfter(Token* t)
185   {
186     assert(t !is null);
187     do
188       lexer.peek(t);
189     while (t.isWhitespace); // Skip whitespace
190     return t;
191   }
192 
193   /// Consumes the current token and returns it.
194   Token* consume()()
195   {
196     nT();
197     return prevToken;
198   }
199 
200   /// Consumes the current token if its kind matches T!str and returns true.
201   bool consumed(string str)()
202   {
203     return tokenIs!str ? (nT(), true) : false;
204   }
205 
206   /// Consumes the current token if its kind matches T!str and returns it.
207   Token* consumedToken(string str)()
208   {
209     return tokenIs!str ? (nT(), prevToken) : null;
210   }
211 
212   /// Asserts that the current token is of kind T!str,
213   /// and then moves to the next token.
214   void skip(string str)()
215   {
216     assert(tokenIs!str);
217     consume();
218   }
219 
220   /// Returns true if the token after the closing parenthesis
221   /// matches the searched kind.
222   /// Params:
223   ///   kind = The token kind to test for.
224   bool tokenAfterParenIs(TOK kind)
225   {
226     assert(tokenIs!"(");
227     return skipParens(token, T!")").kind == kind;
228   }
229 
230   /// Returns the token kind behind the closing bracket.
231   TOK tokenAfterBracket(TOK closing)
232   {
233     assert(token.kind.Any!("[", "{"));
234     return skipParens(token, closing).kind;
235   }
236 
237   /// Skips to the token behind the closing parenthesis token.
238   /// Takes nesting into account.
239   /// Params:
240   ///   peek_token = Opening token to start from.
241   ///   closing = Matching closing token kind.
242   /// Returns: The token searched for, or the EOF token.
243   Token* skipParens(Token* peek_token, TOK closing)
244   {
245     assert(peek_token !is null);
246     size_t level = 1;
247     TOK opening = peek_token.kind;
248     while ((peek_token = peekAfter(peek_token)).kind != T!"EOF")
249       if (peek_token.kind == opening)
250         ++level;
251       else
252       if (peek_token.kind == closing && --level == 0) {
253         peek_token = peekAfter(peek_token); // Closing token found.
254         break;
255       }
256     return peek_token;
257   }
258 
259   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
260   |                       Declaration parsing methods                       |
261    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
262 
263   /// $(BNF ModuleDecl := module ModuleType? Identifier ("." Identifier)* ";"
264   ////ModuleType := "(" safe | system ")")
265   Declaration parseModuleDecl()
266   {
267     auto begin = token;
268     skip!"module";
269     ModuleFQN moduleFQN;
270     Token* typeId;
271     version(D2)
272     {
273     if (consumed!"(")
274     {
275       typeId = requireIdentifier(MID.ExpectedModuleType);
276       if (typeId && !typeId.ident.In(Ident.safe, Ident.system))
277         error(typeId, MID.ExpectedModuleType);
278       require2!")";
279     }
280     } // version(D2)
281     do
282       moduleFQN ~= requireIdentifier(MID.ExpectedModuleIdentifier);
283     while (consumed!".");
284     require2!";";
285     return set(new ModuleDecl(typeId, moduleFQN), begin);
286   }
287 
288   /// Parses DeclarationDefinitions until the end of file is hit.
289   /// $(BNF DeclDefs := DeclDef*)
290   Declaration[] parseDeclarationDefinitions()
291   {
292     Declaration[] decls;
293     while (!tokenIs!"EOF")
294       decls ~= parseDeclarationDefinition();
295     return decls;
296   }
297 
298   /// Parse the body of a template, class, interface, struct or union.
299   /// $(BNF DeclDefsBlock := "{" DeclDefs? "}")
300   CompoundDecl parseDeclarationDefinitionsBody()
301   {
302     // Save attributes.
303     auto linkageType  = this.linkageType;
304     auto protection   = this.protection;
305     auto storageClass = this.storageClass;
306     // Clear attributes.
307     this.linkageType  = LinkageType.None;
308     this.protection   = Protection.None;
309     this.storageClass = StorageClass.None;
310 
311     // Parse body.
312     auto decls = new CompoundDecl;
313     auto brace = requireOpening!"{";
314     while (!token.kind.Any!("}", "EOF"))
315       decls ~= parseDeclarationDefinition();
316     requireClosing!"}"(brace);
317     set(decls, brace);
318 
319     // Restore original values.
320     this.linkageType  = linkageType;
321     this.protection   = protection;
322     this.storageClass = storageClass;
323 
324     return decls;
325   }
326 
327   /// Parses a DeclarationDefinition.
328   ///
329   /// $(BNF DeclDef := Attributes | AliasThisDecl | AliasDecl | TypedefDecl |
330   ////  StaticCtorDecl | StaticDtorDecl | StaticIfDecl | StaticAssertDecl |
331   ////  ImportDecl | EnumDecl | ClassDecl | InterfaceDecl | StructDecl |
332   ////  UnionDecl | ConstructorDecl | DestructorDecl | InvariantDecl |
333   ////  UnittestDecl | DebugDecl | VersionDecl | TemplateDecl | NewDecl |
334   ////  DeleteDecl | MixinDecl | EmptyDecl | VariablesOrFunction
335   ////TypedefDecl := typedef VariablesDecl)
336   Declaration parseDeclarationDefinition()
337   out(decl)
338   { assert(isNodeSet(decl)); }
339   body
340   {
341     auto begin = token;
342     Declaration decl;
343     switch (token.kind)
344     {
345     version(D2)
346     { // T!"shared", T!"immutable", T!"inout"
347     case T!"__gshared", T!"ref", T!"pure", T!"nothrow", T!"@":
348       goto case;
349     }
350     case T!"align", T!"pragma",
351          // Protection attributes
352          T!"export", T!"private", T!"package", T!"protected", T!"public",
353          // Storage classes
354          //T!"static", T!"const",
355          T!"extern", T!"deprecated", T!"override", T!"abstract",
356          T!"synchronized", T!"auto", T!"scope", T!"final":
357     case_parseAttributes:
358       return parseAttributes();
359     case T!"alias":
360       decl = parseAliasDecl();
361       break;
362     case T!"typedef":
363       nT();
364       auto td = new TypedefDecl(parseAttributes(&decl));
365       td.vardecl = decl;
366       if (!decl.Is!(VariablesDecl))
367         error(decl.begin, MID.TypedefExpectsVariable, decl.toText());
368       decl = td;
369       break;
370     case T!"static":
371       switch (peekNext())
372       {
373       case T!"import": goto case_Import;
374       case T!"this":   decl = parseStaticCtorDecl();   break;
375       case T!"~":      decl = parseStaticDtorDecl();   break;
376       case T!"if":     decl = parseStaticIfDecl();     break;
377       case T!"assert": decl = parseStaticAssertDecl(); break;
378       default: goto case_parseAttributes;
379       }
380       break;
381     case T!"import":
382     case_Import:
383       auto importDecl = parseImportDecl();
384       imports ~= importDecl;
385       // Handle specially. StorageClass mustn't be set.
386       importDecl.setProtection(this.protection);
387       return set(importDecl, begin);
388     case T!"enum":
389       version(D2)
390       if (isEnumManifest())
391         goto case_parseAttributes;
392       decl = parseEnumDecl();
393       break;
394     case T!"class":
395       decl = parseClassDecl();
396       break;
397     case T!"interface":
398       decl = parseInterfaceDecl();
399       break;
400     case T!"struct", T!"union":
401       decl = parseStructOrUnionDecl();
402       break;
403     case T!"this":
404       if (nextIs!"(")
405         decl = parseConstructorDecl();
406       else
407         goto case_Declaration;
408       break;
409     case T!"~":
410       decl = parseDestructorDecl();
411       break;
412     version(D2)
413     {
414     case T!"const", T!"immutable", T!"inout", T!"shared":
415       if (nextIs!"(")
416         goto case_Declaration;
417       goto case_parseAttributes;
418     } // version(D2)
419     else
420     { // D1
421     case T!"const":
422       goto case_parseAttributes;
423     }
424     case T!"invariant":
425       decl = parseInvariantDecl(); // invariant "(" ")"
426       break;
427     case T!"unittest":
428       decl = parseUnittestDecl();
429       break;
430     case T!"debug":
431       decl = parseDebugDecl();
432       break;
433     case T!"version":
434       decl = parseVersionDecl();
435       break;
436     case T!"template":
437       decl = parseTemplateDecl();
438       break;
439     case T!"new":
440       decl = parseNewDecl();
441       break;
442     case T!"delete":
443       decl = parseDeleteDecl();
444       break;
445     case T!"mixin":
446       decl = parseMixin!(MixinDecl, Declaration)();
447       break;
448     case T!";":
449       nT();
450       decl = new EmptyDecl();
451       break;
452     // Declaration
453     version(D2)
454     {
455     case T!"super"/*, T!"this"*/:
456       goto case_Declaration;
457     }
458     case T!"Identifier", T!".", T!"typeof":
459     case_Declaration:
460       return parseVariablesOrFunction(this.storageClass, this.protection,
461                                       this.linkageType);
462     default:
463       if (token.isIntegralType)
464         goto case_Declaration;
465       else if (tokenIs!"module")
466       {
467         decl = parseModuleDecl();
468         error(begin, MID.ModuleDeclarationNotFirst);
469         return decl;
470       }
471 
472       decl = new IllegalDecl();
473       // Skip to next valid token.
474       do
475         nT();
476       while (!token.isDeclDefStart() && !token.kind.Any!("}", "EOF"));
477       auto text = begin.textSpan(this.prevToken);
478       error(begin, MID.IllegalDeclaration, text);
479     }
480     decl.setProtection(this.protection);
481     decl.setStorageClass(this.storageClass);
482     assert(!isNodeSet(decl));
483     set(decl, begin);
484     return decl;
485   }
486 
487   /// Parses a DeclarationsBlock.
488   /// $(BNF DeclsBlock := ":" DeclDefs | "{" DeclDefs? "}" | DeclDef)
489   Declaration parseDeclarationsBlock()
490   {
491     Declaration d;
492     switch (token.kind)
493     {
494     case T!"{":
495       auto brace = consume();
496       auto decls = new CompoundDecl;
497       while (!token.kind.Any!("}", "EOF"))
498         decls ~= parseDeclarationDefinition();
499       requireClosing!"}"(brace);
500       d = set(decls, brace);
501       break;
502     case T!":":
503       auto colon = consume();
504       auto begin2 = token;
505       auto decls = new CompoundDecl;
506       while (!token.kind.Any!("}", "EOF"))
507         decls ~= parseDeclarationDefinition();
508       set(decls, begin2);
509       d = set(new ColonBlockDecl(decls), colon);
510       break;
511     case T!";":
512       error(MID.ExpectedNonEmptyDeclaration, token);
513       goto default;
514     default:
515       d = parseDeclarationDefinition();
516     }
517     assert(isNodeSet(d));
518     return d;
519   }
520 
521   /// $(BNF
522   ////AliasDecl := alias Attributes
523   ////AliasThisDecl := alias Identifier this ";"
524   ////AliasesDecl := alias AliasName "=" Type ("," AliasName "=" Type)* ";"
525   ////AliasName := this | Identifier)
526   Declaration parseAliasDecl()
527   {
528     skip!"alias";
529     version (D2)
530     {
531     if (tokenIs!"Identifier" && nextIs!"this")
532     {
533       auto ident = consume();
534       skip!"this";
535       require2!";";
536       return new AliasThisDecl(ident);
537     }
538     else
539     if (token.kind.Any!("this", "Identifier") && nextIs!"=")
540     {
541       Token*[] idents;
542       TypeNode[] types;
543       goto LenterLoop;
544 
545       while (consumed!",")
546       {
547         if (!token.kind.Any!("this", "Identifier"))
548           error(token, MID.ExpectedAliasName, token.text);
549       LenterLoop:
550         idents ~= token;
551         nT();
552         require2!"=";
553         types ~= parseType();
554       }
555 
556       require2!";";
557       return new AliasesDecl(idents, types);
558     }
559     } // version(D2)
560 
561     Declaration decl;
562     auto ad = new AliasDecl(parseAttributes(&decl));
563     ad.vardecl = decl;
564     if (auto var = decl.Is!(VariablesDecl))
565     {
566       foreach (init; var.inits)
567         if (init)
568          error(init.begin.prevNWS(), MID.AliasHasInitializer);
569     }
570     else
571       error(decl.begin, MID.AliasExpectsVariable, decl.toText());
572     return ad;
573   }
574 
575   /// Parses either a VariablesDecl or a FunctionDecl.
576   ///
577   /// $(BNF
578   ////VariablesOrFunctionDecl :=
579   ////  AutoDecl | VariablesDecl | FunctionDecl
580   ////AutoDecl      := AutoVariables | AutoFunction
581   ////AutoVariables := Name "=" Initializer MoreVariables* ";"
582   ////AutoFunction  := Name TemplateParameterList? ParameterList FunctionBody
583   ////VariablesDecl :=
584   ////  BasicTypes Name DeclaratorSuffix? ("=" Initializer)? MoreVariables* ";"
585   ////MoreVariables := "," Name ("=" Initializer)?
586   ////FunctionDecl  :=
587   ////  BasicTypes Name TemplateParameterList? ParameterList FunctionBody
588   ////Name          := Identifier)
589   /// Params:
590   ///   stcs = Previously parsed storage classes.
591   ///   protection = Previously parsed protection attribute.
592   ///   linkType = Previously parsed linkage type.
593   ///   testAutoDeclaration = Whether to check for an AutoDecl.
594   Declaration parseVariablesOrFunction(
595     StorageClass stcs = StorageClass.None,
596     Protection protection = Protection.None,
597     LinkageType linkType = LinkageType.None,
598     bool testAutoDeclaration = false)
599   {
600     auto begin = token;
601     Type type; // Variable or function type.
602     Token* name; // Name of the variable or the function.
603 
604     Parameters params; // Function parameters.
605     TemplateParameters tparams; // Function template parameters.
606     Expression constraint; // Function template constraint.
607 
608     // Check for AutoDecl.
609     if (testAutoDeclaration && tokenIs!"Identifier")
610     {
611       auto next_kind = peekNext();
612       if (next_kind == T!"=")
613       { // AutoVariables
614         name = consume();
615         goto LparseVariables;
616       }
617       else version(D2) if (next_kind == T!"(")
618       { // Check for AutoFunction.
619         auto peek_token = peekAfter(token); // Skip the Identifier.
620         next_kind = skipParens(peek_token, T!")").kind; // Token after "("...")"
621         if (next_kind == T!"(")
622         { // TemplateParameterList ParameterList
623           name = consume();
624           assert(tokenIs!"(");
625           goto LparseTPList; // Continue parsing templatized AutoFunction.
626         }
627         else
628         if (next_kind.Any!("{", FunctionPostfix, "in", "out", "body"))
629         { // ParameterList ("{" | FunctionPostfix | in | out | body)
630           name = consume();
631           assert(tokenIs!"(");
632           goto LparseBeforeParams; // Continue parsing AutoFunction.
633         }
634       } // version(D2)
635     }
636 
637     // VariableType or ReturnType
638     type = parseBasicTypes();
639 
640     if (nextIs!"(")
641     { // ReturnType FunctionName "(" ParameterList ")" FunctionBody
642       name = requireIdentifier(MID.ExpectedFunctionName);
643       if (!tokenIs!"(")
644         nT(); // Skip non-identifier token.
645 
646     LparseBeforeTParams:
647       assert(tokenIs!"(");
648       if (tokenAfterParenIs(T!"("))
649       LparseTPList: // "(" TemplateParameterList ")"
650         tparams = parseTemplateParameterList();
651 
652     LparseBeforeParams: // "(" ParameterList ")"
653       params = parseParameterList();
654 
655     LparseAfterParams:
656       StorageClass postfix_stcs; // const | immutable | @property | ...
657       version(D2)
658       {
659       params.postSTCs = postfix_stcs = parseFunctionPostfix();
660       if (tparams) // if "(" ConstraintExpr ")"
661         constraint = parseOptionalConstraint();
662       } // version(D2)
663 
664       // FunctionBody
665       auto funcBody = parseFunctionBody();
666       auto fd = new FunctionDecl(type, name, params, funcBody, linkType);
667       Declaration decl = fd;
668       if (tparams)
669       {
670         decl =
671           putInsideTemplateDeclaration(begin, name, fd, tparams, constraint);
672         decl.setStorageClass(stcs);
673         decl.setProtection(protection);
674       }
675       fd.setStorageClass(stcs | postfix_stcs); // Combine prefix/postfix stcs.
676       fd.setProtection(protection);
677       return set(decl, begin);
678     }
679     else
680     { // Type VariableName DeclaratorSuffix
681       name = requireIdentifier(MID.ExpectedVariableName);
682       type = parseDeclaratorSuffix(type);
683     }
684 
685   LparseVariables:
686     // It's a variables declaration.
687     Token*[] names = [name]; // One identifier has been parsed already.
688     Expression[] values;
689     goto LenterLoop; // Enter the loop and check for an initializer.
690     while (consumed!",")
691     {
692       names ~= requireIdentifier(MID.ExpectedVariableName);
693     LenterLoop:
694       values ~= consumed!"=" ? parseInitializer() : null;
695     }
696     require2!";";
697     auto d = new VariablesDecl(type, names, values, linkType);
698     d.setStorageClass(stcs);
699     d.setProtection(protection);
700     return set(d, begin);
701   }
702 
703   /// Parses a variable initializer.
704   /// $(BNF Initializer        := VoidInitializer | NonVoidInitializer
705   ////VoidInitializer    := void
706   ////NonVoidInitializer :=
707   ////  ArrayInitializer | StructInitializer | AssignExpr
708   ////ArrayInitializer   := "[" ArrayInitElements? "]"
709   ////ArrayInitElements  := ArrayInitElement ("," ArrayInitElement)* ","?
710   ////ArrayInitElement   := (AssignExpr ":")? NonVoidInitializer
711   ////StructInitializer  := "{" StructInitElements? "}"
712   ////StructInitElements := StructInitElement ("," StructInitElement)* ","?
713   ////StructInitElement  := (MemberName ":")? NonVoidInitializer
714   ////MemberName         := Identifier)
715   Expression parseInitializer()
716   {
717     if (tokenIs!"void" && peekNext().Any!(",", ";"))
718       return set(new VoidInitExpr(), consume());
719     return parseNonVoidInitializer();
720   }
721 
722   /// Parses a NonVoidInitializer.
723   /// $(BNF NonVoidInitializer :=
724   ////  ArrayInitializer | StructInitializer | AssignExpr)
725   Expression parseNonVoidInitializer()
726   {
727     auto begin = token;
728     Expression init;
729     switch (token.kind)
730     {
731     case T!"[":
732       if (!tokenAfterBracket(T!"]").Any!(",", "]", "}", ";"))
733         goto default; // Parse as an AssignExpr.
734       // ArrayInitializer := "[" ArrayInitElements? "]"
735       Expression[] keys, values;
736 
737       skip!"[";
738       while (!tokenIs!"]")
739       {
740         Expression key;
741         auto value = parseNonVoidInitializer();
742         if (consumed!":")
743           (key = value), // Switch roles.
744           assert(!(key.Is!(ArrayInitExpr) || key.Is!(StructInitExpr))),
745           value = parseNonVoidInitializer(); // Parse actual value.
746         keys ~= key;
747         values ~= value;
748         if (!consumed!",")
749           break;
750       }
751       requireClosing!"]"(begin);
752       init = new ArrayInitExpr(keys, values);
753       break;
754     case T!"{":
755       if (!tokenAfterBracket(T!"}").Any!(",", "]", "}", ";"))
756         goto default; // Parse as an AssignExpr.
757       // StructInitializer := "{" StructInitElements? "}"
758       Token*[] idents;
759       Expression[] values;
760 
761       skip!"{";
762       while (!tokenIs!"}")
763       { // Peek for colon to see if this is a member identifier.
764         Token* ident;
765         if (tokenIs!"Identifier" && nextIs!":")
766           (ident = token),
767           skip!"Identifier", skip!":";
768         idents ~= ident;
769         values ~= parseNonVoidInitializer();
770         if (!consumed!",")
771           break;
772       }
773       requireClosing!"}"(begin);
774       init = new StructInitExpr(idents, values);
775       break;
776     default:
777       return parseAssignExpr();
778     }
779     set(init, begin);
780     return init;
781   }
782 
783   /// Parses the body of a function.
784   FuncBodyStmt parseFunctionBody()
785   {
786     auto begin = token;
787     Statement funcBody, inBody, outBody;
788     Token* outIdent;
789 
790     // Save the attributes.
791     auto saved_stcs = this.storageClass;
792     auto saved_prot = this.protection;
793     auto saved_link = this.linkageType;
794     // Clear attributes.
795     this.storageClass = StorageClass.None;
796     this.protection   = Protection.None;
797     this.linkageType  = LinkageType.None;
798 
799   Loop:
800     while (1)
801       switch (token.kind)
802       {
803       case T!"{":
804         funcBody = parseStatements();
805         break Loop;
806       case T!";":
807         nT();
808         break Loop;
809       case T!"in":
810         if (inBody)
811           error(MID.InContract);
812         nT();
813         inBody = parseStatements();
814         break;
815       case T!"out":
816         if (outBody)
817           error(MID.OutContract);
818         nT();
819         if (consumed!"(")
820           (outIdent = requireIdentifier(MID.ExpectedAnIdentifier)),
821           require2!")";
822         outBody = parseStatements();
823         break;
824       case T!"body":
825         // if (!outBody || !inBody) // TODO:
826         //   error2(MID.ExpectedInOutBody, token);
827         nT();
828         goto case T!"{";
829       default:
830         version (D2)
831         {
832         if (inBody || outBody)
833           // In D2, having in or out contracts without a body is valid.
834           break Loop;
835         } // version (D2)
836         error2(MID.ExpectedFunctionBody, token);
837         break Loop;
838       }
839 
840     // Restore the original attributes.
841     this.storageClass = saved_stcs;
842     this.protection = saved_prot;
843     this.linkageType = saved_link;
844 
845     auto func = new FuncBodyStmt(funcBody, inBody, outBody, outIdent);
846     return set(func, begin);
847   }
848 
849   /// $(BNF FunctionPostfix :=
850   ////  (const|immutable|inout|nothrow|shared|pure| "@" Identifier)*)
851   StorageClass parseFunctionPostfix()
852   {
853     version(D2)
854     {
855     StorageClass stcs, stc;
856     while (1)
857     {
858       switch (token.kind)
859       {
860       case T!"const":     stc = StorageClass.Const;     break;
861       case T!"immutable": stc = StorageClass.Immutable; break;
862       case T!"inout":     stc = StorageClass.Inout;     break;
863       case T!"nothrow":   stc = StorageClass.Nothrow;   break;
864       case T!"shared":    stc = StorageClass.Shared;    break;
865       case T!"pure":      stc = StorageClass.Pure;      break;
866       case T!"@":         stc = parseAtAttribute();     break;
867       default:
868         return stcs;
869       }
870       if (stcs & stc)
871         error2(MID.RedundantStorageClass, token);
872       stcs |= stc;
873       nT();
874     }
875     return stcs;
876     } // version(D2)
877     assert(0);
878   }
879 
880   /// A tuple of all the possible postfix tokens.
881   alias FunctionPostfix = Tuple!("const", "immutable", "inout", "nothrow",
882     "shared", "pure", "@");
883 
884   /// $(BNF ExternLinkageType := extern "(" LinkageType ")"
885   ///LinkageType := "C" | "C" "++" | "D" | "Windows" | "Pascal" | "System")
886   LinkageType parseExternLinkageType()
887   {
888     LinkageType linkageType;
889 
890     skip!"extern", skip!"(";
891 
892     if (consumed!")")
893     { // extern "(" ")"
894       error(MID.MissingLinkageType);
895       return linkageType;
896     }
897 
898     if (auto idtok = requireIdentifier(MID.ExpectedLinkageIdentifier))
899       switch (idtok.ident.idKind)
900       {
901       case IDK.C:       linkageType = consumed!"++" ?
902                                       LinkageType.Cpp :
903                                       LinkageType.C;       break;
904       case IDK.D:       linkageType = LinkageType.D;       break;
905       case IDK.Windows: linkageType = LinkageType.Windows; break;
906       case IDK.Pascal:  linkageType = LinkageType.Pascal;  break;
907       case IDK.System:  linkageType = LinkageType.System;  break;
908       default:
909         error2(MID.UnrecognizedLinkageType, idtok);
910       }
911     require2!")";
912     return linkageType;
913   }
914 
915   /// Reports an error if a linkage type has already been parsed.
916   void checkLinkageType(ref LinkageType prev_lt, LinkageType lt, Token* begin)
917   {
918     if (prev_lt == LinkageType.None)
919       prev_lt = lt;
920     else
921       error(begin, MID.RedundantLinkageType, begin.textSpan(prevToken));
922   }
923 
924   /// Returns a StorageClass when the next token is not a "(".
925   StorageClass getSTC()
926   {
927     if (nextIs!"(")
928       return StorageClass.None;
929     auto k = token.kind;
930     return k == T!"const" ? StorageClass.Const :
931        k == T!"immutable" ? StorageClass.Immutable :
932            k == T!"inout" ? StorageClass.Inout :
933                             StorageClass.Shared;
934   }
935 
936   /// Parses one or more attributes and a Declaration at the end.
937   ///
938   /// $(BNF
939   ////Attributes :=
940   ////  (StorageAttribute | AlignAttribute | PragmaAttribute | ProtAttribute)*
941   ////  DeclsBlock
942   ////StorageAttribute := extern | ExternLinkageType | override | abstract |
943   ////  auto | synchronized | static | final | const | immutable | enum | scope
944   ////AlignAttribute   := align ("(" Integer ")")?
945   ////PragmaAttribute  := pragma "(" Identifier ("," ExpressionList)? ")"
946   ////ProtAttribute    := private | public | package | protected | export)
947   /// Params:
948   ///   pDecl = Set to the non-attribute Declaration if non-null.
949   Declaration parseAttributes(Declaration* pDecl = null)
950   {
951     StorageClass stcs, // Set to StorageClasses parsed in the loop.
952       stc; // Current StorageClass in the loop.
953     LinkageType linkageType; // Currently parsed LinkageType.
954     Protection protection, // Set to the Protection parsed in the loop.
955       prot; // Current Protection in the loop.
956     uint alignSize; // Set to the AlignSize parsed in the loop.
957     bool testAutoDecl; // Test for: auto Identifier "=" Expression
958 
959     // Allocate dummy declarations.
960     scope emptyDecl = new EmptyDecl();
961     // Function as the head of the attribute chain.
962     scope AttributeDecl headAttr = new StorageClassDecl(STC.None, emptyDecl);
963 
964     AttributeDecl currentAttr = headAttr, prevAttr = headAttr;
965 
966     // Parse the attributes.
967   Loop:
968     while (1)
969     {
970       auto begin = token;
971       switch (token.kind)
972       {
973       case T!"extern":
974         if (nextIs!"(")
975         {
976           checkLinkageType(linkageType, parseExternLinkageType(), begin);
977           currentAttr = new LinkageDecl(linkageType, emptyDecl);
978           testAutoDecl = false;
979           break;
980         }
981                              stc = StorageClass.Extern;       goto Lcommon;
982       case T!"override":     stc = StorageClass.Override;     goto Lcommon;
983       case T!"deprecated":   stc = StorageClass.Deprecated;   goto Lcommon;
984       case T!"abstract":     stc = StorageClass.Abstract;     goto Lcommon;
985       case T!"synchronized": stc = StorageClass.Synchronized; goto Lcommon;
986       case T!"static":
987         // Avoid parsing static import, static this etc.
988         if (peekNext().Any!("import", "this", "~", "if", "assert"))
989           break Loop;
990                              stc = StorageClass.Static;       goto Lcommon;
991       case T!"final":        stc = StorageClass.Final;        goto Lcommon;
992       version(D2)
993       {
994       case T!"const", T!"immutable", T!"inout", T!"shared":
995         if ((stc = getSTC()) == 0)
996           break Loop;
997         goto Lcommon;
998       case T!"enum":
999         if (!isEnumManifest())
1000           break Loop;
1001                              stc = StorageClass.Manifest;     goto Lcommon;
1002       case T!"ref":          stc = StorageClass.Ref;          goto Lcommon;
1003       case T!"pure":         stc = StorageClass.Pure;         goto Lcommon;
1004       case T!"nothrow":      stc = StorageClass.Nothrow;      goto Lcommon;
1005       case T!"__gshared":    stc = StorageClass.Gshared;      goto Lcommon;
1006       case T!"@":            stc = parseAtAttribute();        goto Lcommon;
1007       } // version(D2)
1008       else
1009       { // D1
1010       case T!"const":        stc = StorageClass.Const;        goto Lcommon;
1011       }
1012       case T!"auto":         stc = StorageClass.Auto;         goto Lcommon;
1013       case T!"scope":        stc = StorageClass.Scope;        goto Lcommon;
1014       Lcommon:
1015         if (stcs & stc) // Issue error if redundant.
1016           error2(MID.RedundantStorageClass, token);
1017         stcs |= stc;
1018         nT(); // Skip the storage class token.
1019         currentAttr = new StorageClassDecl(stc, emptyDecl);
1020         testAutoDecl = true;
1021         break;
1022       // Protection attributes:
1023       case T!"private":   prot = Protection.Private;   goto Lprot;
1024       case T!"package":   prot = Protection.Package;   goto Lprot;
1025       case T!"protected": prot = Protection.Protected; goto Lprot;
1026       case T!"public":    prot = Protection.Public;    goto Lprot;
1027       case T!"export":    prot = Protection.Export;    goto Lprot;
1028       Lprot:
1029         if (protection != Protection.None)
1030           error2(MID.RedundantProtection, token);
1031         protection = prot;
1032         nT();
1033         currentAttr = new ProtectionDecl(prot, emptyDecl);
1034         testAutoDecl = false;
1035         break;
1036       case T!"align":
1037         // align ("(" Integer ")")?
1038         Token* sizetok;
1039         alignSize = parseAlignAttribute(sizetok);
1040         // TODO: error msg for redundant align attributes.
1041         currentAttr = new AlignDecl(sizetok, emptyDecl);
1042         testAutoDecl = false;
1043         break;
1044       case T!"pragma":
1045         // Pragma := pragma "(" Identifier ("," ExpressionList)? ")"
1046         nT();
1047         auto paren = requireOpening!"(";
1048         auto ident = requireIdentifier(MID.ExpectedPragmaIdentifier);
1049         auto args = consumed!"," ? parseExpressionList() : null;
1050         requireClosing!")"(paren);
1051         currentAttr = new PragmaDecl(ident, args, emptyDecl);
1052         testAutoDecl = false;
1053         break;
1054       default:
1055         break Loop;
1056       }
1057       // NB: the 'end' member is not set to the end token of
1058       //   the declaration, which is parsed below.
1059       //   If necessary, this could be fixed by traversing
1060       //   the attributes at the end and calling set() there.
1061       set(currentAttr, begin);
1062       // Correct the child node and continue parsing attributes.
1063       prevAttr.setDecls(currentAttr);
1064       prevAttr = currentAttr; // Current becomes previous.
1065     }
1066 
1067     // Parse the declaration.
1068     Declaration decl;
1069     if (!linkageType)
1070       linkageType = this.linkageType;
1071     // Save attributes.
1072     auto outer_storageClass = this.storageClass;
1073     auto outer_linkageType = this.linkageType;
1074     auto outer_protection = this.protection;
1075     auto outer_alignSize = this.alignSize;
1076     // Set parsed values.
1077     stcs |= outer_storageClass; // Combine with outer stcs.
1078     this.storageClass = stcs;
1079     this.linkageType = linkageType;
1080     this.protection = protection;
1081     this.alignSize = alignSize;
1082     if (testAutoDecl && tokenIs!"Identifier") // "auto" Identifier "="
1083       decl = // This could be a normal Declaration or an AutoDeclaration
1084         parseVariablesOrFunction(stcs, protection, linkageType, true);
1085     else
1086     {
1087       if (prevAttr.Is!PragmaDecl && tokenIs!";")
1088         decl = parseDeclarationDefinition(); // Allow semicolon after pragma().
1089       else // Parse a block.
1090         decl = parseDeclarationsBlock();
1091     }
1092     // Restore outer values.
1093     this.storageClass = outer_storageClass;
1094     this.linkageType = outer_linkageType;
1095     this.protection = outer_protection;
1096     this.alignSize = outer_alignSize;
1097     if (pDecl)
1098       *pDecl = decl;
1099 
1100     assert(decl !is null && isNodeSet(decl));
1101     // Attach the declaration to the previously parsed attribute.
1102     prevAttr.setDecls(decl);
1103     // Return the first attribute declaration.
1104     return headAttr.decls;
1105   }
1106 
1107   /// $(BNF AlignAttribute := align ("(" Integer ")")?)
1108   uint parseAlignAttribute(out Token* sizetok)
1109   {
1110     skip!"align";
1111     uint size;
1112     if (consumed!"(")
1113     {
1114       if (tokenIs!"Int32")
1115         (sizetok = token), (size = token.int_), skip!"Int32";
1116       else
1117         expected!"Int32";
1118       require2!")";
1119     }
1120     return size;
1121   }
1122 
1123   /// $(BNF AtAttribute := "@" Identifier)
1124   StorageClass parseAtAttribute()
1125   {
1126     skip!"@";
1127     StorageClass stc;
1128     if (tokenIs!"Identifier")
1129       switch (token.ident.idKind)
1130       {
1131       case IDK.disable:  stc = StorageClass.Disable;  break;
1132       case IDK.property: stc = StorageClass.Property; break;
1133       case IDK.safe:     stc = StorageClass.Safe;     break;
1134       case IDK.system:   stc = StorageClass.System;   break;
1135       case IDK.trusted:  stc = StorageClass.Trusted;  break;
1136       default:
1137         error2(MID.UnrecognizedAttribute, token);
1138       }
1139     else
1140       error2(MID.ExpectedAttributeId, token);
1141     // Return without skipping the identifier.
1142     return stc;
1143   }
1144 
1145   /// $(BNF ImportDecl := static? import
1146   ////              ImportModule ("," ImportModule)*
1147   ////              (":" ImportBind ("," ImportBind)*)?
1148   ////              ";"
1149   ////ImportModule := (AliasName "=")? ModuleName
1150   ////ImportBind   := (AliasName "=")? BindName
1151   ////ModuleName   := Identifier ("." Identifier)*
1152   ////AliasName    := Identifier
1153   ////BindName     := Identifier)
1154   ImportDecl parseImportDecl()
1155   {
1156     bool isStatic = consumed!"static";
1157     skip!"import";
1158 
1159     ModuleFQN[] moduleFQNs;
1160     Token*[] moduleAliases;
1161     Token*[] bindNames;
1162     Token*[] bindAliases;
1163 
1164     do
1165     {
1166       ModuleFQN moduleFQN;
1167       Token* moduleAlias;
1168       // AliasName = ModuleName
1169       if (nextIs!"=")
1170       {
1171         moduleAlias = requireIdentifier(MID.ExpectedAliasModuleName);
1172         skip!"=";
1173       }
1174       // Identifier ("." Identifier)*
1175       do
1176         moduleFQN ~= requireIdentifier(MID.ExpectedModuleIdentifier);
1177       while (consumed!".");
1178       // Push identifiers.
1179       moduleFQNs ~= moduleFQN;
1180       moduleAliases ~= moduleAlias;
1181     } while (consumed!",");
1182 
1183     if (consumed!":")
1184     { // ImportBind := (BindAlias "=")? BindName
1185       // ":" ImportBind ("," ImportBind)*
1186       do
1187       {
1188         Token* bindAlias;
1189         // BindAlias = BindName
1190         if (nextIs!"=")
1191         {
1192           bindAlias = requireIdentifier(MID.ExpectedAliasImportName);
1193           skip!"=";
1194         }
1195         // Push identifiers.
1196         bindNames ~= requireIdentifier(MID.ExpectedImportName);
1197         bindAliases ~= bindAlias;
1198       } while (consumed!",");
1199     }
1200     require2!";";
1201 
1202     return new ImportDecl(moduleFQNs, moduleAliases, bindNames,
1203                                  bindAliases, isStatic);
1204   }
1205 
1206   /// Returns true if this is an enum manifest or
1207   /// false if it's a normal enum declaration.
1208   bool isEnumManifest()
1209   {
1210     version(D2)
1211     {
1212     assert(tokenIs!"enum");
1213     auto next = peekAfter(token);
1214     auto kind = next.kind;
1215     if (kind.Any!(":", "{"))
1216       return false; // Anonymous enum.
1217     else
1218     if (kind == T!"Identifier" && peekAfter(next).kind.Any!(":", "{", ";"))
1219       return false; // Named enum.
1220     return true; // Manifest enum.
1221     }
1222     assert(0);
1223   }
1224 
1225   /// $(BNF
1226   ////EnumDecl :=
1227   ////  enum Name? (":" BasicType)? EnumBody |
1228   ////  enum Name ";"
1229   ////EnumBody     := "{" EnumMembers "}"
1230   ////EnumMembers  := EnumMember ("," EnumMember)* ","?
1231   ////EnumMembers2 := Type? EnumMember ("," Type? EnumMember)* ","? # D2.0
1232   ////EnumMember   := Name ("=" AssignExpr)?)
1233   Declaration parseEnumDecl()
1234   {
1235     skip!"enum";
1236 
1237     EnumMemberDecl[] members;
1238 
1239     auto enumName = optionalIdentifier();
1240     auto baseType = consumed!":" ? parseBasicType() : null;
1241 
1242     if (!enumName || !consumed!";")
1243       if (auto brace = consumedToken!"{")
1244       {
1245         while (!tokenIs!"}")
1246         {
1247           auto begin = token;
1248           Type type; // Optional member type.
1249 
1250           version(D2)
1251           if (!peekNext().Any!("=", ",", "}"))
1252             type = parseType();
1253 
1254           auto name = requireIdentifier(MID.ExpectedEnumMember);
1255           // "=" AssignExpr
1256           auto value = consumed!"=" ? parseAssignExpr() : null;
1257           auto member = new EnumMemberDecl(type, name, value);
1258           members ~= set(member, begin);
1259 
1260           if (!consumed!",")
1261             break;
1262         }
1263         requireClosing!"}"(brace);
1264       }
1265       else
1266         error2(MID.ExpectedEnumBody, token);
1267 
1268     return new EnumDecl(enumName, baseType, members);
1269   }
1270 
1271   /// Wraps a declaration inside a template declaration.
1272   /// Params:
1273   ///   begin = Begin token of decl.
1274   ///   name = Name of decl.
1275   ///   decl = The declaration to be wrapped.
1276   ///   tparams = The template parameters.
1277   ///   constraint = The constraint expression.
1278   TemplateDecl putInsideTemplateDeclaration(
1279     Token* begin,
1280     Token* name,
1281     Declaration decl,
1282     TemplateParameters tparams,
1283     Expression constraint)
1284   {
1285     set(decl, begin);
1286     auto cd = new CompoundDecl;
1287     cd ~= decl;
1288     set(cd, begin);
1289     decl.setStorageClass(this.storageClass);
1290     decl.setProtection(this.protection);
1291     return new TemplateDecl(name, tparams, constraint, cd);
1292   }
1293 
1294   /// $(BNF ClassDecl :=
1295   ////  class Name TemplateParameterList? (":" BaseClasses) ClassBody |
1296   ////  class Name ";"
1297   ////ClassBody := DeclDefsBlock)
1298   Declaration parseClassDecl()
1299   {
1300     auto begin = token;
1301     skip!"class";
1302 
1303     TemplateParameters tparams;
1304     Expression constraint;
1305     CompoundDecl decls;
1306 
1307     auto name = requireIdentifier(MID.ExpectedClassName);
1308 
1309     if (tokenIs!"(")
1310     {
1311       tparams = parseTemplateParameterList();
1312       version(D2) constraint = parseOptionalConstraint();
1313     }
1314 
1315     auto bases = consumed!":" ? parseBaseClasses() : null;
1316 
1317     version(D2)
1318     if (bases.length && tokenIs!"if")
1319     {
1320       if (constraint)
1321         error(MID.RedundantConstraint);
1322       constraint = parseOptionalConstraint();
1323     }
1324 
1325     if (bases.length || !consumed!";")
1326       if (tokenIs!"{")
1327         decls = parseDeclarationDefinitionsBody();
1328       else
1329         error2(MID.ExpectedClassBody, token);
1330 
1331     Declaration d = new ClassDecl(name, /+tparams, +/bases, decls);
1332     if (tparams)
1333       d = putInsideTemplateDeclaration(begin, name, d, tparams, constraint);
1334     return d;
1335   }
1336 
1337   /// $(BNF BaseClasses := BaseClass ("," BaseClass)*
1338   ////BaseClass   := Protection? BasicType
1339   ////Protection  := private | public | protected | package)
1340   BaseClassType[] parseBaseClasses()
1341   {
1342     BaseClassType[] bases;
1343     do
1344     {
1345       Protection prot;
1346       switch (token.kind)
1347       {
1348       case T!"Identifier", T!".", T!"typeof": goto LparseBasicType;
1349       case T!"private":   prot = Protection.Private;   break;
1350       case T!"protected": prot = Protection.Protected; break;
1351       case T!"package":   prot = Protection.Package;   break;
1352       case T!"public":    prot = Protection.Public;    break;
1353       default:
1354         error2(MID.ExpectedBaseClasses, token);
1355         return bases;
1356       }
1357       nT(); // Skip protection attribute.
1358     LparseBasicType:
1359       auto begin = token;
1360       auto type = parseBasicType();
1361       bases ~= set(new BaseClassType(prot, type), begin);
1362     } while (consumed!",");
1363     return bases;
1364   }
1365 
1366   /// $(BNF InterfaceDecl :=
1367   ////  interface Name TemplateParameterList? (":" BaseClasses) InterfaceBody |
1368   ////  interface Name ";"
1369   ////InterfaceBody := DeclDefsBlock)
1370   Declaration parseInterfaceDecl()
1371   {
1372     auto begin = token;
1373     skip!"interface";
1374 
1375     TemplateParameters tparams;
1376     Expression constraint;
1377     CompoundDecl decls;
1378 
1379     auto name = requireIdentifier(MID.ExpectedInterfaceName);
1380 
1381     if (tokenIs!"(")
1382     {
1383       tparams = parseTemplateParameterList();
1384       version(D2) constraint = parseOptionalConstraint();
1385     }
1386 
1387     auto bases = consumed!":" ? parseBaseClasses() : null;
1388 
1389     version(D2)
1390     if (bases.length && tokenIs!"if")
1391     {
1392       if (constraint)
1393         error(MID.RedundantConstraint);
1394       constraint = parseOptionalConstraint();
1395     }
1396 
1397     if (bases.length || !consumed!";")
1398       if (tokenIs!"{")
1399         decls = parseDeclarationDefinitionsBody();
1400       else
1401         error2(MID.ExpectedInterfaceBody, token);
1402 
1403     Declaration d = new InterfaceDecl(name, bases, decls);
1404     if (tparams)
1405       d = putInsideTemplateDeclaration(begin, name, d, tparams, constraint);
1406     return d;
1407   }
1408 
1409   /// $(BNF StructDecl :=
1410   ////  struct Name? TemplateParameterList? StructBody |
1411   ////  struct Name ";"
1412   ////StructBody := DeclDefsBlock
1413   ////UnionDecl  :=
1414   ////  union Name? TemplateParameterList? UnionBody |
1415   ////  union Name ";"
1416   ////UnionBody  := DeclDefsBlock)
1417   Declaration parseStructOrUnionDecl()
1418   {
1419     assert(token.kind.Any!("struct", "union"));
1420     auto begin = token;
1421     nT();
1422 
1423     TemplateParameters tparams;
1424     Expression constraint;
1425     CompoundDecl decls;
1426 
1427     auto name = optionalIdentifier();
1428 
1429     if (name && tokenIs!"(")
1430     {
1431       tparams = parseTemplateParameterList();
1432       version(D2) constraint = parseOptionalConstraint();
1433     }
1434 
1435     if (!name || !consumed!";")
1436       if (tokenIs!"{")
1437         decls = parseDeclarationDefinitionsBody();
1438       else
1439         error2(begin.kind == T!"struct" ?
1440                MID.ExpectedStructBody : MID.ExpectedUnionBody, token);
1441 
1442     Declaration d;
1443     if (begin.kind == T!"struct")
1444     {
1445       auto sd = new StructDecl(name, /+tparams, +/decls);
1446       sd.setAlignSize(this.alignSize);
1447       d = sd;
1448     }
1449     else
1450       d = new UnionDecl(name, /+tparams, +/decls);
1451 
1452     if (tparams)
1453       d = putInsideTemplateDeclaration(begin, name, d, tparams, constraint);
1454     return d;
1455   }
1456 
1457   /// $(BNF ConstructorDecl := this ParameterList FunctionBody)
1458   Declaration parseConstructorDecl()
1459   {
1460     version(D2)
1461     {
1462     auto begin = token;
1463     TemplateParameters tparams;
1464     Expression constraint;
1465     skip!"this";
1466     if (tokenIs!"(" && tokenAfterParenIs(T!"("))
1467       tparams = parseTemplateParameterList(); // "(" TemplateParameterList ")"
1468     Parameters parameters;
1469     if (!nextIs!"this")
1470       parameters = parseParameterList(); // "(" ParameterList ")"
1471     else // PostBlit := this "(" this ")"
1472     {
1473       auto paren = requireOpening!"(";
1474       parameters = new Parameters();
1475       auto this_ = consume();
1476       auto thisParam = new Parameter(STC.None, null, null, this_, null);
1477       parameters ~= set(thisParam, this_);
1478       requireClosing!")"(paren);
1479       set(parameters, paren);
1480     }
1481     parameters.postSTCs = parseFunctionPostfix();
1482     // FIXME: |= to storageClass?? Won't this affect other decls?
1483     this.storageClass |= parameters.postSTCs; // Combine with current stcs.
1484     if (tparams) // if "(" ConstraintExpr ")"
1485       constraint = parseOptionalConstraint();
1486     auto funcBody = parseFunctionBody();
1487     Declaration d = new ConstructorDecl(parameters, funcBody);
1488     if (tparams)
1489       d = putInsideTemplateDeclaration(begin, begin, d, tparams, constraint);
1490     return d;
1491     } // version(D2)
1492     else
1493     { // D1
1494     skip!"this";
1495     auto parameters = parseParameterList();
1496     auto funcBody = parseFunctionBody();
1497     return new ConstructorDecl(parameters, funcBody);
1498     }
1499   }
1500 
1501   /// $(BNF DestructorDecl := "~" this "(" ")" FunctionBody)
1502   Declaration parseDestructorDecl()
1503   {
1504     skip!"~";
1505     require2!"this";
1506     require2!"(";
1507     require2!")";
1508     auto funcBody = parseFunctionBody();
1509     return new DestructorDecl(funcBody);
1510   }
1511 
1512   /// $(BNF StaticCtorDecl := static this "(" ")" FunctionBody)
1513   Declaration parseStaticCtorDecl()
1514   {
1515     skip!"static";
1516     skip!"this";
1517     require2!"(";
1518     require2!")";
1519     auto funcBody = parseFunctionBody();
1520     return new StaticCtorDecl(funcBody);
1521   }
1522 
1523   /// $(BNF
1524   ////StaticDtorDecl := static "~" this "(" ")" FunctionBody)
1525   Declaration parseStaticDtorDecl()
1526   {
1527     skip!"static";
1528     skip!"~";
1529     require2!"this";
1530     require2!"(";
1531     require2!")";
1532     auto funcBody = parseFunctionBody();
1533     return new StaticDtorDecl(funcBody);
1534   }
1535 
1536   /// $(BNF InvariantDecl := invariant ("(" ")")? FunctionBody)
1537   Declaration parseInvariantDecl()
1538   {
1539     skip!"invariant";
1540     if (consumed!"(") // Optional "(" ")"
1541       require2!")";
1542     auto funcBody = parseFunctionBody();
1543     return new InvariantDecl(funcBody);
1544   }
1545 
1546   /// $(BNF UnittestDecl := unittest FunctionBody)
1547   Declaration parseUnittestDecl()
1548   {
1549     skip!"unittest";
1550     if (!tokenIs!"{")
1551       error2(MID.ExpectedUnittestBody, token);
1552     auto funcBody = parseFunctionBody();
1553     return new UnittestDecl(funcBody);
1554   }
1555 
1556   /// Parses an identifier or an integer. Reports an error otherwise.
1557   /// $(BNF IdentOrInt := Identifier | Integer)
1558   Token* parseIdentOrInt()
1559   {
1560     if (token.kind.Any!("Identifier", "Int32"))
1561       return consume();
1562     error2(MID.ExpectedIdentOrInt, token);
1563     return null;
1564   }
1565 
1566   /// $(BNF VersionCondition := unittest #*D2.0*# | IdentOrInt)
1567   Token* parseVersionCondition()
1568   {
1569     version(D2)
1570     if (token.kind.Any!("unittest", "assert"))
1571       return consume();
1572     return parseIdentOrInt();
1573   }
1574 
1575   /// $(BNF DebugDecl :=
1576   ////  debug "=" IdentOrInt ";" |
1577   ////  debug DebugCondition? DeclsBlock (else DeclsBlock)?
1578   ////DebugCondition := "(" IdentOrInt ")")
1579   Declaration parseDebugDecl()
1580   {
1581     skip!"debug";
1582     Token* spec, cond;
1583     Declaration decls, elseDecls;
1584     if (consumed!"=")
1585     { // debug "=" (Integer | Identifier) ";"
1586       spec = parseIdentOrInt();
1587       require2!";";
1588     }
1589     else
1590     {
1591       if (auto paren = consumedToken!"(")
1592       { // "(" Condition ")"
1593         cond = parseIdentOrInt();
1594         requireClosing!")"(paren);
1595       }
1596       decls = parseDeclarationsBlock(); // DeclsBlock
1597       if (consumed!"else") // else DeclsBlock
1598         elseDecls = parseDeclarationsBlock();
1599     }
1600     return new DebugDecl(spec, cond, decls, elseDecls);
1601   }
1602 
1603   /// $(BNF VersionDecl :=
1604   ////  version "=" IdentOrInt ";" |
1605   ////  version VCondition DeclsBlock (else DeclsBlock)?
1606   ////VCondition  := "(" VersionCondition ")")
1607   Declaration parseVersionDecl()
1608   {
1609     skip!"version";
1610     Token* spec, cond;
1611     Declaration decls, elseDecls;
1612     if (consumed!"=")
1613     { // version = (Integer | Identifier) ";"
1614       spec = parseIdentOrInt();
1615       require2!";";
1616     }
1617     else
1618     { // "(" Condition ")"
1619       auto paren = requireOpening!"(";
1620       cond = parseVersionCondition();
1621       requireClosing!")"(paren);
1622       decls = parseDeclarationsBlock(); // DeclsBlock
1623       if (consumed!"else") // else DeclsBlock
1624         elseDecls = parseDeclarationsBlock();
1625     }
1626     return new VersionDecl(spec, cond, decls, elseDecls);
1627   }
1628 
1629   /// $(BNF StaticIfDecl :=
1630   ////  static if "(" AssignExpr ")" DeclsBlock (else DeclsBlock)?)
1631   Declaration parseStaticIfDecl()
1632   {
1633     skip!"static";
1634     skip!"if";
1635     auto paren = requireOpening!"(";
1636     auto condition = parseAssignExpr();
1637     requireClosing!")"(paren);
1638     auto ifDecls = parseDeclarationsBlock();
1639     auto elseDecls = consumed!"else" ? parseDeclarationsBlock() : null;
1640     return new StaticIfDecl(condition, ifDecls, elseDecls);
1641   }
1642 
1643   /// $(BNF StaticAssertDecl :=
1644   ////  static assert "(" AssignExpr ("," Message)? ")" ";"
1645   ////Message          := AssignExpr)
1646   Declaration parseStaticAssertDecl()
1647   {
1648     skip!"static";
1649     skip!"assert";
1650     auto paren = requireOpening!"(";
1651     auto condition = parseAssignExpr();
1652     auto message = consumed!"," ? parseAssignExpr() : null;
1653     requireClosing!")"(paren);
1654     require2!";";
1655     return new StaticAssertDecl(condition, message);
1656   }
1657 
1658   /// $(BNF TemplateDecl :=
1659   ////  template Name TemplateParameterList Constraint? DeclDefsBlock)
1660   TemplateDecl parseTemplateDecl()
1661   {
1662     skip!"template";
1663     auto name = requireIdentifier(MID.ExpectedTemplateName);
1664     auto tparams = parseTemplateParameterList();
1665     auto constraint = parseOptionalConstraint();
1666     auto decls = parseDeclarationDefinitionsBody();
1667     return new TemplateDecl(name, tparams, constraint, decls);
1668   }
1669 
1670   /// $(BNF NewDecl := new ParameterList FunctionBody)
1671   Declaration parseNewDecl()
1672   {
1673     skip!"new";
1674     auto parameters = parseParameterList();
1675     auto funcBody = parseFunctionBody();
1676     return new NewDecl(parameters, funcBody);
1677   }
1678 
1679   /// $(BNF DeleteDecl := delete ParameterList FunctionBody)
1680   Declaration parseDeleteDecl()
1681   {
1682     skip!"delete";
1683     auto parameters = parseParameterList();
1684     auto funcBody = parseFunctionBody();
1685     return new DeleteDecl(parameters, funcBody);
1686   }
1687 
1688   /// Parses a MixinDecl or MixinStmt.
1689   /// $(BNF
1690   ////MixinDecl       := (MixinExpr | MixinTemplate | MixinTemplateId) ";"
1691   ////MixinExpr       := mixin "(" AssignExpr ")"
1692   ////MixinTemplate   := mixin TemplateDecl # D2
1693   ////MixinTemplateId := mixin TemplateIdentifier
1694   ////                   ("!" "(" TemplateArguments ")")? MixinIdentifier?)
1695   RetT parseMixin(Class, RetT = Class)()
1696   {
1697     static assert(is(Class == MixinDecl) || is(Class == MixinStmt));
1698     skip!"mixin";
1699 
1700     static if (is(Class == MixinDecl))
1701     {
1702     if (auto paren = consumedToken!"(")
1703     {
1704       auto e = parseAssignExpr();
1705       requireClosing!")"(paren);
1706       require2!";";
1707       return new MixinDecl(e);
1708     }
1709     else version(D2) if (tokenIs!"template")
1710     {
1711       auto d = parseTemplateDecl();
1712       d.isMixin = true;
1713       return d;
1714     } // version(D2)
1715     }
1716 
1717     auto e = parseIdentifiersExpr();
1718     auto mixinIdent = optionalIdentifier();
1719     require2!";";
1720 
1721     return new Class(e, mixinIdent);
1722   }
1723 
1724   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1725   |                        Statement parsing methods                        |
1726    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
1727 
1728   /// $(BNF Statements := "{" Statement* "}")
1729   CompoundStmt parseStatements()
1730   {
1731     auto brace = requireOpening!"{";
1732     auto statements = new CompoundStmt();
1733     while (!token.kind.Any!("}", "EOF"))
1734       statements ~= parseStatement();
1735     requireClosing!"}"(brace);
1736     return set(statements, brace);
1737   }
1738 
1739   /// Parses a Statement.
1740   Statement parseStatement()
1741   {
1742     auto begin = token;
1743     Statement s;
1744     Declaration d;
1745 
1746     if (token.isIntegralType)
1747     {
1748       d = parseVariablesOrFunction();
1749       goto LreturnDeclarationStmt;
1750     }
1751 
1752     switch (token.kind)
1753     {
1754     case T!"align":
1755       Token* sizetok;
1756       uint size = parseAlignAttribute(sizetok);
1757       // Restrict align attribute to structs in parsing phase.
1758       StructDecl structDecl;
1759       if (tokenIs!"struct")
1760       {
1761         auto begin2 = token;
1762         structDecl = parseStructOrUnionDecl().to!(StructDecl);
1763         structDecl.setAlignSize(size);
1764         set(structDecl, begin2);
1765       }
1766       else
1767         expected!"struct";
1768 
1769       d = structDecl ? cast(Declaration)structDecl : new CompoundDecl;
1770       d = new AlignDecl(sizetok, d);
1771       goto LreturnDeclarationStmt;
1772 
1773     case T!"extern", T!"const", T!"auto":
1774          //T!"final", T!"scope", T!"static":
1775       goto case_parseAttribute;
1776     version(D2)
1777     {
1778     case T!"immutable", T!"inout", T!"pure", T!"shared", T!"__gshared",
1779          T!"ref", T!"nothrow", T!"@":
1780       goto case_parseAttribute;
1781     }
1782 
1783     case T!"Identifier":
1784       if (nextIs!":")
1785       {
1786         skip!"Identifier"; skip!":";
1787         s = new LabeledStmt(begin, parseNoScopeOrEmptyStmt());
1788         break;
1789       }
1790       goto case T!".";
1791     version(D2)
1792     {
1793     case T!"this", T!"super":
1794       goto case T!".";
1795     }
1796     case T!".", T!"typeof":
1797       bool success;
1798       d = tryToParse({ return parseVariablesOrFunction(); }, success);
1799       if (success)
1800         goto LreturnDeclarationStmt; // Declaration
1801       else
1802         goto case_parseExpressionStmt; // Expression
1803     case T!"if":              s = parseIfStmt();            break;
1804     case T!"while":           s = parseWhileStmt();         break;
1805     case T!"do":              s = parseDoWhileStmt();       break;
1806     case T!"for":             s = parseForStmt();           break;
1807     case T!"foreach",
1808          T!"foreach_reverse": s = parseForeachStmt();       break;
1809     case T!"switch":          s = parseSwitchStmt();        break;
1810     case T!"case":            s = parseCaseStmt();          break;
1811     case T!"default":         s = parseDefaultStmt();       break;
1812     case T!"continue":        s = parseContinueStmt();      break;
1813     case T!"break":           s = parseBreakStmt();         break;
1814     case T!"return":          s = parseReturnStmt();        break;
1815     case T!"goto":            s = parseGotoStmt();          break;
1816     case T!"with":            s = parseWithStmt();          break;
1817     case T!"synchronized":    s = parseSynchronizedStmt();  break;
1818     case T!"try":             s = parseTryStmt();           break;
1819     case T!"throw":           s = parseThrowStmt();         break;
1820     case T!"volatile":        s = parseVolatileStmt();      break;
1821     case T!"asm":             s = parseAsmBlockStmt();      break;
1822     case T!"pragma":          s = parsePragmaStmt();        break;
1823     case T!"debug":           s = parseDebugStmt();         break;
1824     case T!"version":         s = parseVersionStmt();       break;
1825     case T!"{":               s = parseScopeStmt();         break;
1826     case T!";":         nT(); s = new EmptyStmt();          break;
1827     case_T_Scope:             s = parseScopeGuardStmt();    break;
1828     case_T_Mixin:             s = parseMixin!(MixinStmt)(); break;
1829     case_parseAttribute:      s = parseAttributeStmt();     break;
1830     case T!"scope":
1831       if (!nextIs!"(")
1832         goto case_parseAttribute;
1833       goto case_T_Scope;
1834     case T!"mixin":
1835       if (nextIs!"(")
1836         goto case_parseExpressionStmt; // Parse as expression.
1837       goto case_T_Mixin;
1838     case T!"final":
1839       version(D2)
1840       {
1841       if (nextIs!"switch")
1842         goto case T!"switch";
1843       }
1844       goto case_parseAttribute;
1845     case T!"static":
1846       switch (peekNext())
1847       {
1848       case T!"if":     s = parseStaticIfStmt();     break;
1849       case T!"assert": s = parseStaticAssertStmt(); break;
1850       default:         goto case_parseAttribute;
1851       }
1852       break;
1853     // DeclDef
1854     case T!"alias", T!"typedef":
1855       d = parseDeclarationDefinition();
1856       goto LreturnDeclarationStmt;
1857     case T!"enum":
1858       version(D2)
1859       if (isEnumManifest())
1860         goto case_parseAttribute;
1861       d = parseEnumDecl();
1862       goto LreturnDeclarationStmt;
1863     case T!"class":
1864       d = parseClassDecl();
1865       goto LreturnDeclarationStmt;
1866     case T!"import":
1867       version(D2)
1868       {
1869       if (!nextIs!"(")
1870       {
1871         d = parseImportDecl();
1872         goto LreturnDeclarationStmt;
1873       }
1874       }
1875       goto case_parseExpressionStmt;
1876     case T!"interface":
1877       d = parseInterfaceDecl();
1878       goto LreturnDeclarationStmt;
1879     case T!"struct", T!"union":
1880       d = parseStructOrUnionDecl();
1881       // goto LreturnDeclarationStmt;
1882     LreturnDeclarationStmt:
1883       set(d, begin);
1884       s = new DeclarationStmt(d);
1885       break;
1886     // Parse an ExpressionStmt:
1887     // Tokens that start a PrimaryExpr.
1888     // case T!"Identifier", T!".", T!"typeof":
1889     version(D1)
1890     {
1891     case T!"this":
1892     case T!"super":
1893     }
1894     case T!"null":
1895     case T!"true", T!"false":
1896     // case T!"$":
1897     case T!"Int32", T!"Int64", T!"UInt32", T!"UInt64":
1898     case T!"Float32", T!"Float64", T!"Float80",
1899          T!"IFloat32", T!"IFloat64", T!"IFloat80":
1900     case T!"Character":
1901     case T!"String":
1902     case T!"[":
1903     // case T!"{":
1904     case T!"function", T!"delegate":
1905     case T!"assert":
1906     // case T!"mixin":
1907     case T!"typeid":
1908     case T!"is":
1909     case T!"(":
1910     version(D2)
1911     {
1912     case T!"__traits":
1913     }
1914     // Tokens that can start a UnaryExpr:
1915     case T!"&", T!"++", T!"--", T!"*", T!"-",
1916          T!"+", T!"!", T!"~", T!"new", T!"delete", T!"cast":
1917     case_parseExpressionStmt:
1918       s = new ExpressionStmt(parseExpression());
1919       require2!";";
1920       break;
1921     default:
1922       if (token.isSpecialToken)
1923         goto case_parseExpressionStmt;
1924 
1925       if (!tokenIs!"$")
1926         // Assert that this isn't a valid expression.
1927         assert(delegate bool(){
1928             bool success;
1929             auto expression = tryToParse(&parseExpression, success);
1930             return success;
1931           }() == false, "Didn't expect valid expression."
1932         );
1933 
1934       // Report error: it's an illegal statement.
1935       s = new IllegalStmt();
1936       // Skip to next valid token.
1937       do
1938         nT();
1939       while (!token.isStatementStart() && !token.kind.Any!("}", "EOF"));
1940       auto text = begin.textSpan(this.prevToken);
1941       error(begin, MID.IllegalStatement, text);
1942     }
1943     assert(s !is null);
1944     set(s, begin);
1945     return s;
1946   }
1947 
1948   /// Parses a ScopeStmt.
1949   /// $(BNF ScopeStmt := NoScopeStmt)
1950   Statement parseScopeStmt()
1951   {
1952     auto s = parseNoScopeStmt();
1953     return set(new ScopeStmt(s), s.begin);
1954   }
1955 
1956   /// $(BNF
1957   ////NoScopeStmt := NonEmptyStmt | BlockStmt
1958   ////BlockStmt   := Statements)
1959   Statement parseNoScopeStmt()
1960   {
1961     if (tokenIs!"{")
1962       return parseStatements();
1963     else
1964     {
1965       if (tokenIs!";")
1966         error(MID.ExpectedNonEmptyStatement, token);
1967       return parseStatement();
1968     }
1969   }
1970 
1971   /// $(BNF NoScopeOrEmptyStmt := ";" | NoScopeStmt)
1972   Statement parseNoScopeOrEmptyStmt()
1973   {
1974     if (auto semicolon = consumedToken!";")
1975       return set(new EmptyStmt(), semicolon);
1976     else
1977       return parseNoScopeStmt();
1978   }
1979 
1980   /// $(BNF AttributeStmt := Attributes+
1981   ////  (VariableOrFunctionDecl | DeclDef)
1982   ////Attributes := extern | ExternLinkageType | auto | static |
1983   ////              final | const | immutable | enum | scope)
1984   Statement parseAttributeStmt()
1985   {
1986     StorageClass stcs, stc;
1987     LinkageType linkageType;
1988     bool testAutoDecl;
1989 
1990     // Allocate dummy declarations.
1991     scope emptyDecl = new EmptyDecl();
1992     // Function as the head of the attribute chain.
1993     scope AttributeDecl headAttr =
1994       new StorageClassDecl(StorageClass.None, emptyDecl);
1995 
1996     AttributeDecl currentAttr, prevAttr = headAttr;
1997 
1998     // Parse the attributes.
1999   Loop:
2000     while (1)
2001     {
2002       auto begin = token;
2003       switch (token.kind)
2004       {
2005       case T!"extern":
2006         if (nextIs!"(")
2007         {
2008           checkLinkageType(linkageType, parseExternLinkageType(), begin);
2009           currentAttr = new LinkageDecl(linkageType, emptyDecl);
2010           testAutoDecl = false;
2011           break;
2012         }
2013                           stc = StorageClass.Extern;   goto Lcommon;
2014       case T!"static":    stc = StorageClass.Static;   goto Lcommon;
2015       case T!"final":     stc = StorageClass.Final;    goto Lcommon;
2016       version(D2)
2017       {
2018       case T!"const", T!"immutable", T!"inout", T!"shared":
2019         if ((stc = getSTC()) == 0)
2020           break Loop;
2021         goto Lcommon;
2022       case T!"enum":
2023         if (!isEnumManifest())
2024           break Loop;
2025                           stc = StorageClass.Manifest; goto Lcommon;
2026       case T!"ref":       stc = StorageClass.Ref;      goto Lcommon;
2027       case T!"pure":      stc = StorageClass.Pure;     goto Lcommon;
2028       case T!"nothrow":   stc = StorageClass.Nothrow;  goto Lcommon;
2029       case T!"__gshared": stc = StorageClass.Gshared;  goto Lcommon;
2030       case T!"@":         stc = parseAtAttribute();    goto Lcommon;
2031       } // version(D2)
2032       else
2033       { // D1
2034       case T!"const":     stc = StorageClass.Const;    goto Lcommon;
2035       }
2036       case T!"auto":      stc = StorageClass.Auto;     goto Lcommon;
2037       case T!"scope":     stc = StorageClass.Scope;    goto Lcommon;
2038       Lcommon:
2039         if (stcs & stc) // Issue error if redundant.
2040           error2(MID.RedundantStorageClass, token);
2041         stcs |= stc;
2042         nT(); // Skip the storage class token.
2043         currentAttr = new StorageClassDecl(stc, emptyDecl);
2044         testAutoDecl = true;
2045         break;
2046       default:
2047         break Loop;
2048       }
2049       set(currentAttr, begin);
2050       // Correct the child node and continue parsing attributes.
2051       prevAttr.setDecls(currentAttr);
2052       prevAttr = currentAttr; // Current becomes previous.
2053     }
2054 
2055     // Parse the declaration.
2056     Declaration decl;
2057     assert(this.storageClass == StorageClass.None);
2058     assert(this.protection == Protection.None);
2059     assert(this.linkageType == LinkageType.None);
2060     if (token.kind.Any!("class", "interface", "struct", "union", "alias",
2061         "typedef", "enum"))
2062     {
2063       // Set current values.
2064       this.storageClass = stcs;
2065       this.linkageType = linkageType;
2066       // Parse a declaration.
2067       decl = parseDeclarationDefinition();
2068       // Clear values.
2069       this.storageClass = StorageClass.None;
2070       this.linkageType = LinkageType.None;
2071     }
2072     else
2073       decl =
2074         parseVariablesOrFunction(stcs, protection, linkageType, testAutoDecl);
2075     assert(decl !is null && isNodeSet(decl));
2076     // Attach the declaration to the previously parsed attribute.
2077     prevAttr.setDecls(decl);
2078     // Return the first attribute declaration. Wrap it in a Statement.
2079     return new DeclarationStmt(headAttr.decls);
2080   }
2081 
2082   /// $(BNF IfStmt    := if "(" Condition ")" ScopeStmt (else ScopeStmt)?
2083   ////Condition := AutoDecl | VariableDecl | Expression)
2084   Statement parseIfStmt()
2085   {
2086     skip!"if";
2087     auto paren = requireOpening!"(";
2088 
2089     Declaration variable;
2090     Expression condition;
2091     Type type;
2092     Token* name;
2093     auto begin = token; // For start of AutoDecl or normal Declaration.
2094     bool success;
2095 
2096     tryToParse({
2097       if (consumed!"auto") // auto Identifier = Expression
2098         name = requireIdentifier(MID.ExpectedVariableName);
2099       else // Declarator "=" Expression
2100         type = parseDeclarator(name);
2101       require!"=";
2102       return type;
2103     }, success);
2104 
2105     if (success)
2106     {
2107       auto init = parseExpression();
2108       variable = new VariablesDecl(type, [name], [init]);
2109       set(variable, begin);
2110     }
2111     else // Normal Expression.
2112       condition = parseExpression();
2113 
2114     requireClosing!")"(paren);
2115     auto ifBody = parseScopeStmt();
2116     auto elseBody = consumed!"else" ? parseScopeStmt() : null;
2117     return new IfStmt(variable, condition, ifBody, elseBody);
2118   }
2119 
2120   /// $(BNF WhileStmt := while "(" Expression ")" ScopeStmt)
2121   Statement parseWhileStmt()
2122   {
2123     skip!"while";
2124     auto paren = requireOpening!"(";
2125     auto condition = parseExpression();
2126     requireClosing!")"(paren);
2127     return new WhileStmt(condition, parseScopeStmt());
2128   }
2129 
2130   /// $(BNF DoWhileStmt := do ScopeStmt while "(" Expression ")")
2131   Statement parseDoWhileStmt()
2132   {
2133     skip!"do";
2134     auto doBody = parseScopeStmt();
2135     require!"while";
2136     auto paren = requireOpening!"(";
2137     auto condition = parseExpression();
2138     requireClosing!")"(paren);
2139     version(D2)
2140     require2!";";
2141     return new DoWhileStmt(condition, doBody);
2142   }
2143 
2144   /// $(BNF ForStmt :=
2145   ////  for "(" (NoScopeStmt | ";") Expression? ";" Expression? ")"
2146   ////    ScopeStmt)
2147   Statement parseForStmt()
2148   {
2149     skip!"for";
2150     auto paren = requireOpening!"(";
2151     auto init = !consumed!";" ? parseNoScopeStmt() : null;
2152     auto condition = !tokenIs!";" ? parseExpression() : null;
2153     require2!";";
2154     auto increment = !tokenIs!")" ? parseExpression() : null;
2155     requireClosing!")"(paren);
2156     auto forBody = parseScopeStmt();
2157     return new ForStmt(init, condition, increment, forBody);
2158   }
2159 
2160   /// $(BNF ForeachStmt :=
2161   ////  Foreach "(" ForeachVarList ";" Aggregate ")"
2162   ////    ScopeStmt
2163   ////Foreach        := foreach | foreach_reverse
2164   ////ForeachVarList := ForeachVar ("," ForeachVar)*
2165   ////ForeachVar     := ref? (Identifier | Declarator)
2166   ////RangeExpr2     := Expression ".." Expression # D2
2167   ////Aggregate      := RangeExpr2 | Expression)
2168   Statement parseForeachStmt()
2169   {
2170     assert(token.kind.Any!("foreach", "foreach_reverse"));
2171     auto kind = consume().kind;
2172     auto params = new Parameters;
2173     auto paren = requireOpening!"(";
2174     auto paramsBegin = token;
2175     do
2176     {
2177       auto paramBegin = token;
2178       StorageClass stcs, stc;
2179       Type type;
2180       Token* name, stctok;
2181 
2182     Lswitch:
2183       switch (token.kind)
2184       {
2185       version(D2)
2186       {
2187       case T!"const", T!"immutable", T!"inout", T!"shared":
2188         if ((stc = getSTC()) == 0)
2189           goto default;
2190         goto Lcommon;
2191       case T!"ref":
2192         stc = StorageClass.Ref;
2193       Lcommon:
2194         if (stcs & stc)
2195           error2(MID.RedundantStorageClass, token);
2196         stcs |= stc;
2197         stctok = token;
2198         nT();
2199         goto Lswitch;
2200       }
2201       version(D1)
2202       {
2203       case T!"inout", T!"ref":
2204         stcs = StorageClass.Ref;
2205         stctok = token;
2206         nT();
2207         goto case T!"Identifier";
2208       }
2209       case T!"Identifier":
2210         if (peekNext().Any!(",", ";", ")"))
2211         { // (ref|const|...)? Identifier
2212           name = requireIdentifier(MID.ExpectedVariableName);
2213           break;
2214         }
2215         goto default;
2216       default: // (ref|const|...)? Declarator
2217         type = parseDeclarator(name);
2218       }
2219 
2220       params ~= set(new Parameter(stcs, stctok, type, name, null), paramBegin);
2221     } while (consumed!",");
2222     set(params, paramsBegin);
2223 
2224     require2!";";
2225     auto e = parseExpression();
2226 
2227     version(D2)
2228     if (auto op = consumedToken!"..") // Expression ".." Expression
2229       e = set(new RangeExpr(e, parseExpression(), op), e.begin);
2230 
2231     requireClosing!")"(paren);
2232     auto forBody = parseScopeStmt();
2233     return new ForeachStmt(kind, params, e, forBody);
2234   }
2235 
2236   /// $(BNF SwitchStmt := final? switch "(" Expression ")" ScopeStmt)
2237   Statement parseSwitchStmt()
2238   {
2239     bool isFinal = consumed!"final";
2240     skip!"switch";
2241     auto paren = requireOpening!"(";
2242     auto condition = parseExpression();
2243     requireClosing!")"(paren);
2244     auto switchBody = parseScopeStmt();
2245     return new SwitchStmt(condition, switchBody, isFinal);
2246   }
2247 
2248   /// Helper function for parsing the body of a default or case statement.
2249   /// $(BNF CaseOrDefaultBody := ScopeStmt*)
2250   Statement parseCaseOrDefaultBody()
2251   {
2252     // This function is similar to parseNoScopeStmt()
2253     auto begin = token;
2254     auto s = new CompoundStmt();
2255     while (!token.kind.Any!("case", "default", "}", "EOF"))
2256       s ~= parseStatement();
2257     if (begin is token) // Nothing consumed.
2258       begin = this.prevToken;
2259     set(s, begin);
2260     return set(new ScopeStmt(s), begin);
2261   }
2262 
2263   /// $(BNF CaseStmt := case ExpressionList ":" CaseOrDefaultBody |
2264   ////            case AssignExpr ":" ".." case AssignExpr ":" CaseOrDefaultBody)
2265   Statement parseCaseStmt()
2266   {
2267     skip!"case";
2268     auto values = parseExpressionList();
2269     require2!":";
2270     version(D2)
2271     if (consumed!"..")
2272     {
2273       if (values.length > 1)
2274         error(values[1].begin, MID.CaseRangeStartExpression);
2275       require!"case";
2276       Expression left = values[0], right = parseAssignExpr();
2277       require2!":";
2278       auto caseBody = parseCaseOrDefaultBody();
2279       return new CaseRangeStmt(left, right, caseBody);
2280     } // version(D2)
2281     auto caseBody = parseCaseOrDefaultBody();
2282     return new CaseStmt(values, caseBody);
2283   }
2284 
2285   /// $(BNF DefaultStmt := default ":" CaseOrDefaultBody)
2286   Statement parseDefaultStmt()
2287   {
2288     skip!"default";
2289     require2!":";
2290     auto defaultBody = parseCaseOrDefaultBody();
2291     return new DefaultStmt(defaultBody);
2292   }
2293 
2294   /// $(BNF ContinueStmt := continue Identifier? ";")
2295   Statement parseContinueStmt()
2296   {
2297     skip!"continue";
2298     auto ident = optionalIdentifier();
2299     require2!";";
2300     return new ContinueStmt(ident);
2301   }
2302 
2303   /// $(BNF BreakStmt := break Identifier? ";")
2304   Statement parseBreakStmt()
2305   {
2306     skip!"break";
2307     auto ident = optionalIdentifier();
2308     require2!";";
2309     return new BreakStmt(ident);
2310   }
2311 
2312   /// $(BNF ReturnStmt := return Expression? ";")
2313   Statement parseReturnStmt()
2314   {
2315     skip!"return";
2316     auto expr = !tokenIs!";" ? parseExpression() : null;
2317     require2!";";
2318     return new ReturnStmt(expr);
2319   }
2320 
2321   /// $(BNF
2322   ////GotoStmt := goto (case Expression? | default | Identifier) ";")
2323   Statement parseGotoStmt()
2324   {
2325     skip!"goto";
2326     auto ident = token;
2327     Expression caseExpr;
2328     if (consumed!"case")
2329     {
2330       if (!tokenIs!";")
2331         caseExpr = parseExpression();
2332     }
2333     else if (!consumed!"default")
2334       ident = requireIdentifier(MID.ExpectedAnIdentifier);
2335     require2!";";
2336     return new GotoStmt(ident, caseExpr);
2337   }
2338 
2339   /// $(BNF WithStmt := with "(" Expression ")" ScopeStmt)
2340   Statement parseWithStmt()
2341   {
2342     skip!"with";
2343     auto paren = requireOpening!"(";
2344     auto expr = parseExpression();
2345     requireClosing!")"(paren);
2346     return new WithStmt(expr, parseScopeStmt());
2347   }
2348 
2349   /// $(BNF SynchronizedStmt := synchronized ("(" Expression ")")? ScopeStmt)
2350   Statement parseSynchronizedStmt()
2351   {
2352     skip!"synchronized";
2353     Expression expr;
2354     if (auto paren = consumedToken!"(")
2355     {
2356       expr = parseExpression();
2357       requireClosing!")"(paren);
2358     }
2359     return new SynchronizedStmt(expr, parseScopeStmt());
2360   }
2361 
2362   /// $(BNF TryStmt := try ScopeStmt CatchStmt* LastCatchStmt? FinallyStmt?
2363   ////CatchStmt     := catch "(" BasicType Identifier ")" NoScopeStmt
2364   ////LastCatchStmt := catch NoScopeStmt
2365   ////FinallyStmt   := finally NoScopeStmt)
2366   Statement parseTryStmt()
2367   {
2368     auto begin = token;
2369     skip!"try";
2370 
2371     auto tryBody = parseScopeStmt();
2372     CatchStmt[] catchBodies;
2373     FinallyStmt finBody;
2374 
2375     while (consumed!"catch")
2376     {
2377       auto catchBegin = prevToken;
2378       Parameter param;
2379       if (auto paren = consumedToken!"(")
2380       {
2381         auto paramBegin = token;
2382         Token* name;
2383         auto type = parseDeclaratorOptId(name);
2384         param = new Parameter(StorageClass.None, null, type, name, null);
2385         set(param, paramBegin);
2386         requireClosing!")"(paren);
2387       }
2388       catchBodies ~= set(new CatchStmt(param, parseNoScopeStmt()), catchBegin);
2389       if (param is null)
2390         break; // This is a LastCatch
2391     }
2392 
2393     if (auto t = consumedToken!"finally")
2394       finBody = set(new FinallyStmt(parseNoScopeStmt()), t);
2395 
2396     if (catchBodies is null && finBody is null)
2397       error(begin, MID.MissingCatchOrFinally);
2398 
2399     return new TryStmt(tryBody, catchBodies, finBody);
2400   }
2401 
2402   /// $(BNF ThrowStmt := throw Expression ";")
2403   Statement parseThrowStmt()
2404   {
2405     skip!"throw";
2406     auto expr = parseExpression();
2407     require2!";";
2408     return new ThrowStmt(expr);
2409   }
2410 
2411   /// $(BNF ScopeGuardStmt := scope "(" ScopeCondition ")" ScopeGuardBody
2412   ////ScopeCondition := "exit" | "success" | "failure"
2413   ////ScopeGuardBody := ScopeStmt | NoScopeStmt)
2414   Statement parseScopeGuardStmt()
2415   {
2416     skip!"scope";
2417     assert(tokenIs!"(");
2418     auto paren = consume();
2419     auto condition = requireIdentifier(MID.ExpectedScopeIdentifier);
2420     if (condition &&
2421         !condition.ident.In(Ident.exit, Ident.success, Ident.failure))
2422       error2(MID.InvalidScopeIdentifier, condition);
2423     requireClosing!")"(paren);
2424     auto scopeBody = tokenIs!"{" ? parseScopeStmt() : parseNoScopeStmt();
2425     return new ScopeGuardStmt(condition, scopeBody);
2426   }
2427 
2428   /// $(BNF VolatileStmt := volatile (ScopeStmt | NoScopeStmt))
2429   Statement parseVolatileStmt()
2430   {
2431     skip!"volatile";
2432     auto volatileBody = tokenIs!"{" ? parseScopeStmt() : parseNoScopeStmt();
2433     return new VolatileStmt(volatileBody);
2434   }
2435 
2436   /// $(BNF PragmaStmt :=
2437   ////  pragma "(" Identifier ("," ExpressionList)? ")" NoScopeStmt)
2438   Statement parsePragmaStmt()
2439   {
2440     skip!"pragma";
2441     auto paren = requireOpening!"(";
2442     auto name = requireIdentifier(MID.ExpectedPragmaIdentifier);
2443     auto args = consumed!"," ? parseExpressionList() : null;
2444     requireClosing!")"(paren);
2445     auto pragmaBody = parseNoScopeOrEmptyStmt();
2446     return new PragmaStmt(name, args, pragmaBody);
2447   }
2448 
2449   /// $(BNF StaticIfStmt :=
2450   ////  static if "(" Expression ")" NoScopeStmt (else NoScopeStmt)?)
2451   Statement parseStaticIfStmt()
2452   {
2453     skip!"static";
2454     skip!"if";
2455     auto paren = requireOpening!"(";
2456     auto condition = parseExpression();
2457     requireClosing!")"(paren);
2458     auto ifBody = parseNoScopeStmt();
2459     auto elseBody = consumed!"else" ? parseNoScopeStmt() : null;
2460     return new StaticIfStmt(condition, ifBody, elseBody);
2461   }
2462 
2463   /// $(BNF StaticAssertStmt :=
2464   ////  static assert "(" AssignExpr ("," Message)? ")" ";"
2465   ////Message := AssignExpr)
2466   Statement parseStaticAssertStmt()
2467   {
2468     skip!"static";
2469     skip!"assert";
2470     auto paren = requireOpening!"(";
2471     auto condition = parseAssignExpr();
2472     auto message = consumed!"," ? parseAssignExpr() : null;
2473     requireClosing!")"(paren);
2474     require2!";";
2475     return new StaticAssertStmt(condition, message);
2476   }
2477 
2478   /// $(BNF DebugStmt :=
2479   ////  debug DebugCondition? NoScopeStmt (else NoScopeStmt)?)
2480   Statement parseDebugStmt()
2481   {
2482     skip!"debug";
2483     Token* cond;
2484     if (auto paren = consumedToken!"(")
2485     { // ( Condition )
2486       cond = parseIdentOrInt();
2487       requireClosing!")"(paren);
2488     }
2489     auto debugBody = parseNoScopeStmt();
2490     auto elseBody = consumed!"else" ? parseNoScopeStmt() : null;
2491     return new DebugStmt(cond, debugBody, elseBody);
2492   }
2493 
2494   /// $(BNF VersionStmt :=
2495   ////  version VCondition NoScopeStmt (else NoScopeStmt)?)
2496   Statement parseVersionStmt()
2497   {
2498     skip!"version";
2499     auto paren = requireOpening!"(";
2500     auto cond = parseVersionCondition();
2501     requireClosing!")"(paren);
2502     auto versionBody = parseNoScopeStmt();
2503     auto elseBody = consumed!"else" ? parseNoScopeStmt() : null;
2504     return new VersionStmt(cond, versionBody, elseBody);
2505   }
2506 
2507   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2508   |                        Assembler parsing methods                        |
2509    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
2510 
2511   /// Parses an AsmBlockStmt.
2512   /// $(BNF AsmBlockStmt := asm "{" AsmStmt* "}")
2513   Statement parseAsmBlockStmt()
2514   {
2515     skip!"asm";
2516     auto brace = requireOpening!"{";
2517     auto ss = new CompoundStmt;
2518     while (!token.kind.Any!("}", "EOF"))
2519       ss ~= parseAsmStmt();
2520     requireClosing!"}"(brace);
2521     return new AsmBlockStmt(set(ss, brace));
2522   }
2523 
2524   /// $(BNF
2525   ////AsmStmt :=
2526   ////  OpcodeStmt | LabeledStmt | AsmAlignStmt | EmptyStmt
2527   ////OpcodeStmt   := Opcode Operands? ";"
2528   ////Opcode       := Identifier
2529   ////Operands     := AsmExpr ("," AsmExpr)*
2530   ////LabeledStmt  := Identifier ":" AsmStmt
2531   ////AsmAlignStmt := align Integer ";"
2532   ////EmptyStmt    := ";")
2533   Statement parseAsmStmt()
2534   {
2535     auto begin = token;
2536     Statement s;
2537     alias ident = begin;
2538     switch (token.kind)
2539     {
2540     case T!"in", T!"int", T!"out": // Keywords that are valid opcodes.
2541       nT();
2542       goto LparseOperands;
2543     case T!"Identifier":
2544       nT();
2545       if (consumed!":")
2546       { // Identifier ":" AsmStmt
2547         s = new LabeledStmt(ident, parseAsmStmt());
2548         break;
2549       }
2550 
2551       // JumpOpcode (short | (near | far) ptr)?
2552       if (Ident.isJumpOpcode(ident.ident.idKind))
2553         if (tokenIs!"short")
2554           nT();
2555         else if (tokenIs!"Identifier" && token.ident.In(Ident.near, Ident.far))
2556         {
2557           nT();
2558           if (tokenIs!"Identifier" && token.ident is Ident.ptr)
2559             skip!"Identifier";
2560           else
2561             error2(MID.ExpectedButFound, "ptr", token);
2562         }
2563 
2564       // TODO: Handle opcodes db, ds, di, dl, df, dd, de.
2565       //       They accept string operands.
2566 
2567     LparseOperands:
2568       // Opcode Operands? ";"
2569       Expression[] es;
2570       if (!tokenIs!";")
2571         do
2572           es ~= parseAsmExpr();
2573         while (consumed!",");
2574       require2!";";
2575       s = new AsmStmt(ident, es);
2576       break;
2577     case T!"align":
2578       // align Integer ";"
2579       nT();
2580       auto number = token;
2581       if (!consumed!"Int32")
2582         error2(MID.ExpectedIntegerAfterAlign, token);
2583       require2!";";
2584       s = new AsmAlignStmt(number);
2585       break;
2586     case T!";":
2587       s = new EmptyStmt();
2588       nT();
2589       break;
2590     default:
2591       s = new IllegalAsmStmt();
2592       // Skip to next valid token.
2593       do
2594         nT();
2595       while (!token.isAsmStatementStart() && !token.kind.Any!("}", "EOF"));
2596       auto text = begin.textSpan(this.prevToken);
2597       error(begin, MID.IllegalAsmStatement, text);
2598     }
2599     set(s, begin);
2600     return s;
2601   }
2602 
2603   /// $(BNF AsmExpr     := AsmCondExpr
2604   ////AsmCondExpr := AsmBinaryExpr ("?" AsmExpr ":" AsmExpr)?)
2605   Expression parseAsmExpr()
2606   {
2607     auto begin = token;
2608     auto e = parseAsmBinaryExpr();
2609     if (auto qtok = consumedToken!"?")
2610     {
2611       auto iftrue = parseAsmExpr();
2612       auto ctok = token; // ":"
2613       require!":";
2614       auto iffalse = parseAsmExpr();
2615       e = new CondExpr(e, iftrue, iffalse, qtok, ctok);
2616       set(e, begin);
2617     }
2618     // TODO: create AsmExpr that contains e?
2619     return e;
2620   }
2621 
2622   /// $(BNF AsmBinaryExpr := AsmOrOrExpr
2623   ////AsmOrOrExpr   := AsmAndAndExpr ("||" AsmAndAndExpr)*
2624   ////AsmAndAndExpr := AsmOrExpr  ("&&" AsmOrExpr)*
2625   ////AsmOrExpr     := AsmXorExpr ("|" AsmXorExpr)*
2626   ////AsmXorExpr    := AsmAndExpr ("^" AsmAndExpr)*
2627   ////AsmAndExpr    := AsmCmpExpr ("&" AsmCmpExpr)*
2628   ////AsmCmpExpr    := AsmShiftExpr (AsmCmpOp AsmShiftExpr)*
2629   ////AsmCmpOp      := "==" | "!=" | "<" | "<=" | ">" | ">="
2630   ////AsmShiftExpr  := AsmAddExpr (AsmShiftOp AsmAddExpr)*
2631   ////AsmShiftOp    := "<<" | ">>" | ">>>"
2632   ////AsmAddExpr    := AsmMulExpr (AsmAddOp AsmMulExpr)*
2633   ////AsmAddOp      := "+" | "-"
2634   ////AsmMulExpr    := AsmPostExpr (AsmMulOp AsmPostExpr)*
2635   ////AsmMulOp      := "*" | "/" | "%"
2636   ////)
2637   /// Params:
2638   ///   prevPrec = The precedence of the previous operator.
2639   Expression parseAsmBinaryExpr(PREC prevPrec = PREC.None)
2640   {
2641     auto begin = token;
2642     auto e = parseAsmPostExpr(); // Parse the left-hand side.
2643 
2644     NewBinaryExpr makeBinaryExpr = void;
2645     while (1)
2646     {
2647       auto operator = token;
2648       auto opPrec = parseBinaryOp(makeBinaryExpr, prevPrec);
2649       if (opPrec <= prevPrec) // Continue as long as the operators
2650         break;                // have higher precedence.
2651       if (prevToken.kind.Any!(/*"!", */"is", "in", "!<>=", "!<>", "!<=", "!<",
2652         "!>=", "!>", "<>=", "<>", "~", "^^"))
2653         // Use textSpan() for operators like "!is" and "!in".
2654         error(operator, MID.IllegalAsmBinaryOp, operator.textSpan(prevToken));
2655       auto rhs = parseAsmBinaryExpr(opPrec); // Parse the right-hand side.
2656       e = makeBinaryExpr(e, rhs, operator);
2657       set(e, begin);
2658     }
2659     return e;
2660   }
2661 
2662   /// $(BNF AsmPostExpr := AsmUnaryExpr ("[" AsmExpr "]")*)
2663   Expression parseAsmPostExpr()
2664   {
2665     Token* begin = token, bracket = void;
2666     auto e = parseAsmUnaryExpr();
2667     while ((bracket = consumedToken!"[") !is null)
2668     {
2669       e = new AsmPostBracketExpr(e, parseAsmExpr());
2670       requireClosing!"]"(bracket);
2671       set(e, begin);
2672     }
2673     return e;
2674   }
2675 
2676   /// $(BNF
2677   ////AsmUnaryExpr :=
2678   ////  AsmPrimaryExpr | AsmTypeExpr | AsmOffsetExpr | AsmSegExpr |
2679   ////  SignExpr | NotExpr | ComplementExpr
2680   ////AsmTypeExpr := TypePrefix "ptr" AsmExpr
2681   ////TypePrefix  := "byte" | "shor" | "int" | "float" | "double" | "real"
2682   ////               "near" | "far" | "word" | "dword" | "qword"
2683   ////AsmOffsetExpr  := "offset" AsmExpr
2684   ////AsmSegExpr     := "seg" AsmExpr
2685   ////SignExpr       := ("+" | "-") AsmUnaryExpr
2686   ////NotExpr        := "!" AsmUnaryExpr
2687   ////ComplementExpr := "~" AsmUnaryExpr
2688   ////)
2689   Expression parseAsmUnaryExpr()
2690   {
2691     auto begin = token;
2692     Expression e;
2693     switch (token.kind)
2694     {
2695     case T!"byte",  T!"short",  T!"int", T!"float", T!"double", T!"real":
2696       goto LAsmTypePrefix;
2697     case T!"Identifier":
2698       switch (token.ident.idKind)
2699       {
2700       case IDK.near, IDK.far,/* "byte",  "short",  "int",*/
2701            IDK.word, IDK.dword, IDK.qword/*, "float", "double", "real"*/:
2702       LAsmTypePrefix:
2703         nT();
2704         if (tokenIs!"Identifier" && token.ident is Ident.ptr)
2705           skip!"Identifier";
2706         else
2707           error2(MID.ExpectedButFound, "ptr", token);
2708         e = new AsmTypeExpr(begin, parseAsmExpr());
2709         break;
2710       case IDK.offsetof:
2711         nT();
2712         e = new AsmOffsetExpr(parseAsmExpr());
2713         break;
2714       case IDK.seg:
2715         nT();
2716         e = new AsmSegExpr(parseAsmExpr());
2717         break;
2718       default:
2719         goto LparseAsmPrimaryExpr;
2720       }
2721       break;
2722     case T!"-", T!"+":
2723       nT();
2724       e = new SignExpr(parseAsmUnaryExpr());
2725       break;
2726     case T!"!":
2727       nT();
2728       e = new NotExpr(parseAsmUnaryExpr());
2729       break;
2730     case T!"~":
2731       nT();
2732       e = new CompExpr(parseAsmUnaryExpr());
2733       break;
2734     default:
2735     LparseAsmPrimaryExpr:
2736       e = parseAsmPrimaryExpr();
2737       return e;
2738     }
2739     set(e, begin);
2740     return e;
2741   }
2742 
2743   /// $(BNF AsmPrimaryExpr :=
2744   ////  IntExpr | FloatExpr | DollarExpr |
2745   ////  AsmBracketExpr |AsmLocalSizeExpr | AsmRegisterExpr |
2746   ////  IdentifiersExpr
2747   ////IntExpr          := IntegerLiteral
2748   ////FloatExpr        := FloatLiteral
2749   ////DollarExpr       := "$"
2750   ////AsmBracketExpr   := "[" AsmExpr "]"
2751   ////AsmLocalSizeExpr := "__LOCAL_SIZE"
2752   ////AsmRegisterExpr  := ...)
2753   Expression parseAsmPrimaryExpr()
2754   {
2755     auto begin = token;
2756     Expression e;
2757     switch (token.kind)
2758     {
2759     case T!"Int32", T!"Int64", T!"UInt32", T!"UInt64":
2760       e = new IntExpr(token);
2761       nT();
2762       break;
2763     case T!"Float32", T!"Float64", T!"Float80",
2764          T!"IFloat32", T!"IFloat64", T!"IFloat80":
2765       e = new FloatExpr(token);
2766       nT();
2767       break;
2768     case T!"$":
2769       e = new DollarExpr();
2770       nT();
2771       break;
2772     case T!"[":
2773       // [ AsmExpr ]
2774       auto bracket = consume();
2775       e = parseAsmExpr();
2776       requireClosing!"]"(bracket);
2777       e = new AsmBracketExpr(e);
2778       break;
2779     case T!"Identifier":
2780       auto register = token;
2781       switch (register.ident.idKind)
2782       {
2783       // __LOCAL_SIZE
2784       case IDK.__LOCAL_SIZE:
2785         nT();
2786         e = new AsmLocalSizeExpr();
2787         break;
2788       // Register
2789       case IDK.ST:
2790         nT();
2791         Expression number; // (1) - (7)
2792         if (auto paren = consumedToken!"(")
2793           (number = parseAsmExpr()),
2794           requireClosing!")"(paren);
2795         e = new AsmRegisterExpr(register, number);
2796         break;
2797       case IDK.ES, IDK.CS, IDK.SS, IDK.DS, IDK.GS, IDK.FS:
2798         nT(); // Segment := XX (":" AsmExpr)?
2799         auto number = consumed!":" ? parseAsmExpr() : null;
2800         e = new AsmRegisterExpr(register, number);
2801         break;
2802       case IDK.AL, IDK.AH, IDK.AX, IDK.EAX,
2803            IDK.BL, IDK.BH, IDK.BX, IDK.EBX,
2804            IDK.CL, IDK.CH, IDK.CX, IDK.ECX,
2805            IDK.DL, IDK.DH, IDK.DX, IDK.EDX,
2806            IDK.BP, IDK.EBP, IDK.SP, IDK.ESP,
2807            IDK.DI, IDK.EDI, IDK.SI, IDK.ESI,
2808            IDK.CR0, IDK.CR2, IDK.CR3, IDK.CR4,
2809            IDK.DR0, IDK.DR1, IDK.DR2, IDK.DR3, IDK.DR6, IDK.DR7,
2810            IDK.TR3, IDK.TR4, IDK.TR5, IDK.TR6, IDK.TR7,
2811            IDK.MM0, IDK.MM1, IDK.MM2, IDK.MM3,
2812            IDK.MM4, IDK.MM5, IDK.MM6, IDK.MM7,
2813            IDK.XMM0, IDK.XMM1, IDK.XMM2, IDK.XMM3,
2814            IDK.XMM4, IDK.XMM5, IDK.XMM6, IDK.XMM7:
2815         nT();
2816         e = new AsmRegisterExpr(register);
2817         break;
2818       default:
2819         e = parseIdentifiersExpr();
2820       } // end of switch
2821       break;
2822     case T!".":
2823       e = parseIdentifiersExpr();
2824       break;
2825     default:
2826       error2(MID.ExpectedButFound, "Expression", token);
2827       nT();
2828       e = new IllegalExpr();
2829     }
2830     set(e, begin);
2831     return e;
2832   }
2833 
2834   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2835   |                       Expression parsing methods                        |
2836    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
2837 
2838 
2839   /// Instantiates a function that returns a new binary expression.
2840   static Expression newBinaryExpr(E)(Expression l, Expression r, Token* op)
2841   {
2842     return new E(l, r, op);
2843   }
2844   /// The function signature of newBinaryExpr.
2845   alias NewBinaryExpr = Expression function(Expression, Expression, Token*);
2846 
2847   /// The root method for parsing an Expression.
2848   /// $(BNF Expression := CommaExpr
2849   ////CommaExpr := AssignExpr ("," AssignExpr)*)
2850   Expression parseExpression()
2851   {
2852     Token* begin = token, comma = void;
2853     auto e = parseAssignExpr();
2854     while ((comma = consumedToken!",") !is null)
2855       e = set(new CommaExpr(e, parseAssignExpr(), comma), begin);
2856     return e;
2857   }
2858 
2859   /// $(BNF AssignExpr := CondExpr (AssignOp AssignExpr)*
2860   ////AssignOp   := "=" | "<<=" | ">>=" | ">>>=" | "|=" | "&=" |
2861   ////              "+=" | "-=" | "/=" | "*=" | "%=" | "^=" | "~=" | "^^=")
2862   Expression parseAssignExpr()
2863   {
2864     auto begin = token;
2865     auto e = parseCondExpr();
2866     auto optok = token;
2867     NewBinaryExpr f = void;
2868     switch (optok.kind)
2869     {
2870     case T!"=":    f = &newBinaryExpr!(AssignExpr); goto Lcommon;
2871     case T!"<<=":  f = &newBinaryExpr!(LShiftAssignExpr); goto Lcommon;
2872     case T!">>=":  f = &newBinaryExpr!(RShiftAssignExpr); goto Lcommon;
2873     case T!">>>=": f = &newBinaryExpr!(URShiftAssignExpr); goto Lcommon;
2874     case T!"|=":   f = &newBinaryExpr!(OrAssignExpr); goto Lcommon;
2875     case T!"&=":   f = &newBinaryExpr!(AndAssignExpr); goto Lcommon;
2876     case T!"+=":   f = &newBinaryExpr!(PlusAssignExpr); goto Lcommon;
2877     case T!"-=":   f = &newBinaryExpr!(MinusAssignExpr); goto Lcommon;
2878     case T!"/=":   f = &newBinaryExpr!(DivAssignExpr); goto Lcommon;
2879     case T!"*=":   f = &newBinaryExpr!(MulAssignExpr); goto Lcommon;
2880     case T!"%=":   f = &newBinaryExpr!(ModAssignExpr); goto Lcommon;
2881     case T!"^=":   f = &newBinaryExpr!(XorAssignExpr); goto Lcommon;
2882     case T!"~=":   f = &newBinaryExpr!(CatAssignExpr); goto Lcommon;
2883     version(D2)
2884     {
2885     case T!"^^=":  f = &newBinaryExpr!(PowAssignExpr); goto Lcommon;
2886     }
2887     Lcommon:
2888       nT();
2889       // Parse the right-hand side and create the expression.
2890       e = f(e, parseAssignExpr(), optok);
2891       set(e, begin);
2892       break;
2893     default:
2894     }
2895     return e;
2896   }
2897 
2898   /// $(BNF CondExpr := BinaryExpr ("?" Expression ":" CondExpr)?)
2899   Expression parseCondExpr()
2900   {
2901     auto begin = token;
2902     auto e = parseBinaryExpr();
2903     if (auto qtok = consumedToken!"?")
2904     {
2905       auto iftrue = parseExpression();
2906       auto ctok = token; // ":"
2907       require!":";
2908       auto iffalse = parseCondExpr();
2909       e = new CondExpr(e, iftrue, iffalse, qtok, ctok);
2910       set(e, begin);
2911     }
2912     return e;
2913   }
2914 
2915   /// Enumeration of binary operator precedence values.
2916   enum PREC
2917   {
2918     None,  /// No precedence.
2919     OOr,   /// ||
2920     AAnd,  /// &&
2921     Or,    /// |
2922     Xor,   /// ^
2923     And,   /// &
2924     Cmp,   /// in !in is !is == != < > <= >= etc.
2925     Shift, /// << >> >>>
2926     Plus,  /// + - ~
2927     Mul,   /// * / %
2928     Pow,   /// ^^
2929   }
2930 
2931   /// Consumes the tokens of a binary operator.
2932   /// Params:
2933   ///   fn = Receives a function that creates the binary Expression.
2934   ///   prevPrec = The precedence value of the previous operator.
2935   /// Returns: The precedence value of the binary operator.
2936   ///   The higher the value the stronger the operator binds.
2937   PREC parseBinaryOp(out NewBinaryExpr fn, PREC prevPrec)
2938   {
2939     PREC p;
2940     NewBinaryExpr f;
2941     switch (token.kind)
2942     {
2943     case T!"!":
2944       auto next = peekNext();
2945       if (next == T!"is") // "!" is
2946         goto case T!"is";
2947       else version(D2) if (next == T!"in") // "!" in
2948         goto case T!"in";
2949       break; // Not a binary operator.
2950     case T!"||":  p = PREC.OOr;   f = &newBinaryExpr!(OrOrExpr); break;
2951     case T!"&&":  p = PREC.AAnd;  f = &newBinaryExpr!(AndAndExpr); break;
2952     case T!"|":   p = PREC.Or;    f = &newBinaryExpr!(OrExpr); break;
2953     case T!"^":   p = PREC.Xor;   f = &newBinaryExpr!(XorExpr); break;
2954     case T!"&":   p = PREC.And;   f = &newBinaryExpr!(AndExpr); break;
2955     case T!"is":  p = PREC.Cmp;   f = &newBinaryExpr!(IdentityExpr); break;
2956     case T!"in":  p = PREC.Cmp;   f = &newBinaryExpr!(InExpr); break;
2957     case T!"!=",
2958          T!"==":  p = PREC.Cmp;   f = &newBinaryExpr!(EqualExpr); break;
2959     case T!"<=", T!"<", T!">=", T!">", T!"!<>=", T!"!<>", T!"!<=", T!"!<",
2960          T!"!>=", T!"!>", T!"<>=", T!"<>":
2961                   p = PREC.Cmp;   f = &newBinaryExpr!(RelExpr); break;
2962     case T!"<<":  p = PREC.Shift; f = &newBinaryExpr!(LShiftExpr); break;
2963     case T!">>":  p = PREC.Shift; f = &newBinaryExpr!(RShiftExpr); break;
2964     case T!">>>": p = PREC.Shift; f = &newBinaryExpr!(URShiftExpr); break;
2965     case T!"+":   p = PREC.Plus;  f = &newBinaryExpr!(PlusExpr); break;
2966     case T!"-":   p = PREC.Plus;  f = &newBinaryExpr!(MinusExpr); break;
2967     case T!"~":   p = PREC.Plus;  f = &newBinaryExpr!(CatExpr); break;
2968     case T!"*":   p = PREC.Mul;   f = &newBinaryExpr!(MulExpr); break;
2969     case T!"/":   p = PREC.Mul;   f = &newBinaryExpr!(DivExpr); break;
2970     case T!"%":   p = PREC.Mul;   f = &newBinaryExpr!(ModExpr); break;
2971     version(D2)
2972     {
2973     case T!"^^":  p = PREC.Pow;   f = &newBinaryExpr!(PowExpr); break;
2974     }
2975     default:
2976     }
2977     if (p == prevPrec && p == PREC.Cmp)
2978       error(token, MID.CannotChainComparisonOps); // E.g.: a == b == c
2979     // Consume if we have a binary operator
2980     // and the precedence is greater than prevPrec.
2981     if (p > prevPrec)
2982     {
2983       assert(f !is null && p != PREC.None);
2984       fn = f;
2985       if (tokenIs!"!")
2986         nT(); // Consume "!" part.
2987       nT(); // Consume the binary operator.
2988     }
2989     return p;
2990   }
2991 
2992   /// Parses a binary operator expression.
2993   ///
2994   /// $(BNF BinaryExpr := OrOrExpr
2995   ////OrOrExpr   := AndAndExpr ("||" AndAndExpr)*
2996   ////AndAndExpr := OrExpr  ("&&" OrExpr)*
2997   ////OrExpr     := XorExpr ("|" XorExpr)*
2998   ////XorExpr    := AndExpr ("^" AndExpr)*
2999   ////AndExpr    := CmpExpr ("&" CmpExpr)*
3000   ////CmpExpr    := ShiftExpr (CmpOp ShiftExpr)?
3001   ////CmpOp      := "is" | "!" "is" | "in" | "==" | "!=" | "<" | "<=" | ">" |
3002   ////              ">=" | "!<>=" | "!<>" | "!<=" | "!<" |
3003   ////              "!>=" | "!>" | "<>=" | "<>"
3004   ////ShiftExpr  := AddExpr (ShiftOp AddExpr)*
3005   ////ShiftOp    := "<<" | ">>" | ">>>"
3006   ////AddExpr    := MulExpr (AddOp MulExpr)*
3007   ////AddOp      := "+" | "-" | "~"
3008   ////MulExpr    := PostExpr (MulOp PostExpr)*
3009   ////MulExpr2   := PowExpr  (MulOp PowExpr)* # D2
3010   ////MulOp      := "*" | "/" | "%"
3011   ////PowExpr    := PostExpr ("^^" PostExpr)* # D2
3012   ////)
3013   /// Params:
3014   ///   prevPrec = The precedence of the previous operator.
3015   /// Note: Uses the "precedence climbing" method as described here:
3016   /// $(LINK http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm#climbing)
3017   Expression parseBinaryExpr(PREC prevPrec = PREC.None)
3018   {
3019     auto begin = token;
3020     auto e = parsePostExpr(); // Parse the left-hand side.
3021 
3022     NewBinaryExpr makeBinaryExpr = void;
3023     while (1)
3024     {
3025       auto operator = token;
3026       auto opPrec = parseBinaryOp(makeBinaryExpr, prevPrec);
3027       if (opPrec <= prevPrec) // Continue as long as the operators
3028         break;                // have higher precedence.
3029       auto rhs = parseBinaryExpr(opPrec); // Parse the right-hand side.
3030       e = makeBinaryExpr(e, rhs, operator);
3031       set(e, begin);
3032     }
3033     return e;
3034   }
3035 
3036   /// $(BNF PostExpr := UnaryExpr
3037   ////  (PostIdExpr | IncOrDecExpr | CallExpr | SliceExpr | IndexExpr)*
3038   ////PostIdExpr   := "." (NewExpr | IdentifierExpr)
3039   ////IncOrDecExpr := ("++" | "--")
3040   ////CallExpr     := "(" Arguments? ")"
3041   ////RangeExpr    := AssignExpr ".." AssignExpr
3042   ////SliceExpr    := "[" RangeExpr? "]")
3043   ////IndexExpr    := "[" ExpressionList "]")
3044   Expression parsePostExpr()
3045   {
3046     auto begin = token;
3047     auto e = parseUnaryExpr();
3048     while (1)
3049     {
3050       switch (token.kind)
3051       {
3052       case T!".":
3053         nT();
3054         e = tokenIs!"new" ? parseNewExpr(e) : parseIdentifierExpr(e);
3055         continue;
3056       case T!"++":
3057         e = new PostIncrExpr(e);
3058         break;
3059       case T!"--":
3060         e = new PostDecrExpr(e);
3061         break;
3062       case T!"(":
3063         e = new CallExpr(e, parseArguments());
3064         goto Lset;
3065       case T!"[":
3066         auto bracket = token;
3067         nT();
3068         // "[" "]" is the empty SliceExpr
3069         if (tokenIs!"]")
3070         {
3071           e = new SliceExpr(e, null);
3072           break;
3073         }
3074         auto e2 = parseAssignExpr();
3075         // "[" AssignExpr ".." AssignExpr "]"
3076         if (auto op = consumedToken!"..")
3077         {
3078           auto r = set(new RangeExpr(e2, parseAssignExpr(), op), e2.begin);
3079           e = new SliceExpr(e, r);
3080         }
3081         else
3082         { // "[" ExpressionList "]"
3083           auto index = [e2];
3084           if (consumed!",")
3085              index ~= parseExpressionList2(T!"]");
3086           e = new IndexExpr(e, index);
3087         }
3088         requireClosing!"]"(bracket);
3089         goto Lset;
3090       default:
3091         return e;
3092       }
3093       nT();
3094     Lset: // Jumped here to skip nT().
3095       set(e, begin);
3096     }
3097     assert(0);
3098   }
3099 
3100   /// $(BNF UnaryExpr := PrimaryExpr |
3101   ////  NewExpr | AddressExpr | PreIncrExpr |
3102   ////  PreDecrExpr | DerefExpr | SignExpr |
3103   ////  NotExpr | CompExpr | DeleteExpr |
3104   ////  CastExpr | TypeDotIdExpr
3105   ////AddressExpr   := "&" UnaryExpr
3106   ////PreIncrExpr   := "++" UnaryExpr
3107   ////PreDecrExpr   := "--" UnaryExpr
3108   ////DerefExpr     := "*" UnaryExpr
3109   ////SignExpr      := ("-" | "+") UnaryExpr
3110   ////NotExpr       := "!" UnaryExpr
3111   ////CompExpr      := "~" UnaryExpr
3112   ////DeleteExpr    := delete UnaryExpr
3113   ////CastExpr      := cast "(" Type? ")" UnaryExpr
3114   ////TypeDotIdExpr := "(" Type ")" "." Identifier
3115   ////TypeExpr      := Modifier Type)
3116   Expression parseUnaryExpr()
3117   {
3118     auto begin = token;
3119     Expression e;
3120     switch (token.kind)
3121     {
3122     case T!"&":
3123       nT();
3124       e = new AddressExpr(parseUnaryExpr());
3125       break;
3126     case T!"++":
3127       nT();
3128       e = new PreIncrExpr(parseUnaryExpr());
3129       break;
3130     case T!"--":
3131       nT();
3132       e = new PreDecrExpr(parseUnaryExpr());
3133       break;
3134     case T!"*":
3135       nT();
3136       e = new DerefExpr(parseUnaryExpr());
3137       break;
3138     case T!"-",
3139          T!"+":
3140       nT();
3141       e = new SignExpr(parseUnaryExpr());
3142       break;
3143     case T!"!":
3144       nT();
3145       e = new NotExpr(parseUnaryExpr());
3146       break;
3147     case T!"~":
3148       nT();
3149       e = new CompExpr(parseUnaryExpr());
3150       break;
3151     case T!"new":
3152       e = parseNewExpr();
3153       return e;
3154     case T!"delete":
3155       nT();
3156       e = new DeleteExpr(parseUnaryExpr());
3157       break;
3158     case T!"cast":
3159       nT();
3160       auto paren = requireOpening!"(";
3161       Type type;
3162       switch (token.kind)
3163       {
3164       version(D2)
3165       {
3166       case T!")": // Mutable cast: cast "(" ")"
3167         break;
3168       case T!"const", T!"immutable", T!"inout", T!"shared":
3169         if (!nextIs!")")
3170           goto default; // ModParenType
3171         auto mod = consume();
3172         type = set(new ModifierType(mod), mod);
3173         break;
3174       } // version(D2)
3175       default:
3176        type = parseType();
3177       }
3178       requireClosing!")"(paren);
3179       e = new CastExpr(parseUnaryExpr(), type);
3180       break;
3181     case T!"(":
3182       if (!tokenAfterParenIs(T!"."))
3183         goto default;
3184       // "(" Type ")" "." Identifier
3185       bool success;
3186       auto type = tryToParse({
3187         skip!"(";
3188         auto type = parseType(); // Type
3189         require!")";
3190         require!".";
3191         return type;
3192       }, success);
3193       if (!success)
3194         goto default;
3195       auto ident = requireIdentifier(MID.ExpectedIdAfterTypeDot);
3196       e = new TypeDotIdExpr(type, ident);
3197       break;
3198     version(D2)
3199     {
3200     case T!"immutable", T!"const", T!"shared", T!"inout":
3201       e = new TypeExpr(parseType());
3202       break;
3203     }
3204     default:
3205       e = parsePrimaryExpr();
3206       return e;
3207     }
3208     assert(e !is null);
3209     set(e, begin);
3210     return e;
3211   }
3212 
3213   /// $(BNF IdentifiersExpr :=
3214   ////  ModuleScopeExpr? IdentifierExpr ("." IdentifierExpr)*
3215   ////ModuleScopeExpr := ".")
3216   Expression parseIdentifiersExpr()
3217   {
3218     Expression e;
3219     if (tokenIs!".")
3220       e = set(new ModuleScopeExpr(), token, token);
3221     else
3222       e = parseIdentifierExpr();
3223     while (consumed!".")
3224       e = parseIdentifierExpr(e);
3225     return e;
3226   }
3227 
3228   /// $(BNF IdentifierExpr   := Identifier | TemplateInstance
3229   ////TemplateInstance := Identifier "!" TemplateArgumentsOneOrMore)
3230   Expression parseIdentifierExpr(Expression next = null)
3231   {
3232     auto begin = token;
3233     auto ident = requireIdentifier(MID.ExpectedAnIdentifier);
3234     Expression e;
3235     // Peek to avoid parsing: "id !is Exp" or "id !in Exp"
3236     if (tokenIs!"!" && !peekNext().Any!("is", "in"))
3237     {
3238       skip!"!";
3239       // Identifier "!" "(" TemplateArguments? ")"
3240       // Identifier "!" TemplateArgumentSingle
3241       auto tparams = parseOneOrMoreTemplateArguments();
3242       e = new TmplInstanceExpr(ident, tparams, next);
3243     }
3244     else // Identifier
3245       e = new IdentifierExpr(ident, next);
3246     return set(e, begin);
3247   }
3248 
3249   /// $(BNF LambdaBody := AssignExpr)
3250   Expression parseLambdaExprBody()
3251   {
3252     skip!"=>";
3253     return parseAssignExpr();
3254   }
3255 
3256   /// $(BNF LambdaExpr := LambdaParams "=>" LambdaBody
3257   ////LambdaParams := Identifier | ParameterList ParamsPostfix)
3258   Expression parseSingleParamLambdaExpr()
3259   {
3260     auto begin = token;
3261     skip!"Identifier";
3262     auto params = set(new Parameters(), begin);
3263     auto param = new Parameter(StorageClass.None, null, null, begin, null);
3264     params ~= set(param, begin);
3265     auto fstmt = parseLambdaExprBody();
3266     return set(new LambdaExpr(params, fstmt), begin);
3267   }
3268 
3269   /// $(BNF PrimaryExpr := IdentifierExpr | ModuleScopeExpr |
3270   ////  LambdaExpr | TypeofExpr | ThisExpr | SuperExpr |
3271   ////  NullExpr | BoolExpr | DollarExpr | IntExpr | FloatExpr |
3272   ////  CharExpr | StringExpr | ArrayLiteralExpr | AArrayLiteralExpr |
3273   ////  FuncLiteralExpr | AssertExpr | MixinExpr | ImportExpr |
3274   ////  TypeidExpr | IsExpr | ParenExpr | TraitsExpr | TypeDotIdExpr |
3275   ////  SpecialTokenExpr
3276   ////TypeofExpr    := TypeofType
3277   ////ThisExpr      := this
3278   ////SuperExpr     := super
3279   ////NullExpr      := null
3280   ////BoolExpr      := true | false
3281   ////DollarExpr    := "$"
3282   ////IntExpr       := IntegerLiteral
3283   ////FloatExpr     := FloatLiteral
3284   ////CharExpr      := CharacterLiteral
3285   ////StringExpr    := StringLiteral+
3286   ////StringLiteral := NormalStringLiteral | EscapeStringLiteral |
3287   ////  RawStringLiteral | HexStringLiteral | DelimitedStringLiteral |
3288   ////  TokenStringLiteral
3289   ////ArrayLiteralExpr := "[" ExpressionList2 "]"
3290   ////AArrayLiteralExpr := "[" KeyValue ("," KeyValue)* ","? "]"
3291   ////KeyValue := (AssignExpr ":" AssignExpr)
3292   ////FuncLiteralExpr := (function | delegate)?
3293   ////  (ReturnType? ParameterList FunctionPostfix?)? "{" Statements "}"
3294   ////AssertExpr := assert "(" AssignExpr ("," AssignExpr)? ")"
3295   ////MixinExpr  := mixin "(" AssignExpr ")"
3296   ////ImportExpr := import "(" AssignExpr ")"
3297   ////TypeidExpr := typeid "(" Type ")"
3298   ////IsExpr := is "(" Declarator (Specialization TemplateParameterList2)? ")"
3299   ////Specialization := ((":" | "==") (SpecToken | Type))
3300   ////SpecToken := typedef | struct | union | class | interface | enum |
3301   ////  function | delegate | super | return |
3302   ////  const | immutable | inout | shared
3303   ////ParenExpr := "(" Expression ")"
3304   ////TraitsExpr := __traits "(" Identifier ("," TemplateArguments)? ")"
3305   ////TypeDotIdExpr := "(" Type ")" "." Identifier
3306   ////SpecialTokenExpr := SpecialToken)
3307   Expression parsePrimaryExpr()
3308   {
3309     auto begin = token;
3310     Expression e;
3311     switch (token.kind)
3312     {
3313     case T!"Identifier":
3314       e = nextIs!"=>" ? parseSingleParamLambdaExpr() : parseIdentifierExpr();
3315       return e;
3316     case T!"typeof":
3317       e = new TypeofExpr(parseTypeofType());
3318       break;
3319     case T!".":
3320       e = set(new ModuleScopeExpr(), begin, begin);
3321       nT();
3322       // parseIdentifiersExpr() isn't used; see case T!"." in parsePostExpr().
3323       e = parseIdentifierExpr(e);
3324       return e;
3325     case T!"this":
3326       e = new ThisExpr();
3327       goto LnT_and_return;
3328     case T!"super":
3329       e = new SuperExpr();
3330       goto LnT_and_return;
3331     case T!"null":
3332       e = new NullExpr();
3333       goto LnT_and_return;
3334     case T!"true", T!"false":
3335       e = new BoolExpr(token);
3336       goto LnT_and_return;
3337     case T!"$":
3338       e = new DollarExpr();
3339       goto LnT_and_return;
3340     case T!"Int32", T!"Int64", T!"UInt32", T!"UInt64":
3341       e = new IntExpr(token);
3342       goto LnT_and_return;
3343     case T!"Float32", T!"Float64", T!"Float80",
3344          T!"IFloat32", T!"IFloat64", T!"IFloat80":
3345       e = new FloatExpr(token);
3346       goto LnT_and_return;
3347     case T!"Character":
3348       e = new CharExpr(token);
3349       goto LnT_and_return;
3350     LnT_and_return:
3351       nT();
3352       assert(begin is prevToken);
3353       set(e, begin, begin);
3354       return e;
3355     case T!"String":
3356       auto str = token.strval.str;
3357       char postfix = token.strval.pf;
3358       nT();
3359       if (auto t = consumedToken!"String")
3360       { // Concatenate adjacent string literals.
3361         auto buffer = lexer.getBuffer();
3362         buffer ~= cast(cstring)str;
3363         do
3364         {
3365           if (auto pf = t.strval.pf) // If the string has a postfix char.
3366           {
3367             if (pf != postfix)
3368               error(t, MID.StringPostfixMismatch);
3369             postfix = pf;
3370           }
3371           buffer ~= cast(cstring)t.strval.str;
3372         } while((t = consumedToken!"String") !is null);
3373         str = cast(cbinstr)buffer[].dup; // Copy final string.
3374         lexer.setBuffer(buffer);
3375       }
3376 
3377       if (postfix)
3378       { // Check for UTF8 errors and if needed convert to UTF16 or UTF32.
3379         cbinstr function(cstring) conversionFunction =
3380           (postfix == 'c') ? x => cast(cbinstr)x :
3381           (postfix == 'w') ? x => cast(cbinstr)dil.Unicode.toUTF16(x) :
3382                              x => cast(cbinstr)dil.Unicode.toUTF32(x);
3383         if (!hasInvalidUTF8(str, begin))
3384           str = conversionFunction(cast(cstring)str);
3385       }
3386 
3387       // Did the value change due to conversion or multiple string literals?
3388       if (begin.strval.str !is str)
3389         str = lexer.lookupString(str); // Insert into table if so.
3390 
3391       e = new StringExpr(str, postfix);
3392       break;
3393     case T!"[":
3394       nT();
3395       Expression[] exprs;
3396       if (!tokenIs!"]")
3397         exprs = [parseAssignExpr()];
3398       if (consumed!":")
3399       { // "[" AssignExpr ":"
3400         Expression[] values;
3401         while (1)
3402         {
3403           values ~= parseAssignExpr();
3404           if (!consumed!"," || tokenIs!"]")
3405             break;
3406           exprs ~= parseAssignExpr(); // Keys
3407           require!":";
3408         }
3409         e = new AArrayLiteralExpr(exprs, values);
3410       }
3411       else
3412       { // "[" "]" | "[" AssignExpr
3413         if (consumed!",") // "," ExpressionList2
3414           exprs ~= parseExpressionList2(T!"]");
3415         e = new ArrayLiteralExpr(exprs);
3416       }
3417       requireClosing!"]"(begin);
3418       break;
3419     case T!"{":
3420       // DelegateLiteral := { Statements }
3421       e = new FuncLiteralExpr(parseFunctionBody());
3422       break;
3423     case T!"function", T!"delegate":
3424       // FunctionLiteral := ("function" | "delegate")
3425       //   ReturnType? "(" ArgumentList ")" FunctionPostfix? FunctionBody
3426       nT(); // Skip function or delegate keyword.
3427       Type returnType;
3428       Parameters parameters;
3429       if (!tokenIs!"{")
3430       {
3431         if (!tokenIs!"(") // Optional return type
3432           returnType = parseBasicTypes();
3433         parameters = parseParameterList();
3434         version(D2)
3435         parameters.postSTCs = parseFunctionPostfix();
3436       }
3437       auto funcBody = consumed!"=>" ? parseAssignExpr() : parseFunctionBody();
3438       e = new FuncLiteralExpr(begin, returnType, parameters, funcBody);
3439       break;
3440     case T!"assert":
3441       nT();
3442       require2!"(";
3443       e = parseAssignExpr();
3444       auto msg = consumed!"," ? parseAssignExpr() : null;
3445       require2!")";
3446       e = new AssertExpr(e, msg);
3447       break;
3448     case T!"mixin":
3449       nT();
3450       require2!"(";
3451       e = new MixinExpr(parseAssignExpr());
3452       require2!")";
3453       break;
3454     case T!"import":
3455       nT();
3456       require2!"(";
3457       e = new ImportExpr(parseAssignExpr());
3458       require2!")";
3459       break;
3460     case T!"typeid":
3461       nT();
3462       require2!"(";
3463       e = new TypeidExpr(parseType());
3464       require2!")";
3465       break;
3466     case T!"is":
3467       nT();
3468       auto paren = requireOpening!"(";
3469 
3470       Type specType;
3471       Token* ident; // optional Identifier
3472       Token* opTok, specTok;
3473 
3474       auto type = parseDeclaratorOptId(ident);
3475 
3476       if (token.kind.Any!(":", "=="))
3477       {
3478         opTok = token;
3479         nT();
3480         switch (token.kind)
3481         {
3482         case T!"typedef", T!"struct", T!"union", T!"class", T!"interface",
3483              T!"enum", T!"function", T!"delegate", T!"super", T!"return",
3484              T!"__argTypes", T!"__parameters":
3485         case_Const_Immutable_Inout_Shared: // D2
3486           specTok = token;
3487           nT();
3488           break;
3489         version(D2)
3490         {
3491         case T!"const", T!"immutable", T!"inout", T!"shared":
3492           if (peekNext().Any!(")", ","))
3493             goto case_Const_Immutable_Inout_Shared;
3494           goto default; // It's a type.
3495         } // version(D2)
3496         default:
3497           specType = parseType();
3498         }
3499       }
3500 
3501       TemplateParameters tparams;
3502       // "is" "(" DeclaratorOptId (":" | "==") TypeSpecialization ","
3503       //          TemplateParameterList ")"
3504       version(D2)
3505       if (specType && tokenIs!",")
3506         tparams = parseTemplateParameterList2();
3507       requireClosing!")"(paren);
3508       e = new IsExpr(type, ident, opTok, specTok, specType, tparams);
3509       break;
3510     case T!"(":
3511       auto kind = skipParens(token, T!")").kind;
3512       if (kind.Any!(FunctionPostfix, "{", "=>")) // E.g.: "(" int "a" ")" pure
3513       {
3514         auto parameters = parseParameterList(); // "(" ParameterList ")"
3515         parameters.postSTCs = parseFunctionPostfix(); // Optional attributes.
3516         FuncBodyStmt fstmt;
3517         if (tokenIs!"{") // "(" ... ")" "{" ...
3518           fstmt = parseFunctionBody();
3519         else if (tokenIs!"=>") // "(" ... ")" "=>" ...
3520         {
3521           e = new LambdaExpr(parameters, parseLambdaExprBody());
3522           break;
3523         }
3524         else
3525           error(token, MID.ExpectedFunctionBody, token.text);
3526         e = new FuncLiteralExpr(parameters, fstmt);
3527       }
3528       else
3529       { // "(" Expression ")"
3530         auto paren = token;
3531         skip!"(";
3532         e = parseExpression();
3533         requireClosing!")"(paren);
3534         e = new ParenExpr(e);
3535       }
3536       break;
3537     version(D2)
3538     {
3539     case T!"__traits":
3540       nT();
3541       auto paren = requireOpening!"(";
3542       auto ident = requireIdentifier(MID.ExpectedAnIdentifier);
3543       auto args = consumed!"," ? parseTemplateArguments2() : null;
3544       requireClosing!")"(paren);
3545       e = new TraitsExpr(ident, args);
3546       break;
3547     } // version(D2)
3548     default:
3549       if (token.isIntegralType)
3550       { // IntegralType . Identifier
3551         auto type = new IntegralType(token.kind);
3552         nT();
3553         set(type, begin);
3554         require2!".";
3555         auto ident = requireIdentifier(MID.ExpectedIdAfterTypeDot);
3556         e = new TypeDotIdExpr(type, ident);
3557       }
3558       else if (token.isSpecialToken)
3559         e = new SpecialTokenExpr(consume());
3560       else
3561       {
3562         error2(MID.ExpectedButFound, "Expression", token);
3563         nT();
3564         e = new IllegalExpr();
3565       }
3566     }
3567     set(e, begin);
3568     return e;
3569   }
3570 
3571   /// $(BNF NewExpr := NewAnonClassExpr | NewObjectExpr
3572   ////NewAnonClassExpr :=
3573   ////  new NewArguments? class NewArguments?
3574   ////  (SuperClass InterfaceClasses)? ClassBody
3575   ////NewObjectExpr := new NewArguments? Type (NewArguments | NewArray)?
3576   ////NewArguments  := "(" ArgumentList ")"
3577   ////NewArray      := "[" AssignExpr "]")
3578   /// Params:
3579   ///   frame = The frame or 'this' pointer expression.
3580   Expression parseNewExpr(Expression frame = null)
3581   {
3582     auto begin = token;
3583     skip!"new";
3584 
3585     Expression e;
3586     Expression[] ctorArguments;
3587 
3588     auto newArguments = tokenIs!"(" ?  parseArguments() : null;
3589 
3590     if (consumed!"class")
3591     { // NewAnonymousClassExpr
3592       if (tokenIs!"(")
3593         ctorArguments = parseArguments();
3594       auto bases = !tokenIs!"{" ? parseBaseClasses() : null;
3595       auto decls = parseDeclarationDefinitionsBody();
3596       e = new NewClassExpr(frame, newArguments, ctorArguments, bases, decls);
3597     }
3598     else
3599     { // NewObjectExpr
3600       auto type = parseType();
3601 
3602       if (type.Is!(ModifierType))
3603       { // Skip modifier types in the chain and search for an ArrayType.
3604         auto t = type;
3605         while ((t = t.next).Is!(ModifierType))
3606         {}
3607         if (auto at = t.Is!(ArrayType))
3608           if (at.isStatic() || at.isAssociative())
3609           {
3610             at.parent.setNext(at.next); // Link it out.
3611             at.setNext(type); // Make it the head type.
3612             type = at;
3613           }
3614       }
3615 
3616       // Don't parse arguments if an array type was parsed previously.
3617       auto arrayType = type.Is!(ArrayType);
3618       if (arrayType && arrayType.isStatic())
3619       {}
3620       else if (arrayType && arrayType.isAssociative())
3621       { // Backtrack to parse as a StaticArray.
3622         auto bracket = type.begin;
3623         backtrackTo(bracket);
3624 
3625         skip!"[";
3626         auto index = parseExpression();
3627         requireClosing!"]"(bracket);
3628         type = set(new ArrayType(type.next, index), bracket);
3629       }
3630       else if (tokenIs!"(") // NewArguments
3631         ctorArguments = parseArguments();
3632       e = new NewExpr(frame, newArguments, type, ctorArguments);
3633     }
3634     return set(e, begin);
3635   }
3636 
3637   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3638   |                          Type parsing methods                           |
3639    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
3640 
3641   /// Parses a Declarator with an optional Identifier.
3642   ///
3643   /// $(BNF DeclaratorOptId := Type (Identifier DeclaratorSuffix)?)
3644   /// Params:
3645   ///   ident = Receives the optional identifier of the declarator.
3646   Type parseDeclaratorOptId(ref Token* ident)
3647   {
3648     auto type = parseType();
3649     ident = optionalIdentifier();
3650     if (ident)
3651       type = parseDeclaratorSuffix(type);
3652     return type;
3653   }
3654 
3655   /// Parses a Declarator with an Identifier.
3656   ///
3657   /// $(BNF Declarator := Type Identifier DeclaratorSuffix)
3658   /// Params:
3659   ///   ident = Receives the identifier of the declarator.
3660   Type parseDeclarator(ref Token* ident)
3661   {
3662     auto type = parseDeclaratorOptId(ident);
3663     if (!ident)
3664       error2(MID.ExpectedDeclaratorIdentifier, token);
3665     return type;
3666   }
3667 
3668   /// Parses a full Type.
3669   ///
3670   /// $(BNF Type := ModAttrType | BasicTypes
3671   ////ModAttrType := Modifier Type
3672   ////Modifier := const | immutable | shared | inout)
3673   Type parseType()
3674   {
3675     version(D2)
3676     if (!nextIs!"(" && token.kind.Any!("const", "immutable", "inout", "shared"))
3677     {
3678       auto mod = consume();
3679       return set(new ModifierType(parseType(), mod, false), mod);
3680     }
3681     return parseBasicTypes();
3682   }
3683 
3684   /// Parses the basic types.
3685   ///
3686   /// $(BNF BasicTypes := BasicType BasicType2)
3687   Type parseBasicTypes()
3688   {
3689     return parseBasicType2(parseBasicType());
3690   }
3691 
3692   /// $(BNF IdentifierType := Identifier | TemplateInstance)
3693   Type parseIdentifierType(Type next = null)
3694   {
3695     auto begin = token;
3696     auto ident = requireIdentifier(MID.ExpectedAnIdentifier);
3697     auto t =  consumed!"!" ?
3698       new TmplInstanceType(next, ident, parseOneOrMoreTemplateArguments()) :
3699       new IdentifierType(next, ident);
3700     return set(t, begin);
3701   }
3702 
3703   /// $(BNF TypeofType   := typeof "(" Expression ")" | TypeofReturn
3704   ////TypeofReturn := typeof "(" return ")")
3705   Type parseTypeofType()
3706   {
3707     auto begin = token;
3708     skip!"typeof";
3709     auto paren = requireOpening!"(";
3710     version(D1)
3711     auto e = parseExpression();
3712     else
3713     auto e = consumed!"return" ? null : parseExpression();
3714     requireClosing!")"(paren);
3715     return set(new TypeofType(e), begin);
3716   }
3717 
3718   /// $(BNF QualifiedType :=
3719   //// (this | super | TypeofType | ModuleScopeType? IdentifierType)
3720   //// ("." IdentifierType)*)
3721   Type parseQualifiedType()
3722   {
3723     auto begin = token;
3724     Type type;
3725 
3726     if (tokenIs!".")
3727       type = set(new ModuleScopeType(), begin, begin);
3728     else if (tokenIs!"typeof")
3729       type = parseTypeofType();
3730     else if (token.kind.Any!("this", "super")) // D2
3731       type = set(new IdentifierType(null, consume()), begin, begin);
3732     else
3733       type = parseIdentifierType();
3734 
3735     while (consumed!".")
3736       type = parseIdentifierType(type);
3737 
3738     return type;
3739   }
3740 
3741   /// $(BNF BasicType := IntegralType | QualifiedType | ModParenType
3742   ////ModParenType := Modifier "(" Type ")")
3743   Type parseBasicType()
3744   {
3745     auto begin = token;
3746     Type t;
3747 
3748     if (token.isIntegralType)
3749     {
3750       t = new IntegralType(token.kind);
3751       nT();
3752     }
3753     else
3754     switch (token.kind)
3755     {
3756     version (D2)
3757     {
3758     case T!"this", T!"super":
3759       goto case T!"Identifier";
3760     }
3761     case T!"Identifier", T!"typeof", T!".":
3762       t = parseQualifiedType();
3763       return t;
3764     version(D2)
3765     { // Modifier "(" Type ")"
3766     case T!"const", T!"immutable", T!"inout", T!"shared":
3767       auto kind = consume();
3768       auto paren = requireOpening!"(";
3769       t = parseType(); // Type
3770       requireClosing!")"(paren);
3771       t = new ModifierType(t, kind, true);
3772       break;
3773     } // version(D2)
3774     default:
3775       error2(MID.ExpectedButFound, "BasicType", token);
3776       t = new IllegalType();
3777       nT();
3778     }
3779     return set(t, begin);
3780   }
3781 
3782   /// $(BNF BasicType2   :=
3783   ////  (PointerType | ArrayType | FunctionType | DelegateType)*
3784   ////PointerType  := "*"
3785   ////FunctionType := function ParameterList
3786   ////DelegateType := delegate ParameterList)
3787   Type parseBasicType2(Type t)
3788   {
3789     while (1)
3790     {
3791       auto begin = token;
3792       switch (token.kind)
3793       {
3794       case T!"*":
3795         t = new PointerType(t);
3796         nT();
3797         break;
3798       case T!"[":
3799         t = parseArrayType(t);
3800         continue;
3801       case T!"function", T!"delegate":
3802         auto kind = consume().kind;
3803         auto parameters = parseParameterList();
3804         version(D2)
3805         parameters.postSTCs = parseFunctionPostfix();
3806         // TODO: add stcs to t.
3807         if (kind == T!"function")
3808           t = new FunctionType(t, parameters);
3809         else
3810           t = new DelegateType(t, parameters);
3811         break;
3812       default:
3813         return t;
3814       }
3815       set(t, begin);
3816     }
3817     assert(0);
3818   }
3819 
3820   /// Parses the array types after the declarator (C-style.) E.g.: int a[]
3821   ///
3822   /// $(BNF DeclaratorSuffix := ArrayType*)
3823   /// Returns: lhsType or a suffix type.
3824   /// Params:
3825   ///   lhsType = The type on the left-hand side.
3826   Type parseDeclaratorSuffix(Type lhsType)
3827   { // The Type chain should be as follows:
3828     // int[3]* Identifier [][1][2]
3829     //   <– <–.      ·start·–> -.
3830     //         `---------------´
3831     // Resulting chain: [][1][2]*[3]int
3832     auto result = lhsType; // Return lhsType if nothing else is parsed.
3833     if (tokenIs!"[")
3834     { // The previously parsed ArrayType.
3835       auto prevType = result = parseArrayType(lhsType);
3836       // Continue parsing ArrayTypes.
3837       while (tokenIs!"[")
3838       {
3839         auto arrayType = parseArrayType(lhsType);
3840         prevType.setNext(arrayType); // Make prevType point to this type.
3841         prevType = arrayType; // Current type becomes previous type.
3842       }
3843     }
3844     return result;
3845   }
3846 
3847   /// $(BNF ArrayType := "[" (Type | ArrayTypeIndex) "]"
3848   ////ArrayTypeIndex := AssignExpr (".." AssignExpr)?)
3849   Type parseArrayType(Type t)
3850   {
3851     auto begin = token;
3852     skip!"[";
3853     if (consumed!"]")
3854       t = new ArrayType(t);
3855     else
3856     {
3857       bool success;
3858       Type parseAAType()
3859       {
3860         auto type = parseType();
3861         require!"]";
3862         return type;
3863       }
3864       auto assocType = tryToParse(&parseAAType, success);
3865       if (success)
3866         t = new ArrayType(t, assocType);
3867       else
3868       {
3869         auto e = parseAssignExpr();
3870         auto e2 = consumed!".." ? parseAssignExpr() : null;
3871         requireClosing!"]"(begin);
3872         t = new ArrayType(t, e, e2);
3873       }
3874     }
3875     return set(t, begin);
3876   }
3877 
3878   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3879   |                        Parameter parsing methods                        |
3880    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
3881 
3882   /// Parses a list of AssignExpressions.
3883   /// $(BNF ExpressionList := AssignExpr ("," AssignExpr)*)
3884   Expression[] parseExpressionList()
3885   {
3886     Expression[] expressions;
3887     do
3888       expressions ~= parseAssignExpr();
3889     while (consumed!",");
3890     return expressions;
3891   }
3892 
3893   /// Parses an optional ExpressionList and allows a trailing comma.
3894   /// $(BNF ExpressionList2 := (ExpressionList ","?)? )
3895   Expression[] parseExpressionList2(TOK closing_tok)
3896   {
3897     Expression[] expressions;
3898     while (token.kind != closing_tok)
3899     {
3900       expressions ~= parseAssignExpr();
3901       if (!consumed!",")
3902         break;
3903     }
3904     return expressions;
3905   }
3906 
3907   /// Parses a list of Arguments.
3908   /// $(BNF Arguments := "(" ExpressionList2 ")")
3909   Expression[] parseArguments()
3910   {
3911     auto paren = token;
3912     skip!"(";
3913     auto args = !tokenIs!")" ? parseExpressionList2(T!")") : null;
3914     requireClosing!")"(paren);
3915     return args;
3916   }
3917 
3918   /// Parses a ParameterList.
3919   /// $(BNF ParameterList := "(" Parameters? ")"
3920   ////Parameters := Parameter ("," Parameter)* ","?
3921   ////Parameter  := StorageClasses? (Type Name? | Type? Name )
3922   ////              ("=" AssignExpr)?)
3923   Parameters parseParameterList()
3924   {
3925     auto paren = requireOpening!"(";
3926     auto params = new Parameters();
3927 
3928     Expression defValue; // Default value.
3929 
3930     while (!tokenIs!")")
3931     {
3932       auto paramBegin = token;
3933       StorageClass stcs, stc; // Storage classes.
3934       Token* stctok; // Token of the last storage class.
3935       Type type; // Type of the parameter.
3936       Token* name; // Name of the parameter.
3937 
3938       void pushParameter()
3939       { // Appends a new Parameter to the list.
3940         auto param = new Parameter(stcs, stctok, type, name, defValue);
3941         params ~= set(param, paramBegin);
3942       }
3943 
3944       if (consumed!"...")
3945         goto LvariadicParam; // Go to common code and leave the loop.
3946 
3947       while (1)
3948       { // Parse storage classes.
3949         switch (token.kind)
3950         {
3951         version(D2)
3952         {
3953         case T!"const", T!"immutable", T!"inout", T!"shared":
3954           if ((stc = getSTC) == 0)
3955             break;
3956           goto Lcommon;
3957         case T!"final":  stc = StorageClass.Final;  goto Lcommon;
3958         case T!"scope":  stc = StorageClass.Scope;  goto Lcommon;
3959         case T!"static": stc = StorageClass.Static; goto Lcommon;
3960         case T!"auto":   stc = StorageClass.Auto;   goto Lcommon;
3961         } // version(D2)
3962         case T!"in":     stc = StorageClass.In;     goto Lcommon;
3963         case T!"out":    stc = StorageClass.Out;    goto Lcommon;
3964         version (D1)
3965         {
3966         case T!"inout":  goto case T!"ref";
3967         }
3968         case T!"ref":    stc = StorageClass.Ref;    goto Lcommon;
3969         case T!"lazy":   stc = StorageClass.Lazy;   goto Lcommon;
3970         Lcommon:
3971           // Check for redundancy.
3972           if (stcs & stc)
3973             error2(MID.RedundantStorageClass, token);
3974           stcs |= stc;
3975           stctok = token;
3976           nT();
3977         version(D2)
3978           continue;
3979         else
3980           break; // In D1.0 the grammar only allows one storage class.
3981         default:
3982         }
3983         break; // Break out of inner loop.
3984       }
3985       type = parseDeclaratorOptId(name);
3986 
3987       if (consumed!"=")
3988         defValue = parseAssignExpr();
3989       else if (defValue !is null) // Parsed a defValue previously?
3990         error(name ? name : type.begin, // Position.
3991           MID.ExpectedParamDefValue,
3992           name ? name.text : ""); // Name.
3993 
3994       if (consumed!"...")
3995       {
3996         if (stcs & (StorageClass.Ref | StorageClass.Out))
3997           error(paramBegin, MID.IllegalVariadicParam);
3998       LvariadicParam:
3999         stcs |= StorageClass.Variadic;
4000         pushParameter();
4001         // TODO: allow trailing comma here? DMD doesn't...
4002         if (!tokenIs!")")
4003           error(token, MID.ParamsAfterVariadic);
4004         break;
4005       }
4006       // Add a non-variadic parameter to the list.
4007       pushParameter();
4008 
4009       if (!consumed!",")
4010         break;
4011     }
4012     requireClosing!")"(paren);
4013     return set(params, paren);
4014   }
4015 
4016   /// $(BNF TemplateArgumentsOneOrMore :=
4017   ////  TemplateArgumentList | TemplateArgumentSingle)
4018   TemplateArguments parseOneOrMoreTemplateArguments()
4019   {
4020     version(D2)
4021     if (!tokenIs!"(")
4022     { // Parse one TArg, but still put it in TemplateArguments.
4023       auto targs = new TemplateArguments;
4024       auto begin = token;
4025       bool success;
4026       // Don't parse a full Type. TODO: restrict further?
4027       auto typeArg = tryToParse(&parseBasicType, success);
4028       // Don't parse a full Expression. TODO: restrict further?
4029       targs ~= success ? typeArg : parsePrimaryExpr();
4030       return set(targs, begin);
4031     } // version(D2)
4032     return parseTemplateArguments();
4033   }
4034 
4035   /// $(BNF TemplateArgumentList := "(" TemplateArguments? ")")
4036   TemplateArguments parseTemplateArguments()
4037   {
4038     TemplateArguments targs;
4039     auto paren = requireOpening!"(";
4040     targs = !tokenIs!")" ? parseTemplateArguments_() : new TemplateArguments;
4041     requireClosing!")"(paren);
4042     return set(targs, paren);
4043   }
4044 
4045   /// $(BNF TemplateArgumentList2 := TemplateArguments (?= "$(RP)"))
4046   TemplateArguments parseTemplateArguments2()
4047   {
4048     version(D2)
4049     {
4050     TemplateArguments targs;
4051     if (!tokenIs!")")
4052       targs = parseTemplateArguments_();
4053     else
4054       error(token, MID.ExpectedTypeOrExpression);
4055     return targs;
4056     } // version(D2)
4057     else
4058     assert(0);
4059   }
4060 
4061   /// Used with method tryToParse().
4062   /// $(BNF TypeArgument := Type (?= "," | "$(RP)"))
4063   Type parseTypeArgument()
4064   {
4065     assert(trying);
4066     auto type = parseType();
4067     if (token.kind.Any!(",", ")"))
4068       return type;
4069     fail_tryToParse();
4070     return null;
4071   }
4072 
4073   /// $(BNF TemplateArguments := TemplateArgument ("," TemplateArgument)*
4074   ////TemplateArgument  := TypeArgument | AssignExpr)
4075   TemplateArguments parseTemplateArguments_()
4076   {
4077     auto begin = token;
4078     auto targs = new TemplateArguments;
4079     while (!tokenIs!")")
4080     {
4081       bool success;
4082       auto typeArgument = tryToParse(&parseTypeArgument, success);
4083       // TemplateArgument := Type | AssignExpr
4084       targs ~= success ? typeArgument : parseAssignExpr();
4085       if (!consumed!",")
4086         break;
4087     }
4088     set(targs, begin);
4089     return targs;
4090   }
4091 
4092   /// $(BNF Constraint := if "(" ConstraintExpr ")")
4093   Expression parseOptionalConstraint()
4094   {
4095     if (!consumed!"if")
4096       return null;
4097     auto paren = requireOpening!"(";
4098     auto e = parseExpression();
4099     requireClosing!")"(paren);
4100     return e;
4101   }
4102 
4103   /// $(BNF TemplateParameterList := "(" TemplateParameters? ")")
4104   TemplateParameters parseTemplateParameterList()
4105   {
4106     auto tparams = new TemplateParameters;
4107     auto paren = requireOpening!"(";
4108     if (!tokenIs!")")
4109       parseTemplateParameterList_(tparams);
4110     requireClosing!")"(paren);
4111     return set(tparams, paren);
4112   }
4113 
4114   /// $(BNF TemplateParameterList2 := "," TemplateParameters "$(RP)")
4115   TemplateParameters parseTemplateParameterList2()
4116   {
4117   version(D2)
4118   {
4119     skip!",";
4120     auto begin = token;
4121     auto tparams = new TemplateParameters;
4122     if (!tokenIs!")")
4123       parseTemplateParameterList_(tparams);
4124     else
4125       error(token, MID.ExpectedTemplateParameters);
4126     return set(tparams, begin);
4127   } // version(D2)
4128   else return null;
4129   }
4130 
4131   /// Parses template parameters.
4132   /// $(BNF TemplateParameters := TemplateParam ("," TemplateParam)*
4133   ////TemplateParam      :=
4134   ////  TemplateAliasParam | TemplateTypeParam | TemplateTupleParam |
4135   ////  TemplateValueParam | TemplateThisParam
4136   ////TemplateAliasParam := alias Identifier SpecOrDefaultType
4137   ////TemplateTypeParam  := Identifier SpecOrDefaultType
4138   ////TemplateTupleParam := Identifier "..."
4139   ////TemplateValueParam := Declarator SpecOrDefaultValue
4140   ////TemplateThisParam  := this Identifier SpecOrDefaultType # D2.0
4141   ////SpecOrDefaultType  := (":" Type)? ("=" Type)?
4142   ////SpecOrDefaultValue := (":" Value)? ("=" Value)?
4143   ////Value := CondExpr
4144   ////)
4145   void parseTemplateParameterList_(TemplateParameters tparams)
4146   {
4147     while (!tokenIs!")")
4148     {
4149       auto paramBegin = token;
4150       TemplateParam tp;
4151       Token* ident;
4152       Type specType, defType;
4153 
4154       void parseSpecAndOrDefaultType()
4155       {
4156         if (consumed!":")  // ":" SpecializationType
4157           specType = parseType();
4158         if (consumed!"=") // "=" DefaultType
4159           defType = parseType();
4160       }
4161 
4162       switch (token.kind)
4163       {
4164       case T!"alias": // TemplateAliasParam := "alias" Identifier
4165         nT();
4166         ident = requireIdentifier(MID.ExpectedAliasTemplateParam);
4167         Node spec, def;
4168         version(D2)
4169         {
4170         Node parseExpOrType()
4171         {
4172           bool success;
4173           auto typeArgument = tryToParse(&parseTypeArgument, success);
4174           return success ? typeArgument : parseCondExpr();
4175         }
4176         if (consumed!":")  // ":" Specialization
4177           spec = parseExpOrType();
4178         if (consumed!"=") // "=" Default
4179           def = parseExpOrType();
4180         } // version(D2)
4181         else
4182         { // D1
4183         parseSpecAndOrDefaultType();
4184         spec = specType;
4185         def = defType;
4186         }
4187         tp = new TemplateAliasParam(ident, spec, def);
4188         break;
4189       case T!"Identifier":
4190         ident = token;
4191         switch (peekNext())
4192         {
4193         case T!"...": // TemplateTupleParam := Identifier "..."
4194           skip!"Identifier"; skip!"...";
4195           if (tokenIs!",")
4196             error(MID.TemplateTupleParameter);
4197           tp = new TemplateTupleParam(ident);
4198           break;
4199         case T!",", T!")", T!":", T!"=": // TemplateTypeParam := Identifier
4200           skip!"Identifier";
4201           parseSpecAndOrDefaultType();
4202           tp = new TemplateTypeParam(ident, specType, defType);
4203           break;
4204         default: // TemplateValueParam := Declarator
4205           ident = null;
4206           goto LTemplateValueParam;
4207         }
4208         break;
4209       version(D2)
4210       {
4211       case T!"this": // TemplateThisParam := "this" TemplateTypeParam
4212         nT();
4213         ident = requireIdentifier(MID.ExpectedNameForThisTempParam);
4214         parseSpecAndOrDefaultType();
4215         tp = new TemplateThisParam(ident, specType, defType);
4216         break;
4217       } // version(D2)
4218       default:
4219       LTemplateValueParam:
4220         // TemplateValueParam := Declarator
4221         auto valueType = parseDeclarator(ident);
4222         // ":" SpecializationValue
4223         auto specValue = consumed!":" ? parseCondExpr() : null;
4224         // "=" DefaultValue
4225         auto defValue = consumed!"=" ? parseCondExpr() : null;
4226         tp = new TemplateValueParam(valueType, ident, specValue, defValue);
4227       }
4228 
4229       // Push template parameter.
4230       tparams ~= set(tp, paramBegin);
4231 
4232       if (!consumed!",")
4233         break;
4234     }
4235   }
4236 
4237   /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4238   |                          Error handling methods                         |
4239    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
4240 
4241   /// Returns the string of a token printable to the client.
4242   cstring getPrintable(Token* token)
4243   { // TODO: there are some other tokens that have to be handled, e.g. strings.
4244     return token.kind == T!"EOF" ? "EOF" : token.text;
4245   }
4246 
4247   alias expected = require;
4248 
4249   /// Requires a token of kind T!str.
4250   void require(string str)()
4251   {
4252     if (!consumed!str)
4253       error2(MID.ExpectedButFound, str, token);
4254   }
4255 
4256   /// Requires a token of kind tok. Uses the token end as the error location.
4257   void require2(string str)()
4258   {
4259     if (!consumed!str)
4260       error2_eL(MID.ExpectedButFound, str, token);
4261   }
4262 
4263   /// Parses an optional identifier.
4264   /// Returns: null or the identifier.
4265   Token* optionalIdentifier()
4266   {
4267     return tokenIs!"Identifier" ? consume() : null;
4268   }
4269 
4270   /// Reports an error if the current token is not an identifier.
4271   /// Params:
4272   ///   mid = The error message ID to be used.
4273   /// Returns: The identifier token or null.
4274   Token* requireIdentifier(MID mid)
4275   {
4276     auto idtok = consumedToken!"Identifier";
4277     if (!idtok)
4278       error(token, mid, token.text);
4279     return idtok;
4280   }
4281 
4282   /// Returns the opening bracket or the current token.
4283   Token* requireOpening(string str)()
4284   {
4285     static assert(str.In("{", "(", "["), "invalid bracket");
4286     if (consumed!str)
4287       return prevToken;
4288     require2!str;
4289     return token;
4290   }
4291 
4292   /// Reports an error if the closing counterpart of a token is not found.
4293   void requireClosing(string str)(Token* opening)
4294   {
4295     static assert(str.In("}", ")", "]"), "invalid bracket");
4296     assert(opening !is null);
4297     if (!consumed!str)
4298     {
4299       auto loc = opening.getErrorLocation(lexer.srcText.filePath);
4300       error(token, MID.ExpectedClosing,
4301         str, opening.text, loc.lineNum, loc.colNum,
4302         getPrintable(token));
4303     }
4304   }
4305 
4306   /// Returns true if the string str has an invalid UTF-8 sequence.
4307   bool hasInvalidUTF8(cbinstr str, Token* begin)
4308   {
4309     auto invalidUTF8Seq = Lexer.findInvalidUTF8Sequence(str);
4310     if (invalidUTF8Seq.length)
4311       error(begin, MID.InvalidUTF8SequenceInString, invalidUTF8Seq);
4312     return invalidUTF8Seq.length != 0;
4313   }
4314 
4315   /// Forwards error parameters.
4316   void error(Token* token, MID mid, ...)
4317   {
4318     error(_arguments, _argptr, token, false, mid);
4319   }
4320   /// ditto
4321   void error(MID mid, ...)
4322   {
4323     error(_arguments, _argptr, this.token, false, mid);
4324   }
4325   /// ditto
4326   void error_eL(MID mid, ...)
4327   {
4328     error(_arguments, _argptr, this.prevToken, true, mid);
4329   }
4330 
4331   /// ditto
4332   void error2(MID mid, Token* token)
4333   {
4334     error(mid, getPrintable(token));
4335   }
4336   /// ditto
4337   void error2(MID mid, string arg, Token* token)
4338   {
4339     error(mid, arg, getPrintable(token));
4340   }
4341   /// ditto
4342   void error2_eL(MID mid, string arg, Token* token)
4343   {
4344     error_eL(mid, arg, getPrintable(token));
4345   }
4346 
4347   /// Creates an error report and appends it to a list.
4348   /// Params:
4349   ///   token = Used to get the location of the error.
4350   ///   endLoc = Get the position of the token's end or start character?
4351   ///   formatMsg = The parser error message.
4352   void error(TypeInfo[] _arguments, va_list _argptr,
4353              Token* token, bool endLoc, cstring formatMsg)
4354   {
4355     if (trying)
4356     {
4357       errorCount++;
4358       return;
4359     }
4360     auto filePath = lexer.srcText.filePath;
4361     auto location = endLoc ?
4362       token.errorLocationOfEnd(filePath) :
4363       token.getErrorLocation(filePath);
4364     auto msg = diag.format(_arguments, _argptr, formatMsg);
4365     auto error = new ParserError(location, msg);
4366     errors ~= error;
4367     diag ~= error;
4368   }
4369   /// ditto
4370   void error(TypeInfo[] _arguments, va_list _argptr,
4371              Token* token, bool endLoc, MID mid)
4372   {
4373     error(_arguments, _argptr, token, endLoc, diag.bundle.msg(mid));
4374   }
4375 }
4376 
4377 /// Returns true if x is in a list of TOK values.
4378 bool Any(Xs...)(TOK x)
4379 {
4380   return In(x, S2T!Xs);
4381 }