From 2802eb20a9b4f8394d17bc47e994906659d1e9f8 Mon Sep 17 00:00:00 2001
From: Hackerpilot <briancschott@gmail.com>
Date: Sat, 22 Jun 2013 17:23:30 -0700
Subject: [PATCH] More work on the parser

---
 std/d/ast.d    | 315 +++++++++++-----------
 std/d/lexer.d  |  13 +-
 std/d/parser.d | 719 ++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 691 insertions(+), 356 deletions(-)

diff --git a/std/d/ast.d b/std/d/ast.d
index 111fbaf..775801f 100755
--- a/std/d/ast.d
+++ b/std/d/ast.d
@@ -251,9 +251,9 @@ class AddExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */TokenType operator;
-	/** */AddExpression left;
-	/** */MulExpression right;
+	/** */ TokenType operator;
+	/** */ AddExpression left;
+	/** */ MulExpression right;
 }
 
 ///
@@ -261,9 +261,9 @@ class AliasDeclaration : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */Type type;
-	/** */Declarator declarator;
-	/** */AliasInitializer[] initializations;
+	/** */ Type type;
+	/** */ Declarator declarator;
+	/** */ AliasInitializer[] initializations;
 }
 
 ///
@@ -271,8 +271,8 @@ class AliasInitializer : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */Token identifier;
-	/** */Type type;
+	/** */ Token identifier;
+	/** */ Type type;
 }
 
 ///
@@ -280,7 +280,7 @@ class AliasThisDeclaration : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */Token identifier;
+	/** */ Token identifier;
 }
 
 ///
@@ -288,7 +288,7 @@ class AlignAttribute : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */Token intLiteral;
+	/** */ Token intLiteral;
 }
 
 ///
@@ -296,8 +296,8 @@ class AndAndExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AndAndExpression left;
-	/** */OrExpression right;
+	/** */ AndAndExpression left;
+	/** */ OrExpression right;
 }
 
 ///
@@ -305,8 +305,8 @@ class AndExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AndExpression andExpression;
-	/** */ShiftExpression shiftExpression;
+	/** */ AndExpression left;
+	/** */ CmpExpression right;
 }
 
 ///
@@ -314,7 +314,7 @@ class ArgumentList : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AssignExpression[] arguments;
+	/** */ AssignExpression[] arguments;
 }
 
 ///
@@ -322,7 +322,7 @@ class Arguments : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ArgumentList argumentList;
+	/** */ ArgumentList argumentList;
 }
 
 ///
@@ -330,7 +330,7 @@ class ArrayInitializer : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ArrayMemberInitialization[] arrayMemberInitializations;
+	/** */ ArrayMemberInitialization[] arrayMemberInitializations;
 }
 
 ///
@@ -338,7 +338,7 @@ class ArrayLiteral : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ArgumentList argumentList;
+	/** */ ArgumentList argumentList;
 }
 
 ///
@@ -346,8 +346,8 @@ class ArrayMemberInitialization : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AssignExpression assignExpression;
-	/** */NonVoidInitializer nonVoidInitializer;
+	/** */ AssignExpression assignExpression;
+	/** */ NonVoidInitializer nonVoidInitializer;
 }
 
 ///
@@ -355,9 +355,9 @@ class AsmAddExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */Token operator;
-	/** */AsmMulExp left;
-	/** */AsmMulExp right;
+	/** */ TokenType operator;
+	/** */ AsmAddExp left;
+	/** */ AsmMulExp right;
 }
 
 ///
@@ -365,8 +365,8 @@ class AsmAndExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmEqualExp left;
-	/** */AsmEqualExp right;
+	/** */ AsmEqualExp left;
+	/** */ AsmEqualExp right;
 }
 
 ///
@@ -374,9 +374,9 @@ class AsmBrExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmBrExp asmBrExp;
-	/** */AsmEqualExp asmEqualExp;
-	/** */AsmUnaExp asmUnaExp;
+	/** */ AsmBrExp asmBrExp;
+	/** */ AsmEqualExp asmEqualExp;
+	/** */ AsmUnaExp asmUnaExp;
 }
 
 ///
@@ -384,9 +384,9 @@ class AsmEqualExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmRelExp left;
-	/** */AsmRelExp right;
-	/** */Token operator;
+	/** */ AsmRelExp left;
+	/** */ AsmRelExp right;
+	/** */ Token operator;
 }
 
 ///
@@ -394,9 +394,9 @@ class AsmExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmLogOrExp left;
-	/** */AsmExp middle;
-	/** */AsmExp right;
+	/** */ AsmLogOrExp left;
+	/** */ AsmExp middle;
+	/** */ AsmExp right;
 }
 
 ///
@@ -404,10 +404,10 @@ class AsmInstruction : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */Token identifierOrIntegerOrOpcode;
-	/** */bool hasAlign;
-	/** */AsmExp asmExp;
-	/** */Operands operands;
+	/** */ Token identifierOrIntegerOrOpcode;
+	/** */ bool hasAlign;
+	/** */ AsmExp asmExp;
+	/** */ Operands operands;
 }
 
 ///
@@ -415,8 +415,8 @@ class AsmLogAndExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmOrExp left;
-	/** */AsmOrExp right;
+	/** */ AsmOrExp left;
+	/** */ AsmOrExp right;
 }
 
 ///
@@ -424,8 +424,8 @@ class AsmLogOrExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmLogAndExp left;
-	/** */AsmLogAndExp right;
+	/** */ AsmLogAndExp left;
+	/** */ AsmLogAndExp right;
 }
 
 ///
@@ -433,9 +433,10 @@ class AsmMulExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmBrExp left;
-	/** */AsmBrExp right;
-	/** */Token operator;
+	/** */ TokenType operator;
+    /** */ AsmMulExp left;
+	/** */ AsmBrExp right;
+
 }
 
 ///
@@ -443,8 +444,8 @@ class AsmOrExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmXorExp left;
-	/** */AsmXorExp right;
+	/** */ AsmXorExp left;
+	/** */ AsmXorExp right;
 }
 
 ///
@@ -452,9 +453,9 @@ class AsmPrimaryExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */IdentifierChain identifierChain;
-	/** */Register register;
-	/** */Token token;
+	/** */ IdentifierChain identifierChain;
+	/** */ Register register;
+	/** */ Token token;
 }
 
 ///
@@ -462,9 +463,9 @@ class AsmRelExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmShiftExp left;
-	/** */AsmShiftExp right;
-	/** */Token operator;
+	/** */ AsmShiftExp left;
+	/** */ AsmShiftExp right;
+	/** */ Token operator;
 }
 
 ///
@@ -472,9 +473,9 @@ class AsmShiftExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmAddExp left;
-	/** */AsmAddExp right;
-	/** */Token operator;
+	/** */ AsmAddExp left;
+	/** */ AsmAddExp right;
+	/** */ Token operator;
 }
 
 ///
@@ -482,7 +483,7 @@ class AsmStatement : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmInstruction[] asmInstructions;
+	/** */ AsmInstruction[] asmInstructions;
 }
 
 ///
@@ -490,8 +491,8 @@ class AsmTypePrefix : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */Token left;
-	/** */Token right;
+	/** */ Token left;
+	/** */ Token right;
 }
 
 ///
@@ -499,11 +500,11 @@ class AsmUnaExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmTypePrefix asmTypePrefix;
-	/** */AsmExp asmExp;
-	/** */Token prefix;
-	/** */AsmPrimaryExp asmPrimaryExp;
-	/** */AsmUnaExp asmUnaExp;
+	/** */ AsmTypePrefix asmTypePrefix;
+	/** */ AsmExp asmExp;
+	/** */ Token prefix;
+	/** */ AsmPrimaryExp asmPrimaryExp;
+	/** */ AsmUnaExp asmUnaExp;
 }
 
 ///
@@ -511,8 +512,8 @@ class AsmXorExp : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AsmAndExp left;
-	/** */AsmAndExp right;
+	/** */ AsmAndExp left;
+	/** */ AsmAndExp right;
 }
 
 ///
@@ -520,8 +521,8 @@ class AssertExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AssignExpression assertion;
-	/** */AssignExpression message;
+	/** */ AssignExpression assertion;
+	/** */ AssignExpression message;
 }
 
 ///
@@ -529,7 +530,7 @@ class AssertStatement : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AssertExpression assertExpression;
+	/** */ AssertExpression assertExpression;
 }
 
 ///
@@ -537,9 +538,9 @@ class AssignExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */TernaryExpression ternaryExpression;
-	/** */AssignExpression assignExpression;
-	/** */TokenType operator;
+	/** */ TernaryExpression ternaryExpression;
+	/** */ AssignExpression assignExpression;
+	/** */ TokenType operator;
 }
 
 ///
@@ -547,11 +548,11 @@ class AssignStatement : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */PreIncDecExpression preIncDecExpression;
-	/** */PostIncDecExpression postIncDecExpression;
-	/** */UnaryExpression[] unaryExpressions;
-	/** */AssignExpression[] assignExpressions;
-	/** */TokenType[] assignOperators;
+	/** */ PreIncDecExpression preIncDecExpression;
+	/** */ PostIncDecExpression postIncDecExpression;
+	/** */ UnaryExpression[] unaryExpressions;
+	/** */ AssignExpression[] assignExpressions;
+	/** */ TokenType[] assignOperators;
 }
 
 ///
@@ -559,7 +560,7 @@ class AssocArrayLiteral : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */KeyValuePairs keyValuePairs;
+	/** */ KeyValuePairs keyValuePairs;
 }
 
 ///
@@ -567,9 +568,9 @@ class AtAttribute : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */FunctionCallExpression functionCallExpression;
-	/** */ArgumentList argumentList;
-	/** */Token identifier;
+	/** */ FunctionCallExpression functionCallExpression;
+	/** */ ArgumentList argumentList;
+	/** */ Token identifier;
 }
 
 ///
@@ -586,8 +587,8 @@ public:
 				visitor.visit(dec);
 		}
 	}
-	/** */Attribute attribute;
-	/** */Declaration[] declarations;
+	/** */ Attribute attribute;
+	/** */ Declaration[] declarations;
 }
 
 ///
@@ -595,12 +596,12 @@ class Attribute : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */LinkageAttribute linkageAttribute;
-	/** */AlignAttribute alignAttribute;
-	/** */PragmaExpression pragmaExpression;
-	/** */Deprecated deprecated_;
-	/** */AtAttribute atAttribute;
-	/** */TokenType attribute;
+	/** */ LinkageAttribute linkageAttribute;
+	/** */ AlignAttribute alignAttribute;
+	/** */ PragmaExpression pragmaExpression;
+	/** */ Deprecated deprecated_;
+	/** */ AtAttribute atAttribute;
+	/** */ TokenType attribute;
 }
 
 ///
@@ -608,9 +609,9 @@ class AutoDeclaration : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */StorageClass storageClass;
-	/** */Token[] identifiers;
-	/** */Initializer[] initializers;
+	/** */ StorageClass storageClass;
+	/** */ Token[] identifiers;
+	/** */ Initializer[] initializers;
 }
 
 ///
@@ -618,7 +619,7 @@ class BlockStatement : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */DeclarationsAndStatements declarationsAndStatements;
+	/** */ DeclarationsAndStatements declarationsAndStatements;
 }
 
 ///
@@ -626,7 +627,7 @@ class BodyStatement : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */BlockStatement blockStatement;
+	/** */ BlockStatement blockStatement;
 }
 
 ///
@@ -660,7 +661,7 @@ class BasicType : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */TokenType type;
+	/** */ TokenType type;
 }
 
 ///
@@ -668,9 +669,9 @@ class CaseRangeStatement : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */AssignExpression low;
-	/** */AssignExpression high;
-	/** */DeclarationsAndStatements declarationsAndStatements;
+	/** */ AssignExpression low;
+	/** */ AssignExpression high;
+	/** */ DeclarationsAndStatements declarationsAndStatements;
 }
 
 ///
@@ -678,8 +679,8 @@ class CaseStatement: ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ArgumentList argumentList;
-	/** */DeclarationsAndStatements declarationsAndStatements;
+	/** */ ArgumentList argumentList;
+	/** */ DeclarationsAndStatements declarationsAndStatements;
 }
 
 ///
@@ -687,9 +688,9 @@ class CastExpression: ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */Type type;
-	/** */CastQualifier castQualifier;
-	/** */UnaryExpression unaryExpression;
+	/** */ Type type;
+	/** */ CastQualifier castQualifier;
+	/** */ UnaryExpression unaryExpression;
 }
 
 ///
@@ -697,9 +698,9 @@ class CastQualifier: ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */TokenType first;
-	/** */TokenType second;
-	/** */bool hasSecond;
+	/** */ TokenType first;
+	/** */ TokenType second;
+	/** */ bool hasSecond;
 }
 
 ///
@@ -758,9 +759,9 @@ class CompileCondition : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */VersionCondition versionCondition;
-	/** */DebugCondition debugCondition;
-	/** */StaticIfCondition staticIfCondition;
+	/** */ VersionCondition versionCondition;
+	/** */ DebugCondition debugCondition;
+	/** */ StaticIfCondition staticIfCondition;
 }
 
 ///
@@ -768,9 +769,9 @@ class ConditionalDeclaration : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */CompileCondition compileCondition;
-	/** */Declaration[] trueDeclarations;
-	/** */Declaration[] falseDeclarations;
+	/** */ CompileCondition compileCondition;
+	/** */ Declaration[] trueDeclarations;
+	/** */ Declaration[] falseDeclarations;
 }
 
 ///
@@ -778,9 +779,9 @@ class ConditionalStatement : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */CompileCondition compileCondition;
-	/** */StatementNoCaseNoDefault trueStatement;
-	/** */StatementNoCaseNoDefault falseStatement;
+	/** */ CompileCondition compileCondition;
+	/** */ StatementNoCaseNoDefault trueStatement;
+	/** */ StatementNoCaseNoDefault falseStatement;
 }
 
 ///
@@ -788,7 +789,7 @@ class Constraint : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */Expression expression;
+	/** */ Expression expression;
 }
 
 ///
@@ -796,8 +797,8 @@ class Constructor : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */Parameters parameters;
-	/** */FunctionBody functionBody;
+	/** */ Parameters parameters;
+	/** */ FunctionBody functionBody;
 }
 
 ///
@@ -991,7 +992,9 @@ class EqualExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	mixin(SHIFT_SHIFT_BODY);
+	/** */ TokenType operator;
+	/** */ ShiftExpression left;
+	/** */ ShiftExpression right;
 }
 
 ///
@@ -999,7 +1002,7 @@ class Expression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ AssignExpression[] assignExpressions;
+	/** */ AssignExpression[] items;
 }
 
 ///
@@ -1140,8 +1143,7 @@ class GotoStatement : ASTNode
 public:
 	mixin(DEFAULT_ACCEPT);
 	/** */ Expression expression;
-	/** */ Token identifier;
-	/** */ bool isDefault;
+	/** */ Token token;
 }
 
 ///
@@ -1182,7 +1184,9 @@ class IdentityExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	mixin(SHIFT_SHIFT_BODY);
+    /** */ bool negated;
+	/** */ ShiftExpression left;
+	/** */ ShiftExpression right;
 }
 
 ///
@@ -1320,7 +1324,8 @@ class KeyValuePair : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ KeyValuePair[] keyValuePairs;
+    /** */ AssignExpression key;
+	/** */ AssignExpression value;
 }
 
 ///
@@ -1328,8 +1333,7 @@ class KeyValuePairs : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ AssignExpression key;
-	/** */ AssignExpression value;
+	/** */ KeyValuePair[] keyValuePairs;
 }
 
 ///
@@ -1433,8 +1437,8 @@ class MulExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ Token operator;
-	/** */ UnaryExpression left;
+	/** */ TokenType operator;
+	/** */ MulExpression left;
 	/** */ UnaryExpression right;
 }
 
@@ -1445,10 +1449,8 @@ public:
 	mixin(DEFAULT_ACCEPT);
 	/** */ Arguments allocatorArguments;
 	/** */ Arguments constructorArguments;
-	/** */ IdentifierList identifierList;
-	/** */ ClassBody ///
-classBody;
-
+	/** */ BaseClassList baseClassList;
+	/** */ ClassBody classBody;
 }
 
 ///
@@ -1541,8 +1543,8 @@ class OrExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ XorExpression xorExpression;
-	/** */ OrExpression orExpression;
+	/** */ OrExpression left;
+    /** */ XorExpression right;
 }
 
 ///
@@ -1550,8 +1552,8 @@ class OrOrExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ OrOrExpression orOrExpression;
-	/** */ AndAndExpression andAndExpression;
+	/** */ OrOrExpression left;
+	/** */ AndAndExpression right;
 }
 
 ///
@@ -1614,8 +1616,8 @@ class PowExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ UnaryExpression unaryExpression;
-	/** */ PowExpression powExpression;
+	/** */ PowExpression left;
+    /** */ UnaryExpression right;
 }
 
 ///
@@ -1650,20 +1652,19 @@ class PrimaryExpression : ASTNode
 public:
 	mixin(DEFAULT_ACCEPT);
 	/** */ Token primary;
-	/** */ bool hasDot;
-    IdentifierOrTemplateInstance identifierOrTemplateInstance;
-    Type type;
-    TypeofExpression typeofExpression;
-    TypeidExpression typeidExpression;
-    ArrayLiteral arrayLiteral;
-    AssocArrayLiteral assocArrayLiteral;
-    Expression expression;
-    IsExpression isExpression;
-    LambdaExpression lambdaExpression;
-    FunctionLiteralExpression functionLiteralExpression;
-    TraitsExpression traitsExpression;
-    MixinExpression mixinExpression;
-    ImportExpression importExpression;
+    /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
+    /** */ Type type;
+    /** */ TypeofExpression typeofExpression;
+    /** */ TypeidExpression typeidExpression;
+    /** */ ArrayLiteral arrayLiteral;
+    /** */ AssocArrayLiteral assocArrayLiteral;
+    /** */ Expression expression;
+    /** */ IsExpression isExpression;
+    /** */ LambdaExpression lambdaExpression;
+    /** */ FunctionLiteralExpression functionLiteralExpression;
+    /** */ TraitsExpression traitsExpression;
+    /** */ MixinExpression mixinExpression;
+    /** */ ImportExpression importExpression;
 }
 
 ///
@@ -1681,7 +1682,9 @@ class RelExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	mixin(SHIFT_SHIFT_BODY);
+    /** */ TokenType operator;
+	/** */ RelExpression left;
+	/** */ ShiftExpression right;
 }
 
 ///
@@ -1722,9 +1725,9 @@ class ShiftExpression : ASTNode
 {
 public:
 	mixin(DEFAULT_ACCEPT);
-	/** */ AddExpression addExpression;
-	/** */ ShiftExpression shiftExpression;
-	/** */ Token operator;
+	/** */ TokenType operator;
+    /** */ ShiftExpression left;
+    /** */ AddExpression right;
 }
 
 ///
diff --git a/std/d/lexer.d b/std/d/lexer.d
index 3a187ef..d12faad 100755
--- a/std/d/lexer.d
+++ b/std/d/lexer.d
@@ -2220,7 +2220,7 @@ private:
 
 // For now a private helper that is tailored to the way lexer works
 // hides away forwardness of range by buffering
-// RA-version is strightforward thin wrapping
+// random-access version is a strightforward thin wrapping
 // ATM it is byte-oriented
 private struct LexSource(R)
     if(isForwardRange!R && !isRandomAccessRange!R)
@@ -3038,21 +3038,20 @@ struct StringCache
         index = new Slot*[startSize];
     }
 
-    string get(R)(R range)
-        if(isRandomAccessRange!R
-            && is(Unqual!(ElementType!R) : const(ubyte)))
+    string get(R)(R range) if (isRandomAccessRange!R
+        && is(Unqual!(ElementType!R) : const(ubyte)))
     {
         uint h = hash(range);
         uint bucket = h & (index.length-1);
         Slot *s = index[bucket];
-        if(s == null)
+        if (s == null)
         {
             string str = putIntoCache(range);
             index[bucket] = allocateSlot(str, h);
             uniqueSlots++;
             return str;
         }
-        for(;;)
+        while (true)
         {
             if(s.hash == h && s.value.equal(range))
                 return s.value;
@@ -3064,7 +3063,7 @@ struct StringCache
         uniqueSlots++;
         // had at least 1 item in this bucket
         // and inserted another one - check load factor
-        if(uniqueSlots*loadDenom > index.length*loadQuot)
+        if (uniqueSlots * loadDenom > index.length * loadQuot)
             rehash();
         return str;
     }
diff --git a/std/d/parser.d b/std/d/parser.d
index 956ba5b..466ca65 100755
--- a/std/d/parser.d
+++ b/std/d/parser.d
@@ -72,11 +72,13 @@ version (unittest) import std.stdio;
 version = development;
 version(development) import std.stdio;
 
+// TODO: any place that says *expect(...) needs to be fixed
+
 /**
-* Params:
-*     tokens = the tokens parsed by std.d.lexer
-* Returns: the parsed module
-*/
+ * Params:
+ *     tokens = the tokens parsed by std.d.lexer
+ * Returns: the parsed module
+ */
 Module parseModule(const(Token)[] tokens)
 {
     auto parser = new Parser();
@@ -99,17 +101,8 @@ struct Parser
      */
     AddExpression parseAddExpression()
     {
-        auto node = new AddExpression;
-        node.right = parseMulExpression();
-        while (currentIsOneOf(TokenType.plus, TokenType.minus, TokenType.tilde))
-        {
-            node.operator = advance().type;
-            auto newNode = new AddExpression;
-            newNode.left = node;
-            newNode.right = parseMulExpression();
-            node = newNode;
-        }
-        return node;
+        return parseLeftAssocBinaryExpression!(AddExpression, MulExpression,
+            TokenType.plus, TokenType.minus, TokenType.tilde)();
     }
 
     /**
@@ -189,17 +182,8 @@ struct Parser
      */
     AndAndExpression parseAndAndExpression()
     {
-        auto node = new AndAndExpression;
-        node.right = parseOrExpression();
-        while (currentIs(TokenType.logicAnd))
-        {
-            advance();
-            auto node2 = new AndAndExpression;
-            node2.left = node;
-            node2.right = parseOrExpression();
-            node = node2;
-        }
-        return node;
+        return parseLeftAssocBinaryExpression!(AndAndExpression, OrExpression,
+            TokenType.logicAnd)();
     }
 
     /**
@@ -212,9 +196,8 @@ struct Parser
      */
     AndExpression parseAndExpression()
     {
-        auto node = new AndExpression;
-        // TODO
-        return node;
+        return parseLeftAssocBinaryExpression!(AndExpression, CmpExpression,
+            TokenType.bitAnd)();
     }
 
     /**
@@ -325,9 +308,8 @@ struct Parser
      */
     AsmAddExp parseAsmAddExp()
     {
-        auto node = new AsmAddExp;
-        // TODO
-        return node;
+        return parseLeftAssocBinaryExpression!(AsmAddExp, AsmMulExp,
+            TokenType.plus, TokenType.minus)();
     }
 
     /**
@@ -598,21 +580,6 @@ struct Parser
         return node;
     }
 
-    /**
-     * Parses an AssertStatement
-     *
-     * $(GRAMMAR $(RULEDEF assertStatement):
-     *     $(RULE assertExpression) $(LITERAL ';')
-     *     ;)
-     */
-    AssertStatement parseAssertStatement()
-    {
-        auto node = new AssertStatement;
-        node.assertExpression = parseAssertExpression();
-        expect(TokenType.semicolon);
-        return node;
-    }
-
     /**
      * Parses an AssignExpression
      *
@@ -658,8 +625,6 @@ struct Parser
      *
      * $(GRAMMAR $(RULEDEF assignStatement):
      *       $(RULE unaryExpression) $(RULE assignOperator) $(RULE assignExpression) ($(LITERAL ',') $(RULE unaryExpression) $(RULE assignOperator) $(RULE assignExpression))* $(LITERAL ';')
-     *     | $(RULE preIncDecExpression) $(LITERAL ';')
-     *     | $(RULE postIncDecExpression) $(LITERAL ';')
      *     ;)
      */
     AssignStatement parseAssignStatement()
@@ -695,7 +660,20 @@ struct Parser
     AtAttribute parseAtAttribute()
     {
         auto node = new AtAttribute;
-        // TODO
+        expect(TokenType.at);
+        with (TokenType) switch (current().type)
+        {
+        case identifier:
+            if (peekIsOneOf(lParen, dot, not))
+                node.functionCallExpression = parseFunctionCallExpression();
+            else
+                node.identifier = advance();
+            break;
+        case lParen:
+            node.argumentlist = parseArgumentList();
+            expect(rParen);
+            break;
+        }
         return node;
     }
 
@@ -883,8 +861,7 @@ struct Parser
      * Parses a BaseClass
      *
      * $(GRAMMAR $(RULEDEF baseClass):
-     *       $(RULE typeofExpression) ($(LITERAL '.') $(RULE identifierOrTemplateChain))?
-     *     | $(RULE identifierOrTemplateChain)
+     *     ($(RULE typeofExpression) $(LITERAL '.'))? $(RULE identifierOrTemplateChain)
      *     ;)
      */
     BaseClass parseBaseClass()
@@ -908,11 +885,7 @@ struct Parser
      */
     BaseClassList parseBaseClassList()
     {
-        auto node = new BaseClassList;
-        do
-            node.baseClasses ~= parseBaseClass();
-        while(currentIs(TokenType.comma));
-        return node;
+        return parseCommaSeparatedRule!(BaseClassList, BaseClass)();
     }
 
     /**
@@ -1300,7 +1273,43 @@ class ClassFour(A, B) if (someTest()) : Super {}};
     CmpExpression parseCmpExpression()
     {
         auto node = new CmpExpression;
-        // TODO
+        auto shift = parseShiftExpression();
+        with (TokenType) switch (current().type)
+        {
+        case is_:
+            node.identityExpression = parseIdentityExpression(shift);
+            break;
+        case in_:
+            node.inExpression = parseInExpression(shift);
+            break;
+        case not:
+            if (peekIs(is_))
+                node.identityExpression = parseIdentityExpression(shift);
+            else if (peekIs(in_))
+                node.inExpression = parseInExpression(shift);
+            break;
+        case less:
+        case lessEqual:
+        case greater:
+        case greaterEqual:
+        case unordered:
+        case notLessEqualGreater:
+        case lessOrGreater:
+        case lessEqualGreater:
+        case notGreater:
+        case notGreaterEqual:
+        case notLess:
+        case notLessEqual:
+            node.relExpression = parseRelExpression(shift);
+            break;
+        case equal:
+        case notEqual:
+            node.equalExpression = parseEqualExpression(shift);
+            break;
+        default:
+            node.shiftExpression = shift;
+            break;
+        }
         return node;
     }
 
@@ -1352,18 +1361,24 @@ class ClassFour(A, B) if (someTest()) : Super {}};
      * Parses an ConditionalStatement
      *
      * $(GRAMMAR $(RULEDEF conditionalStatement):
-     *     $(RULE compileCondition) $(RULE nonEmptyStatementNoCaseNoDefault) ($(LITERAL 'else') $(RULE nonEmptyStatementNoCaseNoDefault))?
+     *     $(RULE compileCondition) $(RULE statementNoCaseNoDefault) ($(LITERAL 'else') $(RULE nonEmptyStatementNoCaseNoDefault))?
      *     ;)
      */
     ConditionalStatement parseConditionalStatement()
     {
         auto node = new ConditionalStatement;
-        // TODO
+        node.compileCondition = parseCompileCondition();
+        node.trueStatement = parseStatementNoCaseNoDefault();
+        if (currentIs(TokenType.else))
+        {
+            advance();
+            node.falseStatement = parseStatementNoCaseNoDefault();
+        }
         return node;
     }
 
     /**
-     * Parses an Constraint
+     * Parses a Constraint
      *
      * $(GRAMMAR $(RULEDEF constraint):
      *     $(LITERAL 'if') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)')
@@ -1635,11 +1650,11 @@ class ClassFour(A, B) if (someTest()) : Super {}};
     }
 
     /**
-     * Parses an DeclarationsAndStatements
+     * Parses DeclarationsAndStatements
      *
-    * $(GRAMMAR $(RULEDEF declarationsAndStatements):
-    *     ($(RULE declaration) | $(RULE statementNoCaseNoDefault))+
-    *     ;)
+     * $(GRAMMAR $(RULEDEF declarationsAndStatements):
+     *     ($(RULE declaration) | $(RULE statementNoCaseNoDefault))+
+     *     ;)
      */
     DeclarationsAndStatements parseDeclarationsAndStatements()
     {
@@ -1722,21 +1737,6 @@ class ClassFour(A, B) if (someTest()) : Super {}};
         return node;
     }
 
-    /**
-     * Parses a DeleteStatement
-     *
-     * $(GRAMMAR $(RULEDEF deleteStatement):
-     *     $(RULE deleteExpression) $(LITERAL ';')
-     *     ;)
-     */
-    DeleteStatement parseDeleteStatement()
-    {
-        auto node = new DeleteStatement;
-        node.deleteExpression = parseDeleteExpression();
-        expect(TokenType.semicolon);
-        return node;
-    }
-
     /**
      * Parses a Deprecated attribute
      *
@@ -1884,10 +1884,13 @@ class ClassFour(A, B) if (someTest()) : Super {}};
      *     $(RULE shiftExpression) ($(LITERAL '==') | $(LITERAL '!=')) $(RULE shiftExpression)
      *     ;)
      */
-    EqualExpression parseEqualExpression()
+    EqualExpression parseEqualExpression(ShiftExpression shift = null)
     {
         auto node = new EqualExpression;
-        // TODO
+        node.left = shift is null ? parseShiftExpression() : shift;
+        if (currentIsOneOf(TokenType.equal, TokenType.notEqual))
+            node.operator = advance().type;
+        node.right = parseShiftExpression();
         return node;
     }
 
@@ -1900,13 +1903,11 @@ class ClassFour(A, B) if (someTest()) : Super {}};
      */
     Expression parseExpression()
     {
-        auto node = new Expression;
-        // TODO
-        return node;
+        return parseCommaSeparatedRule!(AssignExpression)();
     }
 
     /**
-     * Parses an FinalSwitchStatement
+     * Parses a FinalSwitchStatement
      *
      * $(GRAMMAR $(RULEDEF finalSwitchStatement):
      *     $(LITERAL 'final') $(RULE switchStatement)
@@ -1915,7 +1916,8 @@ class ClassFour(A, B) if (someTest()) : Super {}};
     FinalSwitchStatement parseFinalSwitchStatement()
     {
         auto node = new FinalSwitchStatement;
-        // TODO
+        expect(TokenType.final_);
+        node.switchStatement = parseSwitchStatement();
         return node;
     }
 
@@ -1923,13 +1925,14 @@ class ClassFour(A, B) if (someTest()) : Super {}};
      * Parses a Finally
      *
      * $(GRAMMAR $(RULEDEF finally):
-     *     $(LITERAL 'finally') $(RULE nonEmptyStatementNoCaseNoDefault)
+     *     $(LITERAL 'finally') $(RULE statementNoCaseNoDefault)
      *     ;)
      */
     Finally parseFinally()
     {
         auto node = new Finally;
-        // TODO
+        expect(TokenType.finally_);
+        node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
         return node;
     }
 
@@ -1998,9 +2001,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
      */
     ForeachTypeList parseForeachTypeList()
     {
-        auto node = new ForeachTypeList;
-        // TODO
-        return node;
+        return parseCommaSeparatedRule!(ForeachTypeList, ForeachType)();
     }
 
     /**
@@ -2015,7 +2016,18 @@ class ClassFour(A, B) if (someTest()) : Super {}};
     FunctionAttribute parseFunctionAttribute()
     {
         auto node = new FunctionAttribute;
-        // TODO
+        with (TokenType) switch (curent().type)
+        {
+        case at:
+            node.atAttribute = parseAtAttribute();
+            break;
+        case pure_:
+        case nothrow_:
+            node.token = advance();
+            break;
+        default:
+            break;
+        }
         return node;
     }
 
@@ -2110,7 +2122,10 @@ body {} // six
     FunctionCallExpression parseFunctionCallExpression()
     {
         auto node = new FunctionCallExpression;
-        // TODO
+        node.unaryExpression = parseUnaryExpression();
+        if (currentIs(TokenType.not))
+            node.templateArguments = parseTemplateArguments();
+        node.arguments = parseArguments();
         return node;
     }
 
@@ -2124,7 +2139,8 @@ body {} // six
     FunctionCallStatement parseFunctionCallStatement()
     {
         auto node = new FunctionCallStatement;
-        // TODO
+        node.functionCallExpression = parseFunctionCallExpression();
+        expect(TokenType.semicolon);
         return node;
     }
 
@@ -2190,7 +2206,7 @@ body {} // six
     }
 
     /**
-     * Parses an FunctionLiteralExpression
+     * Parses a FunctionLiteralExpression
      *
      * $(GRAMMAR $(RULEDEF functionLiteralExpression):
      *     (($(LITERAL 'function') | $(LITERAL 'delegate')) $(RULE type)?)? ($(RULE parameters) $(RULE functionAttribute)*)? $(RULE functionBody)
@@ -2204,7 +2220,7 @@ body {} // six
     }
 
     /**
-     * Parses an GotoStatement
+     * Parses a GotoStatement
      *
      * $(GRAMMAR $(RULEDEF gotoStatement):
      *     $(LITERAL 'goto') ($(LITERAL Identifier) | $(LITERAL 'default') | $(LITERAL 'case') $(RULE expression)?) $(LITERAL ';')
@@ -2213,7 +2229,19 @@ body {} // six
     GotoStatement parseGotoStatement()
     {
         auto node = new GotoStatement;
-        // TODO
+        expect(TokenType.goto_);
+        with (TokenType) switch (current().type)
+        {
+        case identifier:
+        case default_:
+            node.token = advance();
+            break;
+        case case_:
+            node.token = advance();
+            node.expression = parseExpression();
+            break;
+        }
+        expect(TokenType.semicolon);
         return node;
     }
 
@@ -2321,10 +2349,14 @@ body {} // six
      *     $(RULE shiftExpression) ($(LITERAL 'is') | $(LITERAL '!') $(LITERAL 'is')) $(RULE shiftExpression)
      *     ;)
      */
-    IdentityExpression parseIdentityExpression()
+    IdentityExpression parseIdentityExpression(ShiftExpression shift = null)
     {
         auto node = new IdentityExpression;
-        // TODO
+        node.left = shift is null ? parseShiftExpression() : shift;
+        if (currentIs(TokenType.not))
+            node.negated = true;
+        expect(TokenType.is_);
+        node.right = parseShiftExpression();
         return node;
     }
 
@@ -2338,7 +2370,11 @@ body {} // six
     IfStatement parseIfStatement()
     {
         auto node = new IfStatement;
-        // TODO
+        expect(TokenType.if_);
+        expect(TokenType.lParen);
+        node.expression = parseExpression();
+        expect(TokenType.rParen);
+        node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
         return node;
     }
 
@@ -2513,10 +2549,14 @@ import foo, bar, baz;
      *     $(RULE shiftExpression) ($(LITERAL 'in') | $(LITERAL '!') $(LITERAL 'in')) $(RULE shiftExpression)
      *     ;)
      */
-    InExpression parseInExpression()
+    InExpression parseInExpression(ShiftExpression shift = null)
     {
         auto node = new InExpression;
-        // TODO
+        node.left = shift is null ? parseShiftExpression() : shift;
+        if (currentIs(TokenType.not))
+            advance();
+        expect(TokenType.in_);
+        node.right = parseShiftExpression();
         return node;
     }
 
@@ -2649,16 +2689,47 @@ interface "Four"
      * Parses an Invariant
      *
      * $(GRAMMAR $(RULEDEF invariant):
-     *     $(LITERAL 'invariant') $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)') $(RULE blockStatement)
+     *     $(LITERAL 'invariant') ($(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)'))? $(RULE blockStatement)
      *     ;)
      */
     Invariant parseInvariant()
     {
         auto node = new Invariant;
-        // TODO
+        if (expect(TokenType.invariant_) is null) return null;
+        if (currentIs(TokenType.lParen))
+        {
+            advance();
+            if (expect(TokenType.rParen) is null) return null;
+        }
+        if ((node.blockStatement = parseBlockStatement()) is null) return null;
         return node;
     }
 
+    unittest
+    {
+        auto sourceCode =
+q{invariant() {}
+invariant{}
+invariant() foo();
+}c;
+
+        Parser p = getParserForUnittest(sourceCode, "parseInvariant");
+
+        auto inv1 = p.parseInvariant();
+        assert (inv1 !is null);
+        assert (inv1.blockStatement !is null);
+        assert (p.errorCount == 0);
+
+        auto inv2 = p.parseInvariant();
+        assert (inv2 !is null);
+        assert (inv2.blockStatement !is null);
+        assert (p.errorCount == 0);
+
+        auto inv3 = p.parseInvariant();
+        assert (inv3 is null);
+        assert (p.errorCount > 0);
+    }
+
     /**
      * Parses an IsExpression
      *
@@ -2669,7 +2740,10 @@ interface "Four"
     IsExpression parseIsExpression()
     {
         auto node = new IsExpression;
+        if (expect(TokenType.is_) is null) return null;
+        if (expect(TokenType.lParen) is null) return null;
         // TODO
+        if (expect(TokenType.rParen) is null) return null;
         return node;
     }
 
@@ -2683,7 +2757,9 @@ interface "Four"
     KeyValuePair parseKeyValuePair()
     {
         auto node = new KeyValuePair;
-        // TODO
+        node.key = parseAssignExpression();
+        if (expect(TokenType.colon) is null) return null;
+        node.value = parseAssignExpression();
         return node;
     }
 
@@ -2697,7 +2773,16 @@ interface "Four"
     KeyValuePairs parseKeyValuePairs()
     {
         auto node = new KeyValuePairs;
-        // TODO
+        while (true)
+        {
+            auto kvPair = parseKeyValuePair();
+            if (kvPair !is null)
+                node.keyValuePairs ~= kvPair;
+            if (currentIs(TokenType.comma))
+                advance();
+            else
+                break;
+        }
         return node;
     }
 
@@ -2741,7 +2826,9 @@ interface "Four"
     LastCatch parseLastCatch()
     {
         auto node = new LastCatch;
-        // TODO
+        if (expect(TokenType.catch_) is null) return null;
+        if ((node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault()) is null)
+            return null;;
         return node;
     }
 
@@ -2810,7 +2897,10 @@ interface "Four"
     MixinExpression parseMixinExpression()
     {
         auto node = new MixinExpression;
-        // TODO
+        expect(TokenType.mixin_);
+        expect(TokenType.lParen);
+        node.assignExpression = parseAssignExpression();
+        expect(TokenType.rParen);
         return node;
     }
 
@@ -2824,7 +2914,12 @@ interface "Four"
     MixinTemplateName parseMixinTemplateName()
     {
         auto node = new MixinTemplateName;
-        // TODO
+        if (currentIs(TokenType.typeof_))
+        {
+            node.typeofExpression = parseTypeofExpression();
+            expect(TokenType.dot);
+        }
+        node.identifierOrTemplateChain = parseIdentifierOrTemplateChain();
         return node;
     }
 
@@ -2838,21 +2933,13 @@ interface "Four"
     Module parseModule()
     {
         Module m = new Module;
+        if (currentIs(TokenType.module_))
+            node.moduleDeclaration = parseModuleDeclaration();
         while (moreTokens())
         {
-            switch (current().type)
-            {
-            case TokenType.module_:
-                if (m.moduleDeclaration is null)
-                    m.moduleDeclaration = parseModuleDeclaration();
-                else
-                    error("Only one module declaration is allowed per module");
-                break;
-            default:
-				auto declaration = parseDeclaration();
-				if (declaration !is null)
-					m.declarations ~= declaration;
-            }
+            auto declaration = parseDeclaration();
+            if (declaration !is null)
+                m.declarations ~= declaration;
         }
         return m;
     }
@@ -2882,27 +2969,27 @@ interface "Four"
      */
     MulExpression parseMulExpression()
     {
-        auto node = new MulExpression;
-        auto left = parseUnaryExpression();
-        if (tokens[index] == TokenType.star || tokens[index] == TokenType.div)
-        {
-            node.operator = tokens[index++];
-            node.right = parseUnaryExpression();
-        }
-        return node;
+        return parseLeftAssocBinaryExpression!(MulExpression, UnaryExpression,
+            TokenType.star, TokenType.div, TokenType.mod)();
     }
 
     /**
      * Parses a NewAnonClassExpression
      *
      * $(GRAMMAR $(RULEDEF newAnonClassExpression):
-     *     $(LITERAL 'new') $(RULE arguments)? $(LITERAL 'class') $(RULE arguments)? $(LITERAL Identifier) $(RULE identifierList)? $(RULE classBody)
+     *     $(LITERAL 'new') $(RULE arguments)? $(LITERAL 'class') $(RULE arguments)? $(RULE baseClassList)? $(RULE classBody)
      *     ;)
      */
     NewAnonClassExpression parseNewAnonClassExpression()
     {
         auto node = new NewAnonClassExpression;
-        // TODO
+        expect(TokenType.new_);
+        if (currentIs(TokenType.lParen))
+            node.allocatorArguments = parseArguments();
+        expect(TokenType.class_);
+        if (!currentIs(TokenType.lBrace))
+            node.baseClassList = parseBaseClassList
+        node.classBody = parseClassBody();
         return node;
     }
 
@@ -2917,7 +3004,21 @@ interface "Four"
     NewExpression parseNewExpression()
     {
         auto node = new NewExpression;
-        // TODO
+        if (peekIsOneOf(TokenType.class_ TokenType.lParen))
+            node.newAnonClassExpression = parseNewAnonClassExpression();
+        else
+        {
+            expect(TokenType.new_);
+            node.type = parseType();
+            if (currentIs(TokenType.lBracket))
+            {
+                advance();
+                node.assignExpression = parseAssignExpression();
+                expect(TokenType.rBracket);
+            }
+            else if (currentIs(TokenType.lParen))
+                node.arguments = parseArguments();
+        }
         return node;
     }
 
@@ -2925,7 +3026,7 @@ interface "Four"
      * Parses a NonEmptyStatement
      *
      * $(GRAMMAR $(RULEDEF nonEmptyStatement):
-     *       $(RULE nonEmptyStatementNoCaseNoDefault)
+     *       $(RULE statementNoCaseNoDefault)
      *     | $(RULE caseStatement)
      *     | $(RULE caseRangeStatement)
      *     | $(RULE defaultStatement)
@@ -2934,6 +3035,18 @@ interface "Four"
     NonEmptyStatement parseNonEmptyStatement()
     {
         auto node = new NonEmptyStatement;
+        with (TokenType) switch (current().type)
+        {
+        case default_:
+            node.defaultStatement = parseDefaultStatement();
+            break;
+        case case_:
+            // TODO
+            break;
+        default:
+            node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
+            break;
+        }
         return node;
     }
 
@@ -2964,18 +3077,86 @@ interface "Four"
      *     | $(RULE foreachRangeStatement)
      *     | $(RULE conditionalStatement)
      *     | $(RULE staticAssertStatement)
-     *     | $(RULE assertStatement)
      *     | $(RULE templateMixinStatement)
      *     | $(RULE versionSpecification)
      *     | $(RULE debugSpecification)
-     *     | $(RULE functionCallStatement)
-     *     | $(RULE deleteStatement)
+     *     | $(RULE expressionStatement)
      *     ;)
      */
     StatementNoCaseNoDefault parseStatementNoCaseNoDefault()
     {
         auto node = new StatementNoCaseNoDefault;
-        // TODO
+        with (TokenType) switch (current().type)
+        {
+        case lBrace:
+            node.blockStatement = parseBlockStatement();
+            break;
+        case if_:
+            node.ifStatement = parseIfStatement();
+            break;
+        case while_:
+            node.whileStatement = parseWhileStatement();
+            break;
+        case do_:
+            node.doStatement = parseDoStatement();
+            break;
+        case for_:
+            node.forStatement = parseForStatement();
+            break;
+        case foreach_:
+            // TODO
+            break;
+        case switch_:
+            node.switchStatement = parseSwitchStatement();
+            break;
+        case continue_:
+            node.continueStatement = parseContinueStatement();
+            break;
+        case break_:
+            node.breakStatement = parseBreakStatement();
+            break;
+        case return_:
+            node.returnStatement = parseReturnStatement();
+            break;
+        case goto_:
+            node.gotoStatement = parseGotoStatement();
+            break;
+        case with_:
+            node.withStatement = parseWithStatement();
+            break;
+        case synchronized_:
+            node.synchronizedStatement = parseSynchronizedStatement();
+            break;
+        case try_:
+            node.tryStatement = parseTryStatement();
+            break;
+        case throw_:
+            node.throwStatement = parseThrowStatement();
+            break;
+        case scope_:
+            node.scopeGuardStatement = parseScopeGuardStatement();
+            break;
+        case asm_:
+            node.asmStatement = parseAsmStatement();
+            break;
+        case assert_:
+            node.assertStatement = parseAssertStatement();
+            break;
+        case delete_:
+            node.deleteStatement = parseDeleteStatement();
+            break;
+        default:
+            break;
+        // TODO: assignStatement
+        // TODO: finalSwitchStatement
+        // TODO: foreachRangeStatement
+        // TODO: conditionalStatement
+        // TODO: staticAssertStatement
+        // TODO: templateMixinStatement
+        // TODO: versionSpecification
+        // TODO: debugSpecification
+        // TODO: functionCallStatement
+        }
         return node;
     }
 
@@ -2991,11 +3172,10 @@ interface "Four"
     NonVoidInitializer parseNonVoidInitializer()
     {
         auto node = new NonVoidInitializer;
-        // TODO
-		if (curentIs(TokenType.lBrace))
-			node.structInitializer = parseStructInitializer()
+		if (currentIs(TokenType.lBrace))
+			node.structInitializer = parseStructInitializer();
 		else if (currentIs(TokenType.lBracket))
-			node.arrayInitializer = parseArrayInitializer()
+			node.arrayInitializer = parseArrayInitializer();
 		else
 			node.assignExpression = parseAssignExpression();
         return node;
@@ -3025,9 +3205,8 @@ interface "Four"
      */
     OrExpression parseOrExpression()
     {
-        auto node = new OrExpression;
-        // TODO
-        return node;
+        return parseLeftAssocBinaryExpression!(OrExpression, XorExpression,
+            TokenType.bitOr)();
     }
 
     /**
@@ -3040,10 +3219,8 @@ interface "Four"
      */
     OrOrExpression parseOrOrExpression()
     {
-        auto node = new OrOrExpression;
-        node.andAndExpression = parseAndAndExpression();
-
-        return node;
+        return parseLeftAssocBinaryExpression!(OrOrExpression, AndAndExpression,
+            TokenType.logicOr)();
     }
 
     /**
@@ -3128,7 +3305,11 @@ interface "Four"
     Postblit parsePostblit()
     {
         auto node = new Postblit;
-        // TODO
+        expect(TokenType.this_);
+        expect(TokenType.lParen);
+        expect(TokenType.this_);
+        expect(TokenType.rParen);
+        node.functionBody = parseFunctionBody();
         return node;
     }
 
@@ -3139,10 +3320,11 @@ interface "Four"
      *     $(RULE unaryExpression) ($(LITERAL '++') | $(LITERAL '--'))
      *     ;)
      */
-    PostIncDecExpression parsePostIncDecExpression()
+    PostIncDecExpression parsePostIncDecExpression(UnaryExpression unary = null)
     {
         auto node = new PostIncDecExpression;
-        // TODO
+        node.unaryExpression = unary is null ? parseUnaryExpression() : unary;
+        node.operator = advance();
         return node;
     }
 
@@ -3156,9 +3338,8 @@ interface "Four"
      */
     PowExpression parsePowExpression()
     {
-        auto node = new PowExpression;
-        // TODO
-        return node;
+        return parseLeftAssocBinaryExpression!(PowExpression, UnaryExpression,
+            TokenType.pow)();
     }
 
     /**
@@ -3171,7 +3352,8 @@ interface "Four"
     PragmaDeclaration parsePragmaDeclaration()
     {
         auto node = new PragmaDeclaration;
-        // TODO
+        node.pragmaExpression = parsePragmaExpression();
+        expect(TokenType.semicolon);
         return node;
     }
 
@@ -3185,7 +3367,17 @@ interface "Four"
     PragmaExpression parsePragmaExpression()
     {
         auto node = new PragmaExpression;
-        // TODO
+        expect(TokenType.pragma_);
+        expect(TokenType.lParen);
+        auto ident = expect(TokenType.identifier);
+        if (ident is null) return null;
+        node.identifier = *ident;
+        if (currentIs(TokenType.comma))
+        {
+            advance();
+            node.argumentList = parseArgumentList();
+        }
+        expect(TokenType.rParen);
         return node;
     }
 
@@ -3199,7 +3391,14 @@ interface "Four"
     PreIncDecExpression parsePreIncDecExpression()
     {
         auto node = new PreIncDecExpression;
-        // TODO
+        if (currentIsOneOf(TokenType.increment, TokenType.decrement))
+            advance();
+        else
+        {
+            error(`"++" or "--" expected`);
+            return null;
+        }
+        node.unaryExpression = parseUnaryExpression();
         return node;
     }
 
@@ -3245,7 +3444,50 @@ interface "Four"
     PrimaryExpression parsePrimaryExpression()
     {
         auto node = new PrimaryExpression;
-        // TODO
+        with (TokenType) switch (current().type)
+        {
+        case identifier:
+            // TODO
+            // symbol or type.identifier
+            break;
+        case typeof_:
+            node.typeofExpression = parseTypeofExpression();
+            break;
+        case typeid_:
+            node.typeidExpression = parseTypeidExpression();
+            break;
+        case lBracket:
+            // TODO: array literal or associative array literal
+            break;
+        case lParen:
+            advance();
+            node.expression = parseExpression();
+            expect(TokenType.rParen);
+            break;
+        case is_:
+            node.isExpression = parseIsExpression();
+            break;
+        // TODO: lambda
+        // TODO: function literal
+        case traits:
+            node.traitsExpression = parseTraitsExpression();
+            break;
+        case mixin_:
+            node.mixinExpression = parseMixinExpression();
+            break;
+        case import_:
+            node.importExpression = parseImportExpression();
+            break;
+        case dollar:
+        case this_:
+        case null_:
+        case true_:
+        case false_:
+        case specialDate: .. case specialPrettyFunction:
+        case doubleLiteral: .. case wstringLiteral:
+            primary = advance();
+            break;
+        }
         return node;
     }
 
@@ -3260,7 +3502,13 @@ interface "Four"
     Register parseRegister()
     {
         auto node = new Register;
-        // TODO
+        node.identifier = *expect(TokenType.identifier);
+        if (currentIs(TokenType.lParen))
+        {
+            advance();
+            node.intLiteral = *expect(TokenType.intLiteral);
+            expect(TokenType.rParen);
+        }
         return node;
     }
 
@@ -3286,11 +3534,15 @@ interface "Four"
      *     | $(LITERAL '!<=')
      *     ;)
      */
-    RelExpression parseRelExpression()
+    RelExpression parseRelExpression(ShiftExpression shift = null)
     {
-        auto node = new RelExpression;
-        // TODO
-        return node;
+        return parseLeftAssocBinaryExpression!(RelExpression, ShiftExpression,
+            TokenType.less, TokenType.lessEqual, TokenType.greater,
+            TokenType.greaterEqual, TokenType.unordered,
+            TokenType.notLessEqualGreater, TokenType.lessOrGreater,
+            TokenType.lessEqualGreater, TokenType.notGreater,
+            TokenType.notGreaterEqual, TokenType.notLess,
+            TokenType.notLessEqual)(shift);
     }
 
     /**
@@ -3314,13 +3566,17 @@ interface "Four"
      * Parses a ScopeGuardStatement
      *
      * $(GRAMMAR $(RULEDEF scopeGuardStatement):
-     *     $(LITERAL 'scope') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
+     *     $(LITERAL 'scope') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) $(LITERAL '$(RPAREN)') $(RULE statementNoCaseNoDefault)
      *     ;)
      */
     ScopeGuardStatement parseScopeGuardStatement()
     {
         auto node = new ScopeGuardStatement;
-        // TODO
+        expect(TokenType.scope_);
+        expect(TokenType.lParen);
+        node.identifier = *expect(TokenType.identifier);
+        expect(TokenType.rParen);
+        node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
         return node;
     }
 
@@ -3334,7 +3590,12 @@ interface "Four"
     SharedStaticConstructor parseSharedStaticConstructor()
     {
         auto node = new SharedStaticConstructor;
-        // TODO
+        expect(TokenType.shared_);
+        expect(TokenType.static_);
+        expect(TokenType.this_);
+        expect(TokenType.lParen);
+        expect(TokenType.rParen);
+        node.functionBody = parseFunctionBody();
         return node;
     }
 
@@ -3348,7 +3609,13 @@ interface "Four"
     SharedStaticDestructor parseSharedStaticDestructor()
     {
         auto node = new SharedStaticDestructor;
-        // TODO
+        expect(TokenType.shared_);
+        expect(TokenType.static_);
+        expect(TokenType.tilde);
+        expect(TokenType.this_);
+        expect(TokenType.lParen);
+        expect(TokenType.rParen);
+        node.functionBody = parseFunctionBody();
         return node;
     }
 
@@ -3362,9 +3629,9 @@ interface "Four"
      */
     ShiftExpression parseShiftExpression()
     {
-        auto node = new ShiftExpression;
-        // TODO
-        return node;
+        return parseLeftAssocBinaryExpression!(ShiftExpression, AddExpression,
+            TokenType.shiftLeft, TokenType.shiftRight,
+            TokenType.unsignedShiftRight)();
     }
 
     /**
@@ -3545,7 +3812,7 @@ interface "Four"
 		version (development)
 			skipBraceContent();
 		else
-			assert (0);
+			static assert (0);
         //while (tokens[index] != TokenType.rBrace && moreTokens())
         //    node.structBodyItems ~= parseStructBodyItem();
         expect(TokenType.rBrace);
@@ -3564,7 +3831,12 @@ interface "Four"
     StructBodyItem parseStructBodyItem()
     {
         auto node = new StructBodyItem;
-
+        if (currentIs(TokenType.invariant_))
+            node.invariant_ = parseInvariant();
+        else if (startsWith(TokenType.this_, TokenType.lParen, TokenType.this_))
+            node.postBlit = parsePostblit();
+        else
+            node.declaration = parseDeclaration();
         return node;
     }
 
@@ -3668,7 +3940,7 @@ interface "Four"
     }
 
     /**
-     * Parses an SwitchStatement
+     * Parses a SwitchStatement
      *
      * $(GRAMMAR $(RULEDEF switchStatement):
      *     $(LITERAL 'switch') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE switchBody)
@@ -3705,7 +3977,7 @@ interface "Four"
     }
 
     /**
-     * Parses an SynchronizedStatement
+     * Parses a SynchronizedStatement
      *
      * $(GRAMMAR $(RULEDEF synchronizedStatement):
      *     $(LITERAL 'synchronized') ($(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)'))? $(RULE nonEmptyStatementNoCaseNoDefault)
@@ -3726,7 +3998,7 @@ interface "Four"
     }
 
     /**
-     * Parses an TemplateAliasParameter
+     * Parses a TemplateAliasParameter
      *
      * $(GRAMMAR $(RULEDEF templateAliasParameter):
      *     $(LITERAL 'alias') $(RULE type)? $(LITERAL Identifier) ($(LITERAL ':') ($(RULE type) | $(RULE expression)))? ($(LITERAL '=') ($(RULE type) | $(RULE expression)))?
@@ -3735,6 +4007,7 @@ interface "Four"
     TemplateAliasParameter parseTemplateAliasParameter()
     {
         auto node = new TemplateAliasParameter;
+        expect(TokenType.alias_);
         // TODO
         return node;
     }
@@ -3764,9 +4037,7 @@ interface "Four"
      */
     TemplateArgumentList parseTemplateArgumentList()
     {
-        auto node = new TemplateArgumentList;
-        // TODO
-        return node;
+        return parseCommaSeparatedRule!(TemplateArgumentList, TemplateArgument)();
     }
 
     /**
@@ -3779,12 +4050,20 @@ interface "Four"
     TemplateArguments parseTemplateArguments()
     {
         auto node = new TemplateArguments;
-        // TODO
+        expect(TokenType.not);
+        if (currentIs(TokenType.lParen))
+        {
+            advance();
+            node.templateArgumentList = parseTemplateArgumentList();
+            expect(TokenType.rParen);
+        }
+        else
+            node.templateSingleArgument = parseTemplateSingleArgument();
         return node;
     }
 
     /**
-     * Parses an TemplateDeclaration
+     * Parses a TemplateDeclaration
      *
      * $(GRAMMAR $(RULEDEF templateDeclaration):
      *     $(LITERAL 'template') $(LITERAL Identifier) $(RULE templateParameters) $(RULE constraint)? $(LITERAL '{') $(RULE declaration)+ $(LITERAL '}')
@@ -3793,7 +4072,16 @@ interface "Four"
     TemplateDeclaration parseTemplateDeclaration()
     {
         auto node = new TemplateDeclaration;
-        // TODO
+        expect(TokenType.template_);
+        node.identifier = *expect(TokenType.identifier);
+        node.templateParameters = parseTemplateParameters();
+        if (currentIs(TokenType.if_));
+            node.constraint = parseConstraint();
+        expect(TokenType.lBrace);
+        do
+            node.declarations ~= parseDeclaration();
+        while (!currentIs(TokenType.rBrace))
+        expect(TokenType.rBrace);
         return node;
     }
 
@@ -3801,13 +4089,14 @@ interface "Four"
      * Parses a TemplateInstance
      *
      * $(GRAMMAR $(RULEDEF templateInstance):
-     *     $(LITERAL Identifier) $(RULE templateArguments)
+     *     $(LITERAL symbol) $(RULE templateArguments)
      *     ;)
      */
     TemplateInstance parseTemplateInstance()
     {
         auto node = new TemplateInstance;
-        // TODO
+        node.symbol = parseSymbol();
+        node.templateArguments = parseTemplateArguments();
         return node;
     }
 
@@ -3875,7 +4164,7 @@ interface "Four"
     }
 
     /**
-     * Parses an TemplateSingleArgument
+     * Parses a TemplateSingleArgument
      *
      * $(GRAMMAR $(RULEDEF templateSingleArgument):
      *       $(RULE builtinType)
@@ -3908,7 +4197,7 @@ interface "Four"
     }
 
     /**
-     * Parses an TemplateThisParameter
+     * Parses a TemplateThisParameter
      *
      * $(GRAMMAR $(RULEDEF templateThisParameter):
      *     $(LITERAL 'this') $(RULE templateTypeParameter)
@@ -3973,7 +4262,20 @@ interface "Four"
     TemplateValueParameterDefault parseTemplateValueParameterDefault()
     {
         auto node = new TemplateValueParameterDefault;
-        // TODO
+        expect(TokenType.assign);
+        with (TokenType) switch (current().type)
+        {
+        case specialFile:
+        case specialModule:
+        case specialLine:
+        case specialFunction:
+        case specialPrettyFunction:
+            node.token = advance();
+            break;
+        default:
+            node.assignExpression = parseAssignExpression();
+            break;
+        }
         return node;
     }
 
@@ -4018,7 +4320,7 @@ interface "Four"
      * Parses an TraitsArgument
      *
      * $(GRAMMAR $(RULEDEF traitsArgument):
-     *     $(RULE assignExpression)
+     *       $(RULE assignExpression)
      *     | $(RULE type)
      *     ;)
      */
@@ -4257,7 +4559,6 @@ interface "Four"
      * $(GRAMMAR $(RULEDEF typeidExpression):
      *     $(LITERAL 'typeid') $(LITERAL '$(LPAREN)')($(RULE type) | $(RULE expression)) $(LITERAL '$(RPAREN)')
      *     ;)
-
      */
     TypeidExpression parseTypeidExpression()
     {
@@ -4526,9 +4827,8 @@ interface "Four"
      */
     XorExpression parseXorExpression()
     {
-        auto node = new XorExpression;
-        // TODO
-        return node;
+        return parseLeftAssocBinaryExpression!(XorExpression, AndExpression,
+            TokenType.xor)();
     }
 
     private bool currentIsMemberFunctionAttribute() const
@@ -4548,6 +4848,39 @@ interface "Four"
         }
     }
 
+    private Left parseLeftAssocBinaryExpression(alias Left, alias Right, Operators ...)
+        (Right r = null)
+    {
+        auto node = new Left;
+        mixin ("node.right = r is null ? parse" ~ Right.stringof ~ "() : r;");
+        while (currentIsOneOf(Operators))
+        {
+            static if (__traits(hasMember, Left, "operator"))
+                node.operator = advance().type;
+            else
+                advance();
+            auto newNode = new Left;
+            newNode.left = node;
+            mixin ("newNode.right = parse" ~ Right.stringof ~ "();");
+            node = newNode;
+        }
+        return node;
+    }
+
+    private ListType parseCommaSeparatedRule(alias ListType, alias ItemType)()
+    {
+        auto node = new ListType;
+        while (true)
+        {
+            mixin ("node.items ~= parse" ~ ItemType.stringof ~ "();");
+            if (currentIs(TokenType.comma))
+                advance();
+            else
+                break;
+        }
+        return node;
+    }
+
     void error(lazy string message)
     {
         import std.stdio;