diff src/expression/expression_apd.d @ 1:4a9dcbd9e54f

-files of 0.13 beta -fixes so that it now compiles with the current dmd version
author marton@basel.hu
date Tue, 05 Apr 2011 20:44:01 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/expression/expression_apd.d	Tue Apr 05 20:44:01 2011 +0200
@@ -0,0 +1,4376 @@
+// Written in the D programming language
+
+/*
+ *  This file has been automatically generated by APaGeD v0.4.2 beta - Attributed Parser Generator for D.
+ *
+ *  Sections generated from custom input are marked as "generated code" and
+ *  are subject to the terms and conditions stated in one of these sections.
+ *  The remaining sections are part of the APaGeD package and subject
+ *  to the terms and conditions of the corresponding license.
+ *
+ *  Attributed Parser Generator for D
+ *  Copyright (c) 2007 Jascha Wetzel. All rights reserved
+ *  License: Artistic License 2.0
+ */
+
+// generated code start
+
+#line 12 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+module expression.expression_apd;
+    
+import codeview.decl;
+import codeview.codeview;
+import expression.evaluationcontext;
+import expression.datahandler;
+import util;
+
+//import internal.aaA;
+
+	struct aaA
+	{
+	    aaA *left;
+	    aaA *right;
+	    hash_t hash;
+	    /* key   */
+	    /* value */
+	}
+
+        struct BB
+	{
+	    aaA*[] b;
+	    size_t nodes;       // total number of aaA nodes
+	}
+
+import std.demangle;
+import std.stdio;
+
+import win32.winnt;
+
+/**********************************************************************************************
+
+**********************************************************************************************/
+bool castArrayIndex(ubyte[] data, string type, out size_t index)
+{
+    assert(type.length>0);
+    switch ( type[0] )
+    {
+        case 'a':
+            if ( *cast(char*)data.ptr < 0 )
+                throw new EvaluationException("Cannot access array with negative index");
+        case 'h':
+            index = *cast(ubyte*)data.ptr;
+            return true;
+        case 's':
+            if ( *cast(short*)data.ptr < 0 )
+                throw new EvaluationException("Cannot access array with negative index");
+        case 't':
+            index = *cast(ushort*)data.ptr;
+            return true;
+        case 'i':
+            if ( *cast(int*)data.ptr < 0 )
+                throw new EvaluationException("Cannot access array with negative index");
+        case 'k':
+            index = *cast(uint*)data.ptr;
+            return true;
+        case 'l':
+            if ( *cast(long*)data.ptr < 0 )
+                throw new EvaluationException("Cannot access array with negative index");
+        case 'm':
+            index = cast(size_t)*cast(ulong*)data.ptr;
+            return true;
+        default:
+    }
+    return false;
+}
+
+/**********************************************************************************************
+
+**********************************************************************************************/
+//    debug = parser;
+unittest
+{
+    bool test(string expr)
+    {
+        SyntaxTree* root;
+        bool success;
+        try success = parse(expr, root);
+        catch ( ParserException e ) {
+            debug(parser) writefln("%s", e.toString);
+            return false;
+        }
+        return success;
+    }
+
+    assert(test("a.bc"));
+    assert(test("bc[def..ghij]"));
+    assert(!test("\"a\\\"\\\u2f85qwe '\""));
+    assert(test("a.bc[def..ghij].klmno.pqrstu[0..'a'][\"a\\\"\\u2f85qwe '\"]"));
+    assert(!test("a.bc.[def..ghij]"));
+    assert(!test("[def..ghij]"));
+    assert(!test("a."));
+    assert(test("asdf[0][i].qwer"));
+    assert(test("cast(uint)asdf"));
+    assert(test("(cast(mystruct)asdf).qwer"));
+    assert(test("(cast(string[])asdf)[0][2..13]"));
+    assert(test("(cast(char[string])asdf)[\"qwer\"]"));
+    assert(!test("(cast(mystruct)asdf).(cast(char[][])qwer)[0]"));
+    assert(test("cast(float)asdf.qwer"));
+    assert(!test("cast.qwer"));
+    assert(!test("cast(uint).qwer"));
+    assert(!test("cast(asdf.qwer).qwer"));
+    assert(test("(cast(string)mystruct.tzui)[0..4]"));
+    assert(test("cast(Vec!(float,3))mystruct"));
+    assert(test("cast(Vec!(float,3,\"asdf\",Vec!(float)))mystruct"));
+    assert(test("vertices[inds[10193]].y"));
+    assert(test("*cast(uint*)#eax"));
+}
+// generated code end
+
+version(Tango)
+{
+  
+}
+else
+{
+    import std.string;
+    debug import std.stdio;
+}
+
+/**************************************************************************************************
+    Semantic Analyzer
+**************************************************************************************************/
+
+class SemanticException : Exception
+{
+    this(string msg)
+    {
+        super(msg);
+    }
+}
+
+struct SyntaxTree
+{
+    uint            _ST_rule,
+                    _ST_line_number,
+                    _ST_column_number;
+    debug
+    {
+        string          _ST_node_name,
+                        _ST_match,
+                        _ST_match_ws;
+        SyntaxTree*[]   _ST_children;
+    }
+    else
+    {
+        union
+        {
+            struct {
+                string      _ST_match,
+                            _ST_match_ws;
+            }
+            SyntaxTree*[]   _ST_children;
+        }
+    }
+
+    debug
+    {
+        SyntaxTree* parent;
+
+        string indent()
+        {
+            string str;
+            for ( SyntaxTree* n = parent; n !is null; n = n.parent )
+                str ~= "  ";
+            return str;
+        }
+
+        void print(string indent = "")
+        {
+            version(Tango)
+                Stdout.format("{}{}{}", indent, _ST_node_name, _ST_rule);
+            else
+                writef("%s%s%d", indent, _ST_node_name, _ST_rule);
+            if ( _ST_children.length == 0 )
+            {
+                version(Tango)
+                    Stdout.formatln(" (\"{}\")", _ST_match);
+                else
+                    writefln(" (\"%s\")", _ST_match);
+            }
+            else
+            {
+                version(Tango)
+                    Stdout.newline;
+                else
+                    writefln;
+            }
+            foreach ( c; _ST_children )
+                c.print(indent~"  ");
+        }
+    }
+
+    void opCatAssign(SyntaxTree* n)
+    {
+        _ST_children ~= n;
+    }
+
+    // augmented semantic code
+// generated code start
+    alias _S_Expr Expr;
+void _S_Expr(EvaluationContext ctx, out SymbolData symdata)
+{
+
+    switch ( _ST_rule )
+    {
+    case 0:
+        debug assert(_ST_children.length == 3);
+        void delegate(EvaluationContext ctx, ref SymbolData symdata) Deref = &_ST_children[0]._S_Deref;
+        void delegate(EvaluationContext ctx, ref SymbolData symdata) Cast = &_ST_children[1]._S_Cast;
+        void delegate(EvaluationContext ctx, out SymbolData symdata) DotChain = &_ST_children[2]._S_DotChain;
+
+#line 136 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        DotChain(ctx, symdata);
+        Cast(ctx, symdata);
+        Deref(ctx, symdata);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_Deref(EvaluationContext ctx, ref SymbolData symdata)
+{
+
+    switch ( _ST_rule )
+    {
+    case 1:
+        debug assert(_ST_children.length == 1);
+        void delegate(EvaluationContext ctx, ref SymbolData symdata) Deref = &_ST_children[0]._S_Deref;
+
+#line 146 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        if ( symdata is null )
+            throw new EvaluationException("Invalid data for dereferencing");
+        if ( symdata.type[0] != 'P' )
+            throw new EvaluationException("Cannot dereference non-pointer of type "~demangleType(symdata.type));
+        symdata.type = symdata.type[1..$];
+        assert(symdata.type.length>0);
+        ubyte[] data = symdata.getData(ctx);
+        if ( data.length != size_t.sizeof ) {
+            throw new EvaluationException("Invalid pointer data size = "~.toString(data.length));
+        }
+        symdata.ptr = (cast(size_t[])data)[0];
+        symdata.len = ctx.codeView.sizeofMangled(symdata.type);
+        symdata.defered_load = true;
+
+        Deref(ctx, symdata);
+        break;
+    case 2:
+        debug assert(_ST_children.length == 0);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_DotChain(EvaluationContext ctx, out SymbolData symdata)
+{
+
+    switch ( _ST_rule )
+    {
+    case 3:
+        debug assert(_ST_children.length == 1);
+        void delegate(EvaluationContext ctx, out SymbolData symdata) Register = &_ST_children[0]._S_Register;
+
+#line 170 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        Register(ctx, symdata);
+        break;
+    case 4:
+        debug assert(_ST_children.length == 2);
+        void delegate(EvaluationContext ctx, out SymbolData symdata) Expr = &_ST_children[0]._S_Expr;
+        void delegate(EvaluationContext ctx, NamedSymbol symbol, NamedSymbol[] symbols, string prefix, ref SymbolData symdata) RefExpr = &_ST_children[1]._S_RefExpr;
+
+#line 178 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        Expr(ctx, symdata);
+        RefExpr(ctx, null, null, "", symdata);
+        break;
+    case 5:
+        debug assert(_ST_children.length == 2);
+        void delegate(out string id) Ident = &_ST_children[0]._S_Ident;
+        void delegate(EvaluationContext ctx, NamedSymbol symbol, NamedSymbol[] symbols, string prefix, ref SymbolData symdata) RefExpr = &_ST_children[1]._S_RefExpr;
+
+#line 185 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        string id;
+        Ident(id);
+
+        NamedSymbol[] symbols;
+        NamedSymbol symbol = ctx.findSymbol(id, symbols);
+        if ( symbol !is null )
+            symdata = ctx.loadSymbolData(symbol);
+        else
+            debug DbgIO.println("symbol %s not found", id);
+        RefExpr(ctx, symbol, symbols, id, symdata);
+        break;
+    case 6:
+        debug assert(_ST_children.length == 1);
+        void delegate(out SymbolData litdata) Lit = &_ST_children[0]._S_Lit;
+
+#line 199 "D:\src\ddbg_continued\src\expression\expression.apd"
+ Lit(symdata);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_RefExpr(EvaluationContext ctx, NamedSymbol symbol, NamedSymbol[] symbols, string prefix, ref SymbolData symdata)
+{
+
+    switch ( _ST_rule )
+    {
+    case 7:
+        debug assert(_ST_children.length == 2);
+        void delegate(out string id) Ident = &_ST_children[0]._S_Ident;
+        void delegate(EvaluationContext ctx, NamedSymbol symbol, NamedSymbol[] symbols, string prefix, ref SymbolData symdata) RefExpr = &_ST_children[1]._S_RefExpr;
+
+#line 208 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        string id;
+        Ident(id);
+        prefix ~= "."~id;
+
+        if ( symdata is null )
+        {
+            symbol = ctx.findSymbol(prefix, symbols);
+            if ( symbol !is null )
+                symdata = ctx.loadSymbolData(symbol);
+        }
+        else
+        {
+			switch ( symdata.type[0] )
+			{
+				//---------------------------------------------------------------------------------
+				// primitive types
+				case 'v': case 'b': case 'x': case 'g': case 'h': case 's':	case 't': case 'i': case 'k': case 'l': case 'm': case 'f':
+				case 'd': case 'e': case 'o': case 'p': case 'j': case 'q': case 'r': case 'c': case 'a': case 'u': case 'w':
+					throw new EvaluationException(
+						"Type mismatch - unexpected . operator in expression of type "~demangleType(symdata.type)
+					);
+				//---------------------------------------------------------------------------------
+                // array properties
+				case 'G':
+                    switch ( id )
+                    {
+                        case "length":
+                            symdata.type = symdata.type[1..$];
+                            size_t len = parseNumber(symdata.type);
+                            symdata.type = "k";
+                            symdata.data = (cast(ubyte*)&len)[0..size_t.sizeof].dup;
+                            symdata.defered_load = false;
+                            break;
+                        case "ptr":
+                            // TODO: can this always be guaranteed?
+                            assert(symdata.defered_load);
+                            size_t ptr = symdata.ptr;
+                            symdata.data = (cast(ubyte*)&ptr)[0..size_t.sizeof];
+                            symdata.defered_load = false;
+                            symdata.type = symdata.type[1..$];
+                            parseNumber(symdata.type);
+                            symdata.type = "P"~symdata.type;
+                            break;
+                        default:
+                            throw new EvaluationException(
+                                "Type mismatch - invalid property "~id~" after expression of type "~demangleType(symdata.type)
+                            );
+                    }
+                    break;
+                case 'A':
+                    switch ( id )
+                    {
+                        case "length":
+                            ubyte[] data = symdata.getData(ctx);
+                            symdata.type = "k";
+                            size_t len = (cast(size_t[])data)[0];
+                            symdata.data = (cast(ubyte*)&len)[0..size_t.sizeof].dup;
+                            symdata.defered_load = false;
+                            break;
+                        case "ptr":
+                            ubyte[] data = symdata.getData(ctx);
+                            symdata.type = "k";
+                            size_t len = (cast(size_t[])data)[1];
+                            symdata.data = (cast(ubyte*)&len)[0..size_t.sizeof].dup;
+                            symdata.defered_load = false;
+                            break;
+                        default:
+                            throw new EvaluationException(
+                                "Type mismatch - invalid property "~id~" after expression of type "~demangleType(symdata.type)
+                            );
+                    }
+                    break;
+                case 'H':
+                    switch ( id )
+                    {
+                        case "length":
+                            ubyte[] data = symdata.getData(ctx);
+                            symdata.ptr = *cast(size_t*)data.ptr;
+                            symdata.len = BB.sizeof;
+                            symdata.defered_load = true;
+                            data = symdata.getData(ctx);
+                            BB* bb = cast(BB*)data.ptr;
+
+                            symdata.type = "k";
+                            symdata.data = (cast(ubyte*)&bb.nodes)[0..size_t.sizeof].dup;
+                            symdata.defered_load = false;
+                            break;
+                        default:
+                            throw new EvaluationException(
+                                "Type mismatch - invalid property "~id~" after expression of type "~demangleType(symdata.type)
+                            );
+                    }
+                    break;
+				//---------------------------------------------------------------------------------
+				// references to structs/classes
+				case 'P':
+                    symdata.type = symdata.type[1..$];
+					if ( symdata.type[0] != 'C' && symdata.type[0] != 'S' )
+					{
+                        throw new EvaluationException(
+                            "Type mismatch - unexpected . operator after expression of type "~demangleType("P"~symdata.type)
+                        );
+					}
+
+                    ubyte[] data = symdata.getData(ctx);
+                    if ( symdata.data.length <= 0 )
+                        throw new EvaluationException("Subexpression evaluated to empty data");
+					symdata.ptr = (cast(uint[])data)[0];
+					symdata.len = ctx.codeView.sizeofMangled(symdata.type);
+					symdata.defered_load = true;
+
+					if ( symdata.ptr == 0 )
+						throw new EvaluationException("pointer is null");
+                    // fall through to struct handling
+
+				//---------------------------------------------------------------------------------
+				// classes/structs
+				case 'C':
+				case 'S':
+                    symdata.type = symdata.type[1..$];
+                    string	scu_name = demangleNameSkip(symdata.type);
+                    assert ( symdata.type.length <= 0 );
+                    if ( (scu_name in ctx.codeView.UDTsByName) is null )
+                        throw new EvaluationException("unknown type \""~scu_name~"\"");
+
+                    LeafClassStruc  lcs = cast(LeafClassStruc)ctx.codeView.UDTsByName[scu_name];
+                    LeafUnion       lu;
+                    LeafFieldList   lfl;
+                    uint            type_length;
+
+                    if ( lcs !is null && lcs.field-0x1000 < ctx.codeView.type_strings.length ) {
+                        Leaf[] fields = ctx.codeView.type_strings[lcs.field-0x1000];
+                        lfl = cast(LeafFieldList)fields[0];
+                        type_length = lcs.length.getUint();
+                    }
+                    else
+                    {
+                        lu = cast(LeafUnion)ctx.codeView.UDTsByName[scu_name];
+                        if ( lu !is null && lu.field-0x1000 < ctx.codeView.type_strings.length ) {
+                            Leaf[] fields = ctx.codeView.type_strings[lu.field-0x1000];
+                            lfl = cast(LeafFieldList)fields[0];
+                            type_length = lu.length.getUint();
+                        }
+                    }
+                    if ( lfl is null )
+                        throw new EvaluationException("invalid struct/class debug symbols");
+
+                    size_t  size,
+                            offset;
+                    if ( !ctx.findMember(id, lfl, size, offset, symdata.type) )
+                        throw new EvaluationException("struct \""~scu_name~"\" has no element \""~id~"\"");
+                    assert ( symdata.type.length > 0 );
+                    debug(eval) DbgIO.println("member: type=%s size=%d offset=%d", symdata.type, size, offset);
+
+                    if ( !symdata.loadByteSlice(offset, offset+size) )
+                        throw new EvaluationException("invalid offset into struct for member \""~id~"\"");
+					break;
+				//---------------------------------------------------------------------------------
+				// unsupported
+				default:
+					throw new EvaluationException("yet unsupported type "~demangleType(symdata.type)~" in expression");
+			}
+        }
+
+        RefExpr(ctx, symbol, symbols, prefix, symdata);
+        break;
+    case 8:
+        debug assert(_ST_children.length == 2);
+        void delegate(EvaluationContext ctx, out SymbolData argdata, out size_t start, out size_t end) Args = &_ST_children[0]._S_Args;
+        void delegate(EvaluationContext ctx, NamedSymbol symbol, NamedSymbol[] symbols, string prefix, ref SymbolData symdata) RefExpr = &_ST_children[1]._S_RefExpr;
+
+#line 383 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        if ( symdata is null )
+            throw new EvaluationException("Unknown symbol "~prefix);
+
+        SymbolData  argdata;
+        size_t      start, end;
+        Args(ctx, argdata, start, end);
+
+        bool isIndex = argdata is null;
+        if ( !isIndex && castArrayIndex(argdata.getData(ctx), argdata.type, start) ) {
+            isIndex = true;
+            end = start+1;
+        }
+
+        switch ( symdata.type[0] )
+        {
+            //---------------------------------------------------------------------------------
+            // primitive types
+            case 'v': case 'b': case 'x': case 'g': case 'h': case 's':	case 't': case 'i': case 'k': case 'l': case 'm': case 'f':
+            case 'd': case 'e': case 'o': case 'p': case 'j': case 'q': case 'r': case 'c': case 'a': case 'u': case 'w':
+            // pointers, classes/structs
+            case 'P': case 'C': case 'S':
+                throw new EvaluationException(
+                    "Type mismatch - unexpected [] operator after expression of type "~demangleType(symdata.type)
+                );
+            //---------------------------------------------------------------------------------
+            // static arrays
+            case 'G':
+                if ( !isIndex )
+                    throw new EvaluationException("Cannot access static array with index type "~demangleType(argdata.type));
+
+                symdata.type = symdata.type[1..$];
+                size_t count = parseNumber(symdata.type);
+                assert(symdata.type.length>0);
+
+                if ( end-start > 1 )
+                {
+                    if ( end > count )
+                        throw new EvaluationException("Array index out of bounds: "~.toString(start)~".."~.toString(end)~" ($="~.toString(count)~")");
+                    size_t size = ctx.codeView.sizeofMangled(symdata.type);
+                    if ( symdata.defered_load ) {
+                        symdata.ptr += start * size;
+                        symdata.len = (end-start) * size;
+                    }
+                    else
+                        symdata.data = symdata.data[start*size .. end*size];
+                    symdata.type = "G"~.toString(end-start)~symdata.type;
+                }
+                else
+                {
+                    if ( !symdata.loadElementSlice(start, end, ctx.codeView) )
+                        throw new EvaluationException("Array index out of bounds: "~.toString(start)~".."~.toString(end)~" ($="~.toString(count)~")");
+                }
+                break;
+            //---------------------------------------------------------------------------------
+            // dynamic arrays
+            case 'A':
+                if ( !isIndex )
+                    throw new EvaluationException("Cannot access dynamic array with index type "~demangleType(argdata.type));
+
+                ubyte[] data = symdata.getData(ctx);
+                if ( data.length < 8 )
+                    throw new EvaluationException("Subexpression evaluated to empty data");
+
+                if ( end-start > 1 )
+                {
+                    if ( end > (cast(size_t[])data)[0] )
+                        throw new EvaluationException("Array index out of bounds: "~.toString(start)~".."~.toString(end)~" ($="~.toString(symdata.len)~")");
+                    size_t size = ctx.codeView.sizeofMangled(symdata.type[1..$]);
+                    (cast(size_t[])data)[1] += start * size,
+                    (cast(size_t[])data)[0] = end-start;
+                }
+                else
+                {
+                    symdata.type = symdata.type[1..$];
+                    assert(symdata.type.length>0);
+                    symdata.ptr = (cast(size_t[])data)[1];
+                    symdata.len = (cast(size_t[])data)[0] * ctx.codeView.sizeofMangled(symdata.type);
+                    symdata.defered_load = true;
+
+                    if ( !symdata.loadElementSlice(start, end, ctx.codeView) )
+                        throw new EvaluationException("Array index out of bounds: "~.toString(start)~".."~.toString(end)~" ($="~.toString(symdata.len)~")");
+                }
+                break;
+            //---------------------------------------------------------------------------------
+            // associative arrays
+            case 'H':
+                int i;
+                for ( i = 1; i < symdata.type.length && std.string.find(lowercase, symdata.type[i]) < 0; ++i ) {}
+                string		key_type	= symdata.type[1..i+1],
+                            val_type	= symdata.type[i+1..$];
+                size_t      val_tsize   = ctx.codeView.sizeofMangled(val_type);
+                TypeInfo	key_ti		= TypeInfoFromMangled(key_type);
+
+                aaA* loadaaA(void* ptr)
+                {
+                    if ( ptr is null )
+                        return null;
+                    ubyte[] data;
+                    data.length = aaA.sizeof+key_ti.tsize+val_tsize;
+                    if ( data.length != ctx.process.readProcessMemory(cast(uint)ptr, data.ptr, data.length) )
+                        return null;
+                    aaA* a = cast(aaA*)data.ptr;
+                    if ( std.string.find(lowercase, key_type[0]) < 0 )
+                    switch ( key_type[0] )
+                    {
+                        case 'A':
+                            ubyte[] tmp = *cast(ubyte[]*)(a+1);
+                            if ( tmp.length > ctx.process.MEMCHECK_MIN && ctx.process.isInvalidMem(cast(size_t)tmp.ptr, tmp.length) )
+                                return null;
+                            data = new ubyte[tmp.length];
+                            if ( data.length != ctx.process.readProcessMemory(cast(size_t)tmp.ptr, data.ptr, data.length) )
+                                return null;
+                            *cast(ubyte[]*)(a+1) = data;
+                            break;
+                        case 'P':
+                            break;
+                        default:
+                            throw new EvaluationException("only basic, pointer and array key types are supported, yet");
+                    }
+                    return a;
+                }
+
+                ubyte[] findKey(size_t ptr, hash_t hash, ubyte[] key_data)
+                {
+                    ubyte[] data;
+                    data.length = BB.sizeof;
+                    if ( data.length != ctx.process.readProcessMemory(ptr, data.ptr, data.length) )
+                        return null;
+                    BB* bb = cast(BB*)data.ptr;
+                    size_t blen = bb.b.length*size_t.sizeof;
+                    debug(eval) DbgIO.println("%d nodes, bb.b.length=%d", bb.nodes, bb.b.length);
+
+                    if ( blen > ctx.process.MEMCHECK_MIN && ctx.process.isInvalidMem(cast(size_t)bb.b.ptr, blen) )
+                        return null;
+                    data = new ubyte[blen];
+                    if ( data.length != ctx.process.readProcessMemory(cast(uint)bb.b.ptr, data.ptr, data.length) )
+                        return null;
+                    bb.b = cast(aaA*[])data;
+
+                    uint i = hash % bb.b.length;
+                    debug(eval) DbgIO.println("start index=%d", i);
+                    aaA* a = loadaaA(bb.b[i]);
+                    while ( a !is null )
+                    {
+                        if ( hash == a.hash )
+                        {
+                            debug(eval) DbgIO.println("equal 0x%x", a.hash);
+                            auto cmp = key_ti.compare(key_data.ptr, a+1);
+                            debug(eval) DbgIO.println("%s: %d == %d -> %d", key_ti, *cast(uint*)key_data.ptr, *cast(uint*)(a+1), cmp);
+                            if ( cmp == 0 )
+                                return ((cast(ubyte*)(a+1))+key_ti.tsize)[0 .. val_tsize];
+                            a = cmp < 0 ? loadaaA(a.left) : loadaaA(a.right);
+                        }
+                        else {
+                            debug(eval) DbgIO.println("not equal 0x%x", a.hash);
+                            a = hash < a.hash ? loadaaA(a.left) : loadaaA(a.right);
+                        }
+                    }
+                    return null;
+                }
+
+                if ( key_type != argdata.type )
+                    throw new EvaluationException("Invalid key type for associative array. Expected "~demangleType(key_type)~" found "~demangleType(argdata.type));
+                TypeInfo ti = TypeInfoFromMangled(argdata.type);
+                hash_t index_hash = ti.getHash(argdata.data.ptr);
+
+                debug(eval) DbgIO.println("searching, hash=0x%x", index_hash);
+                ubyte[] data = symdata.getData(ctx);
+                symdata.data = findKey((cast(size_t[])data)[0], index_hash, argdata.getData(ctx));
+                symdata.type = val_type;
+                break;
+            //---------------------------------------------------------------------------------
+            // unsupported
+            default:
+                throw new EvaluationException("yet unsupported type "~demangleType(symdata.type)~" in expression");
+        }
+
+        RefExpr(ctx, symbol, null, null, symdata);
+        break;
+    case 9:
+        debug assert(_ST_children.length == 0);
+
+#line 568 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        if ( symdata is null )
+            throw new EvaluationException("Unknown symbol "~prefix);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_Args(EvaluationContext ctx, out SymbolData argdata, out size_t start, out size_t end)
+{
+
+    switch ( _ST_rule )
+    {
+    case 10:
+        debug assert(_ST_children.length == 2);
+        void delegate(EvaluationContext ctx, out SymbolData symdata) Expr = &_ST_children[0]._S_Expr;
+        void delegate(EvaluationContext ctx, out SymbolData symdata) Expr2 = &_ST_children[1]._S_Expr;
+
+#line 579 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        SymbolData arg1, arg2;
+        Expr(ctx, arg1);
+        Expr2(ctx, arg2);
+
+        bool isIndex = castArrayIndex(arg1.getData(ctx), arg1.type, start);
+        isIndex = isIndex && castArrayIndex(arg2.getData(ctx), arg2.type, end);
+        if ( !isIndex )
+            throw new EvaluationException("Slices may only have integer indeces, not "~demangleType(arg1.type)~".."~demangleType(arg2.type));
+        break;
+    case 11:
+        debug assert(_ST_children.length == 1);
+        void delegate(EvaluationContext ctx, out SymbolData symdata) Expr = &_ST_children[0]._S_Expr;
+
+#line 591 "D:\src\ddbg_continued\src\expression\expression.apd"
+ Expr(ctx, argdata);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_Register(EvaluationContext ctx, out SymbolData symdata)
+{
+
+    switch ( _ST_rule )
+    {
+    case 12:
+        debug assert(_ST_children.length == 1);
+        void delegate(out string name, out ubyte width) RegName = &_ST_children[0]._S_RegName;
+
+#line 601 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        string  name;
+        ubyte   width;
+        RegName(name, width);
+
+		CONTEXT threadCtx;
+		uint context_flags;
+        context_flags |= CONTEXT_FULL;
+        context_flags |= CONTEXT_FLOATING_POINT;
+        context_flags |= CONTEXT_EXTENDED_REGISTERS;
+		if ( !ctx.getContext(threadCtx, context_flags) )
+			throw new EvaluationException("Couldn't get main thread's context");
+
+        ubyte* ptr;
+        switch ( name[1..$] )
+        {
+            case "ax":
+            case "eax":
+            case "al":  ptr = cast(ubyte*)&threadCtx.Eax;   break;
+            case "ah":  ptr = (cast(ubyte*)&threadCtx.Eax)+1;   break;
+            case "bx":
+            case "ebx":
+            case "bl":  ptr = cast(ubyte*)&threadCtx.Ebx;   break;
+            case "bh":  ptr = (cast(ubyte*)&threadCtx.Ebx)+1;   break;
+            case "cx":
+            case "ecx":
+            case "cl":  ptr = cast(ubyte*)&threadCtx.Ecx;   break;
+            case "ch":  ptr = (cast(ubyte*)&threadCtx.Ecx)+1;   break;
+            case "dx":
+            case "edx":
+            case "dl":  ptr = cast(ubyte*)&threadCtx.Edx;   break;
+            case "dh":  ptr = (cast(ubyte*)&threadCtx.Edx)+1;   break;
+            case "edi":
+            case "di":  ptr = cast(ubyte*)&threadCtx.Edi;   break;
+            case "esi":
+            case "si":  ptr = cast(ubyte*)&threadCtx.Esi;   break;
+            case "ebp":
+            case "bp":  ptr = cast(ubyte*)&threadCtx.Ebp;   break;
+            case "esp":
+            case "sp":  ptr = cast(ubyte*)&threadCtx.Esp;   break;
+            case "eip": ptr = cast(ubyte*)&threadCtx.Eip;   break;
+            case "efl": ptr = cast(ubyte*)&threadCtx.EFlags;    break;
+            case "cs":  ptr = cast(ubyte*)&threadCtx.SegCs; break;
+            case "ds":  ptr = cast(ubyte*)&threadCtx.SegDs; break;
+            case "es":  ptr = cast(ubyte*)&threadCtx.SegEs; break;
+            case "fs":  ptr = cast(ubyte*)&threadCtx.SegFs; break;
+            case "gs":  ptr = cast(ubyte*)&threadCtx.SegGs; break;
+            default:
+                int i = name[$-1]-'0';
+                if ( name[0..2] == "st" )
+                    ptr = cast(ubyte*)&((cast(real[])threadCtx.FloatSave.RegisterArea)[i]);
+                else if ( name[0..2] == "mm" )
+                    ptr = cast(ubyte*)&((cast(long[])threadCtx.ExtendedRegisters)[4+i*2]);
+                else if ( name[0..3] == "xmm" )
+                    ptr = cast(ubyte*)&((cast(long[])threadCtx.ExtendedRegisters)[20+i*2]);
+                else
+                    assert(0);
+        }
+
+        symdata = new SymbolData;
+        switch ( width )
+        {
+            case 8:
+                symdata.type = "h";
+                symdata.data = ptr[0..1].dup;
+                break;
+            case 16:
+                symdata.type = "t";
+                symdata.data = ptr[0..2].dup;
+                break;
+            case 32:
+                symdata.type = "k";
+                symdata.data = ptr[0..4].dup;
+                break;
+            case 64:
+                symdata.type = "m";
+                symdata.data = ptr[0..8].dup;
+                break;
+            case 80:
+                symdata.type = "e";
+                symdata.data = ptr[0..10].dup;
+                break;
+            case 128:
+                symdata.type = "G4k";
+                symdata.data = ptr[0..16].dup;
+                break;
+            default:
+                assert(0, "unhandled register width "~.toString(width));
+        }
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_RegName(out string name, out ubyte width)
+{
+
+    switch ( _ST_rule )
+    {
+    case 13:
+        debug assert(_ST_children.length == 0);
+
+#line 696 "D:\src\ddbg_continued\src\expression\expression.apd"
+ name = _ST_match; width = 32;
+        break;
+    case 14:
+        debug assert(_ST_children.length == 0);
+
+#line 699 "D:\src\ddbg_continued\src\expression\expression.apd"
+ name = _ST_match; width = 16;
+        break;
+    case 15:
+        debug assert(_ST_children.length == 0);
+
+#line 702 "D:\src\ddbg_continued\src\expression\expression.apd"
+ name = _ST_match; width = 8;
+        break;
+    case 16:
+        debug assert(_ST_children.length == 0);
+
+#line 705 "D:\src\ddbg_continued\src\expression\expression.apd"
+ name = _ST_match; width = 8*real.sizeof;
+        break;
+    case 17:
+        debug assert(_ST_children.length == 0);
+
+#line 708 "D:\src\ddbg_continued\src\expression\expression.apd"
+ name = _ST_match; width = 64;
+        break;
+    case 18:
+        debug assert(_ST_children.length == 0);
+
+#line 711 "D:\src\ddbg_continued\src\expression\expression.apd"
+ name = _ST_match; width = 128;
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_Cast(EvaluationContext ctx, ref SymbolData symdata)
+{
+
+    switch ( _ST_rule )
+    {
+    case 19:
+        debug assert(_ST_children.length == 1);
+        void delegate(EvaluationContext ctx, ref string mangled) Type = &_ST_children[0]._S_Type;
+
+#line 724 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        symdata.type = "";
+        Type(ctx, symdata.type);
+        if ( symdata.type.length <= 0 )
+            throw new EvaluationException("Unknown type in cast");
+        break;
+    case 20:
+        debug assert(_ST_children.length == 0);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_Type(EvaluationContext ctx, ref string mangled)
+{
+
+    switch ( _ST_rule )
+    {
+    case 21:
+        debug assert(_ST_children.length == 2);
+        void delegate(EvaluationContext ctx, out string type) BaseType = &_ST_children[0]._S_BaseType;
+        void delegate(EvaluationContext ctx, ref string mangled) QuantList = &_ST_children[1]._S_QuantList;
+
+#line 737 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        string  unmangled;
+        BaseType(ctx, unmangled);
+
+		switch ( unmangled )
+		{
+			case "void":	mangled = "v";	break;
+			case "bool":	mangled = "b";	break;
+			case "byte":	mangled = "g";	break;
+			case "ubyte":	mangled = "h";	break;
+			case "char":	mangled = "a";	break;
+			case "wchar":	mangled = "u";	break;
+			case "dchar":	mangled = "w";	break;
+			case "short":	mangled = "s";	break;
+			case "ushort":	mangled = "t";	break;
+			case "int":		mangled = "i";	break;
+			case "uint":	mangled = "k";	break;
+			case "long":	mangled = "l";	break;
+			case "ulong":	mangled = "m";	break;
+			case "float":	mangled = "f";	break;
+			case "double":	mangled = "d";	break;
+			case "real":	mangled = "e";	break;
+			default:
+				Leaf lf;
+				if ( (unmangled in ctx.codeView.UDTsByName) is null )
+				{
+					foreach ( un, l; ctx.codeView.UDTsByName )
+					{
+						if ( std.string.find(un, "."~unmangled) > 0 ) {
+							lf = l;
+							break;
+						}
+					}
+				}
+				else
+					lf = ctx.codeView.UDTsByName[unmangled];
+
+				if ( lf !is null )
+				{
+					string fqn;
+					switch ( lf.leaf_index )
+					{
+						case LF_CLASS_16t:
+							mangled = "C";
+							fqn = (cast(LeafClassStruc)lf).name;
+							break;
+						case LF_STRUCTURE_16t:
+							mangled = "S";
+							fqn = (cast(LeafClassStruc)lf).name;
+							break;
+						case LF_ENUM_16t:
+							mangled = "E";
+							fqn = (cast(LeafEnum)lf).name;
+							break;
+						default:
+							assert(0);
+					}
+					string[] parts = std.string.split(fqn, ".");
+					foreach ( p; parts ) {
+						mangled ~= .toString(p.length);
+						mangled ~= p;
+					}
+				}
+                else
+                    throw new EvaluationException("Unknown BaseType "~unmangled);
+				break;
+		}
+
+		QuantList(ctx, mangled);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_BaseType(EvaluationContext ctx, out string type)
+{
+
+    switch ( _ST_rule )
+    {
+    case 22:
+        debug assert(_ST_children.length == 2);
+        void delegate(out string id) FQNIdent = &_ST_children[0]._S_FQNIdent;
+        void delegate(EvaluationContext ctx, out string str) TplParams = &_ST_children[1]._S_TplParams;
+
+#line 812 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        FQNIdent(type);
+        string str;
+        TplParams(ctx, str);
+        type ~= str;
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_QuantList(EvaluationContext ctx, ref string mangled)
+{
+
+    switch ( _ST_rule )
+    {
+    case 23:
+        debug assert(_ST_children.length == 2);
+        void delegate(EvaluationContext ctx, ref string mangled) Quantifier = &_ST_children[0]._S_Quantifier;
+        void delegate(EvaluationContext ctx, ref string mangled) QuantList = &_ST_children[1]._S_QuantList;
+
+#line 823 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        Quantifier(ctx, mangled);
+        QuantList(ctx, mangled);
+        break;
+    case 24:
+        debug assert(_ST_children.length == 0);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_Quantifier(EvaluationContext ctx, ref string mangled)
+{
+
+    switch ( _ST_rule )
+    {
+    case 25:
+        debug assert(_ST_children.length == 0);
+
+#line 834 "D:\src\ddbg_continued\src\expression\expression.apd"
+ mangled = "P"~mangled;
+        break;
+    case 26:
+        debug assert(_ST_children.length == 0);
+
+#line 837 "D:\src\ddbg_continued\src\expression\expression.apd"
+ mangled = "A"~mangled;
+        break;
+    case 27:
+        debug assert(_ST_children.length == 1);
+        void delegate(out ulong val) Integer = &_ST_children[0]._S_Integer;
+
+#line 842 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        ulong len;
+        Integer(len);
+        mangled = "G"~.toString(len)~mangled;
+        break;
+    case 28:
+        debug assert(_ST_children.length == 1);
+        void delegate(EvaluationContext ctx, ref string mangled) Type = &_ST_children[0]._S_Type;
+
+#line 851 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        string index_mangled;
+        Type(ctx, index_mangled);
+        mangled = "H"~index_mangled~mangled;
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_TplParams(EvaluationContext ctx, out string str)
+{
+
+    switch ( _ST_rule )
+    {
+    case 29:
+        debug assert(_ST_children.length == 2);
+        void delegate(EvaluationContext ctx, out string str) TplParam = &_ST_children[0]._S_TplParam;
+        void delegate(EvaluationContext ctx, out string str) TplParams2 = &_ST_children[1]._S_TplParams2;
+
+#line 865 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        string tmp;
+        TplParam(ctx, tmp);
+        str = "!("~tmp;
+        TplParams2(ctx, tmp);
+        str ~= tmp~")";
+        break;
+    case 30:
+        debug assert(_ST_children.length == 0);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_TplParams2(EvaluationContext ctx, out string str)
+{
+
+    switch ( _ST_rule )
+    {
+    case 31:
+        debug assert(_ST_children.length == 2);
+        void delegate(EvaluationContext ctx, out string str) TplParam = &_ST_children[0]._S_TplParam;
+        void delegate(EvaluationContext ctx, out string str) TplParams2 = &_ST_children[1]._S_TplParams2;
+
+#line 881 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        TplParam(ctx, str);
+        string tmp;
+        TplParams2(ctx, tmp);
+        str ~= tmp;
+        break;
+    case 32:
+        debug assert(_ST_children.length == 0);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_TplParam(EvaluationContext ctx, out string str)
+{
+
+    switch ( _ST_rule )
+    {
+    case 33:
+        debug assert(_ST_children.length == 1);
+        void delegate(EvaluationContext ctx, ref string mangled) Type = &_ST_children[0]._S_Type;
+
+#line 893 "D:\src\ddbg_continued\src\expression\expression.apd"
+ Type(ctx, str);
+        break;
+    case 34:
+        debug assert(_ST_children.length == 1);
+        void delegate(out string str) StrLit = &_ST_children[0]._S_StrLit;
+
+#line 894 "D:\src\ddbg_continued\src\expression\expression.apd"
+ StrLit(str);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_Lit(out SymbolData litdata)
+{
+
+    switch ( _ST_rule )
+    {
+    case 35:
+        debug assert(_ST_children.length == 3);
+        void delegate(ref SymbolData symdata) Sign = &_ST_children[0]._S_Sign;
+        void delegate(out ulong val) Integer = &_ST_children[1]._S_Integer;
+        void delegate(out string type) IntegerSuffix = &_ST_children[2]._S_IntegerSuffix;
+
+#line 904 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        litdata = new SymbolData;
+        IntegerSuffix(litdata.type);
+        ulong val;
+        Integer(val);
+
+        if ( val > 0x7fffffffffffffff )
+            litdata.type = "m";
+        else if ( val > 0xffffffff )
+            litdata.type = litdata.type[0]=='i'||litdata.type[0]=='l'?"l":"m";
+        else if ( val > 0x7fffffff && litdata.type[0] == 'i' )
+            litdata.type = "k";
+
+        litdata.data = (cast(ubyte*)&val)[0 .. (litdata.type[0] == 'k' || litdata.type[0] == 'i')?uint.sizeof:ulong.sizeof].dup;
+        Sign(litdata);
+        break;
+    case 36:
+        debug assert(_ST_children.length == 0);
+
+#line 923 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        litdata = new SymbolData;
+        litdata.type = "Aa";
+        litdata.data = cast(ubyte[])_ST_match;
+        break;
+    case 37:
+        debug assert(_ST_children.length == 0);
+
+#line 931 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        litdata = new SymbolData;
+        litdata.type = "a";
+        litdata.data = cast(ubyte[])_ST_match[0..1];
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_StrLit(out string str)
+{
+
+    switch ( _ST_rule )
+    {
+    case 38:
+        debug assert(_ST_children.length == 1);
+        void delegate(out ulong val) Integer = &_ST_children[0]._S_Integer;
+
+#line 942 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        ulong val;
+        Integer(val);
+        str = .toString(val);
+        break;
+    case 39:
+        debug assert(_ST_children.length == 0);
+
+#line 950 "D:\src\ddbg_continued\src\expression\expression.apd"
+ str = _ST_match;
+        break;
+    case 40:
+        debug assert(_ST_children.length == 0);
+
+#line 954 "D:\src\ddbg_continued\src\expression\expression.apd"
+ str = _ST_match;
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_Ident(out string id)
+{
+
+    switch ( _ST_rule )
+    {
+    case 41:
+        debug assert(_ST_children.length == 0);
+
+#line 960 "D:\src\ddbg_continued\src\expression\expression.apd"
+ id = _ST_match;
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_FQNIdent(out string id)
+{
+
+    switch ( _ST_rule )
+    {
+    case 42:
+        debug assert(_ST_children.length == 1);
+        void delegate(out string id) Ident = &_ST_children[0]._S_Ident;
+
+#line 966 "D:\src\ddbg_continued\src\expression\expression.apd"
+ Ident(id);
+        break;
+    case 43:
+        debug assert(_ST_children.length == 2);
+        void delegate(out string id) FQNIdent = &_ST_children[0]._S_FQNIdent;
+        void delegate(out string id) Ident = &_ST_children[1]._S_Ident;
+
+#line 969 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        FQNIdent(id);
+        string tmp;
+        Ident(tmp);
+        id ~= "."~tmp;
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_Integer(out ulong val)
+{
+
+    switch ( _ST_rule )
+    {
+    case 44:
+        debug assert(_ST_children.length == 0);
+
+#line 984 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        foreach ( b; _ST_match[2..$] )
+        {
+            val <<= 4;
+            if ( b > 'F' )
+                val |= b-'W';
+            else if ( b > '9' )
+                val |= b-'7';
+            else
+                val |= b-'0';
+        }
+        break;
+    case 45:
+        debug assert(_ST_children.length == 0);
+
+#line 999 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        foreach ( b; _ST_match[2..$] )
+        {
+            val <<= 1;
+            if ( b == '1' )
+                val |= 1;
+        }
+        break;
+    case 46:
+        debug assert(_ST_children.length == 0);
+
+#line 1010 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        foreach ( b; _ST_match[1..$] ) {
+            val <<= 3;
+            val |= b-'0';
+        }
+        break;
+    case 47:
+        debug assert(_ST_children.length == 0);
+
+#line 1019 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        foreach ( b; _ST_match ) {
+            val *= 10;
+            val += b-'0';
+        }
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_IntegerSuffix(out string type)
+{
+
+    switch ( _ST_rule )
+    {
+    case 48:
+        debug assert(_ST_children.length == 0);
+
+#line 1030 "D:\src\ddbg_continued\src\expression\expression.apd"
+ type = "m";
+        break;
+    case 49:
+        debug assert(_ST_children.length == 0);
+
+#line 1033 "D:\src\ddbg_continued\src\expression\expression.apd"
+ type = "m";
+        break;
+    case 50:
+        debug assert(_ST_children.length == 0);
+
+#line 1036 "D:\src\ddbg_continued\src\expression\expression.apd"
+ type = "m";
+        break;
+    case 51:
+        debug assert(_ST_children.length == 0);
+
+#line 1039 "D:\src\ddbg_continued\src\expression\expression.apd"
+ type = "m";
+        break;
+    case 52:
+        debug assert(_ST_children.length == 0);
+
+#line 1042 "D:\src\ddbg_continued\src\expression\expression.apd"
+ type = "l";
+        break;
+    case 53:
+        debug assert(_ST_children.length == 0);
+
+#line 1045 "D:\src\ddbg_continued\src\expression\expression.apd"
+ type = "k";
+        break;
+    case 54:
+        debug assert(_ST_children.length == 0);
+
+#line 1048 "D:\src\ddbg_continued\src\expression\expression.apd"
+ type = "i";
+        break;
+
+    default:
+        assert(0);
+    }
+}
+void _S_Sign(ref SymbolData symdata)
+{
+
+    switch ( _ST_rule )
+    {
+    case 55:
+        debug assert(_ST_children.length == 0);
+
+#line 1054 "D:\src\ddbg_continued\src\expression\expression.apd"
+
+        switch ( symdata.type[0] )
+        {
+            case 'i':
+                *cast(int*)symdata.data.ptr = 0-*cast(int*)symdata.data.ptr;
+                break;
+            case 'k':
+                *cast(uint*)symdata.data.ptr = 0-*cast(uint*)symdata.data.ptr;
+                break;
+            case 'l':
+                *cast(long*)symdata.data.ptr = 0-*cast(long*)symdata.data.ptr;
+                break;
+            case 'm':
+                *cast(ulong*)symdata.data.ptr = 0-*cast(ulong*)symdata.data.ptr;
+                break;
+            default:
+                assert(0);
+        }
+        break;
+    case 56:
+        debug assert(_ST_children.length == 0);
+        break;
+
+    default:
+        assert(0);
+    }
+}
+
+// generated code end
+}
+
+#line 1443 "D:\src\ddbg_continued\src\expression\expression_apd.d"
+// Written in the D programming language
+
+/*
+ *  This file has been automatically generated by APaGeD v0.4.2 beta - Attributed Parser Generator for D.
+ *
+ *  Sections generated from custom input are marked as "generated code" and
+ *  are subject to the terms and conditions stated in one of these sections.
+ *  The remaining sections are part of the APaGeD package and subject
+ *  to the terms and conditions of the corresponding license.
+ *
+ *  Attributed Parser Generator for D
+ *  Copyright (c) 2007 Jascha Wetzel. All rights reserved
+ *  License: Artistic License 2.0
+ */
+
+/**************************************************************************************************
+    Lexer
+**************************************************************************************************/
+
+version(Tango)
+// the following block is stolen from phobos.
+// the copyright notice applies for this block only.
+{
+/*
+ *  Copyright (C) 2003-2004 by Digital Mars, www.digitalmars.com
+ *  Written by Walter Bright
+ *
+ *  This software is provided 'as-is', without any express or implied
+ *  warranty. In no event will the authors be held liable for any damages
+ *  arising from the use of this software.
+ *
+ *  Permission is granted to anyone to use this software for any purpose,
+ *  including commercial applications, and to alter it and redistribute it
+ *  freely, subject to the following restrictions:
+ *
+ *  o  The origin of this software must not be misrepresented; you must not
+ *     claim that you wrote the original software. If you use this software
+ *     in a product, an acknowledgment in the product documentation would be
+ *     appreciated but is not required.
+ *  o  Altered source versions must be plainly marked as such, and must not
+ *     be misrepresented as being the original software.
+ *  o  This notice may not be removed or altered from any source
+ *     distribution.
+ */
+
+bool isValidDchar(dchar c)
+{
+    /* Note: FFFE and FFFF are specifically permitted by the
+     * Unicode standard for application internal use, but are not
+     * allowed for interchange.
+     * (thanks to Arcane Jill)
+     */
+
+    return c < 0xD800 ||
+	(c > 0xDFFF && c <= 0x10FFFF /*&& c != 0xFFFE && c != 0xFFFF*/);
+}
+
+/***************
+ * Decodes and returns character starting at s[idx]. idx is advanced past the
+ * decoded character. If the character is not well formed, a UtfException is
+ * thrown and idx remains unchanged.
+ */
+
+dchar decode(in char[] s, inout size_t idx)
+    {
+	size_t len = s.length;
+	dchar V;
+	size_t i = idx;
+	char u = s[i];
+
+	if (u & 0x80)
+	{   uint n;
+	    char u2;
+
+	    /* The following encodings are valid, except for the 5 and 6 byte
+	     * combinations:
+	     *	0xxxxxxx
+	     *	110xxxxx 10xxxxxx
+	     *	1110xxxx 10xxxxxx 10xxxxxx
+	     *	11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+	     *	111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+	     *	1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+	     */
+	    for (n = 1; ; n++)
+	    {
+		if (n > 4)
+		    goto Lerr;		// only do the first 4 of 6 encodings
+		if (((u << n) & 0x80) == 0)
+		{
+		    if (n == 1)
+			goto Lerr;
+		    break;
+		}
+	    }
+
+	    // Pick off (7 - n) significant bits of B from first byte of octet
+	    V = cast(dchar)(u & ((1 << (7 - n)) - 1));
+
+	    if (i + (n - 1) >= len)
+		goto Lerr;			// off end of string
+
+	    /* The following combinations are overlong, and illegal:
+	     *	1100000x (10xxxxxx)
+	     *	11100000 100xxxxx (10xxxxxx)
+	     *	11110000 1000xxxx (10xxxxxx 10xxxxxx)
+	     *	11111000 10000xxx (10xxxxxx 10xxxxxx 10xxxxxx)
+	     *	11111100 100000xx (10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx)
+	     */
+	    u2 = s[i + 1];
+	    if ((u & 0xFE) == 0xC0 ||
+		(u == 0xE0 && (u2 & 0xE0) == 0x80) ||
+		(u == 0xF0 && (u2 & 0xF0) == 0x80) ||
+		(u == 0xF8 && (u2 & 0xF8) == 0x80) ||
+		(u == 0xFC && (u2 & 0xFC) == 0x80))
+		goto Lerr;			// overlong combination
+
+	    for (uint j = 1; j != n; j++)
+	    {
+		u = s[i + j];
+		if ((u & 0xC0) != 0x80)
+		    goto Lerr;			// trailing bytes are 10xxxxxx
+		V = (V << 6) | (u & 0x3F);
+	    }
+	    if (!isValidDchar(V))
+		goto Lerr;
+	    i += n;
+	}
+	else
+	{
+	    V = cast(dchar) u;
+	    i++;
+	}
+
+	idx = i;
+	return V;
+
+      Lerr:
+	throw new Exception("4invalid UTF-8 sequence");
+    }
+}
+else
+{
+    import std.utf;
+}
+
+// lexer code
+// generated code start
+// ((?\*)|(?\()|(?\))|(?\.)|(?\[)|(?\])|(?\.\.)|(?#(e[abcd]x|e[ds]i|e[bs]p|eip|efl))|(?#([abcd]x|[ds]i|[bs]p|(cdefgs)s))|(?#[abcd][hl])|(?#st[0-7])|(?#mm[0-7])|(?#xmm[0-7])|(?cast)|(?!)|(?,)|(?"(([^"\\]*(\\(['"\?\\abfnrtv]|(x[0-9a-fA-F]{2})|(u[0-9a-fA-F]{4})|(U[0-9a-fA-F]{8})))?)*)")|(?'(([^'\\]|(\\(['"\?\\abfnrtv]|(x[0-9a-fA-F]{2})|(u[0-9a-fA-F]{4})|(U[0-9a-fA-F]{8})))))')|(?[a-zA-Z_][_a-zA-Z0-9]*)|(?0[xX][0-9a-fA-F_]+)|(?0[bB][01_]+)|(?0[0-7_]+)|(?0|([1-9][0-9_]*))|(?L)|(?u)|(?U)|(?[uU])|(?\-)).*?
+bool mainLexer(string input, out uint token, out string match)
+{
+    uint s = 0;
+    static int r56=-1, r57=-1, r58=-1, r59=-1, r60=-1, r61=-1, r62=-1, r63=-1, r64=-1, r65=-1, 
+        r66=-1, r67=-1, r68=-1, r69=-1, r70=-1, r71=-1, r72=-1, r73=-1, r74=-1, r75=-1, 
+        r76=-1, r77=-1, r78=-1, r79=-1, r80=-1, r81=-1, r82=-1, r83=-1, r84=-1, r85=-1, 
+        r86=-1;
+
+    for ( size_t p = 0, q = 0, p_end = input.length; p < p_end; q = p )
+    {
+        dchar c = cast(dchar)input[p];
+        if ( c & 0x80 )
+            decode(input, p);
+        else
+            ++p;
+        switch ( s )
+        {
+            case 0:
+                if ( c == 0x4c ) {
+                    s = 14;
+                    r66 = p;
+                }
+                else if ( c == 0x28 ) {
+                    s = 2;
+                    r57 = p;
+                }
+                else if ( c == 0x63 ) {
+                    s = 13;
+                    r66 = p;
+                }
+                else if ( c == 0x75 ) {
+                    s = 16;
+                    r66 = p;
+                }
+                else if ( c == 0x2d ) {
+                    s = 11;
+                    r64 = p;
+                }
+                else if ( c == 0x55 ) {
+                    s = 17;
+                    r66 = p;
+                }
+                else if ( c == 0x23 ) {
+                    s = 18;
+                }
+                else if ( c == 0x2e ) {
+                    s = 12;
+                    r65 = p;
+                }
+                else if ( c == 0x2c ) {
+                    s = 10;
+                    r63 = p;
+                }
+                else if ( c == 0x2a ) {
+                    s = 1;
+                    r56 = p;
+                }
+                else if ( c == 0x5d ) {
+                    s = 5;
+                    r60 = p;
+                }
+                else if ( c == 0x21 ) {
+                    s = 8;
+                    r61 = p;
+                }
+                else if ( c == 0x29 ) {
+                    s = 3;
+                    r58 = p;
+                }
+                else if ( c == 0x5b ) {
+                    s = 4;
+                    r59 = p;
+                }
+                else if ( c == 0x30 ) {
+                    s = 19;
+                    r62 = p;
+                }
+                else if ( c >= 0x31 && c <= 0x39 ) {
+                    s = 9;
+                    r62 = p;
+                }
+                else if ( c == 0x22 ) {
+                    s = 6;
+                }
+                else if ( c == 0x27 ) {
+                    s = 7;
+                }
+                else if ( c >= 0x41 && c <= 0x4b || c >= 0x4d && c <= 0x54 || c >= 0x56 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x62 || c >= 0x64 && c <= 0x74 || c >= 0x76 && c <= 0x7a ) {
+                    s = 15;
+                    r66 = p;
+                }
+                else
+                    return false;
+                break;
+            case 1:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 129;
+                }
+                else
+                    goto finish1;
+                break;
+            case 2:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 128;
+                }
+                else
+                    goto finish2;
+                break;
+            case 3:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 127;
+                }
+                else
+                    goto finish3;
+                break;
+            case 4:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 126;
+                }
+                else
+                    goto finish4;
+                break;
+            case 5:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 125;
+                }
+                else
+                    goto finish5;
+                break;
+            case 6:
+                if ( c == 0x5c ) {
+                    s = 103;
+                }
+                else if ( c == 0x22 ) {
+                    s = 104;
+                    r67 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 105;
+                }
+                else
+                    return false;
+                break;
+            case 7:
+                if ( c == 0x5c ) {
+                    s = 81;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x26 || c >= 0x28 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 82;
+                }
+                else
+                    return false;
+                break;
+            case 8:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 80;
+                }
+                else
+                    goto finish8;
+                break;
+            case 9:
+                if ( c >= 0x30 && c <= 0x39 || c == 0x5f ) {
+                    s = 79;
+                    r68 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 20;
+                }
+                else
+                    goto finish9;
+                break;
+            case 10:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 78;
+                }
+                else
+                    goto finish10;
+                break;
+            case 11:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 77;
+                }
+                else
+                    goto finish11;
+                break;
+            case 12:
+                if ( c == 0x2e ) {
+                    s = 75;
+                    r69 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 74;
+                }
+                else
+                    goto finish12;
+                break;
+            case 13:
+                if ( c == 0x61 ) {
+                    s = 69;
+                    r70 = p;
+                }
+                else if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x7a ) {
+                    s = 68;
+                    r70 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 67;
+                }
+                else
+                    goto finish13;
+                break;
+            case 14:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x7a ) {
+                    s = 68;
+                    r70 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 67;
+                }
+                else
+                    goto finish14;
+                break;
+            case 15:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x7a ) {
+                    s = 68;
+                    r70 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 67;
+                }
+                else
+                    goto finish15;
+                break;
+            case 16:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x7a ) {
+                    s = 68;
+                    r70 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 67;
+                }
+                else
+                    goto finish16;
+                break;
+            case 17:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x7a ) {
+                    s = 68;
+                    r70 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 67;
+                }
+                else
+                    goto finish17;
+                break;
+            case 18:
+                if ( c == 0x62 ) {
+                    s = 37;
+                }
+                else if ( c == 0x78 ) {
+                    s = 33;
+                }
+                else if ( c == 0x73 ) {
+                    s = 38;
+                }
+                else if ( c == 0x64 ) {
+                    s = 36;
+                }
+                else if ( c == 0x6d ) {
+                    s = 32;
+                }
+                else if ( c == 0x63 ) {
+                    s = 35;
+                }
+                else if ( c == 0x61 ) {
+                    s = 34;
+                }
+                else if ( c == 0x65 ) {
+                    s = 39;
+                }
+                else
+                    return false;
+                break;
+            case 19:
+                if ( c == 0x58 || c == 0x78 ) {
+                    s = 21;
+                }
+                else if ( c == 0x42 || c == 0x62 ) {
+                    s = 22;
+                }
+                else if ( c >= 0x30 && c <= 0x37 || c == 0x5f ) {
+                    s = 23;
+                    r71 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 20;
+                }
+                else
+                    goto finish19;
+                break;
+            case 20:
+                goto finish20;
+            case 21:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c == 0x5f || c >= 0x61 && c <= 0x66 ) {
+                    s = 29;
+                    r72 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 20;
+                }
+                else
+                    goto finish21;
+                break;
+            case 22:
+                if ( c >= 0x30 && c <= 0x31 || c == 0x5f ) {
+                    s = 26;
+                    r73 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 20;
+                }
+                else
+                    goto finish22;
+                break;
+            case 23:
+                if ( c >= 0x30 && c <= 0x37 || c == 0x5f ) {
+                    s = 25;
+                    r74 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 24;
+                }
+                else
+                    goto finish23;
+                break;
+            case 24:
+                goto finish24;
+            case 25:
+                if ( c >= 0x30 && c <= 0x37 || c == 0x5f ) {
+                    s = 25;
+                    r71 = r74;
+                    r74 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 24;
+                    r71 = r74;
+                }
+                else
+                    goto finish25;
+                break;
+            case 26:
+                if ( c >= 0x30 && c <= 0x31 || c == 0x5f ) {
+                    s = 28;
+                    r75 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 27;
+                }
+                else
+                    goto finish26;
+                break;
+            case 27:
+                goto finish27;
+            case 28:
+                if ( c >= 0x30 && c <= 0x31 || c == 0x5f ) {
+                    s = 28;
+                    r73 = r75;
+                    r75 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 27;
+                    r73 = r75;
+                }
+                else
+                    goto finish28;
+                break;
+            case 29:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c == 0x5f || c >= 0x61 && c <= 0x66 ) {
+                    s = 31;
+                    r76 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 30;
+                }
+                else
+                    goto finish29;
+                break;
+            case 30:
+                goto finish30;
+            case 31:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c == 0x5f || c >= 0x61 && c <= 0x66 ) {
+                    s = 31;
+                    r72 = r76;
+                    r76 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 30;
+                    r72 = r76;
+                }
+                else
+                    goto finish31;
+                break;
+            case 32:
+                if ( c == 0x6d ) {
+                    s = 64;
+                }
+                else
+                    return false;
+                break;
+            case 33:
+                if ( c == 0x6d ) {
+                    s = 60;
+                }
+                else
+                    return false;
+                break;
+            case 34:
+                if ( c == 0x78 ) {
+                    s = 48;
+                    r77 = p;
+                }
+                else if ( c == 0x68 || c == 0x6c ) {
+                    s = 53;
+                    r78 = p;
+                }
+                else
+                    return false;
+                break;
+            case 35:
+                if ( c == 0x78 ) {
+                    s = 48;
+                    r77 = p;
+                }
+                else if ( c == 0x64 ) {
+                    s = 55;
+                }
+                else if ( c == 0x68 || c == 0x6c ) {
+                    s = 53;
+                    r78 = p;
+                }
+                else
+                    return false;
+                break;
+            case 36:
+                if ( c == 0x78 ) {
+                    s = 48;
+                    r77 = p;
+                }
+                else if ( c == 0x69 ) {
+                    s = 48;
+                    r77 = p;
+                }
+                else if ( c == 0x68 || c == 0x6c ) {
+                    s = 53;
+                    r78 = p;
+                }
+                else
+                    return false;
+                break;
+            case 37:
+                if ( c == 0x78 ) {
+                    s = 48;
+                    r77 = p;
+                }
+                else if ( c == 0x70 ) {
+                    s = 48;
+                    r77 = p;
+                }
+                else if ( c == 0x68 || c == 0x6c ) {
+                    s = 53;
+                    r78 = p;
+                }
+                else
+                    return false;
+                break;
+            case 38:
+                if ( c == 0x69 ) {
+                    s = 48;
+                    r77 = p;
+                }
+                else if ( c == 0x70 ) {
+                    s = 48;
+                    r77 = p;
+                }
+                else if ( c == 0x74 ) {
+                    s = 49;
+                }
+                else
+                    return false;
+                break;
+            case 39:
+                if ( c == 0x69 ) {
+                    s = 40;
+                }
+                else if ( c == 0x66 ) {
+                    s = 41;
+                }
+                else if ( c == 0x64 ) {
+                    s = 42;
+                }
+                else if ( c == 0x62 ) {
+                    s = 43;
+                }
+                else if ( c == 0x73 ) {
+                    s = 45;
+                }
+                else if ( c == 0x61 || c == 0x63 ) {
+                    s = 44;
+                }
+                else
+                    return false;
+                break;
+            case 40:
+                if ( c == 0x70 ) {
+                    s = 46;
+                    r79 = p;
+                }
+                else
+                    return false;
+                break;
+            case 41:
+                if ( c == 0x6c ) {
+                    s = 46;
+                    r79 = p;
+                }
+                else
+                    return false;
+                break;
+            case 42:
+                if ( c == 0x78 ) {
+                    s = 46;
+                    r79 = p;
+                }
+                else if ( c == 0x69 ) {
+                    s = 46;
+                    r79 = p;
+                }
+                else
+                    return false;
+                break;
+            case 43:
+                if ( c == 0x78 ) {
+                    s = 46;
+                    r79 = p;
+                }
+                else if ( c == 0x70 ) {
+                    s = 46;
+                    r79 = p;
+                }
+                else
+                    return false;
+                break;
+            case 44:
+                if ( c == 0x78 ) {
+                    s = 46;
+                    r79 = p;
+                }
+                else
+                    return false;
+                break;
+            case 45:
+                if ( c == 0x69 ) {
+                    s = 46;
+                    r79 = p;
+                }
+                else if ( c == 0x70 ) {
+                    s = 46;
+                    r79 = p;
+                }
+                else
+                    return false;
+                break;
+            case 46:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 47;
+                }
+                else
+                    goto finish46;
+                break;
+            case 47:
+                goto finish47;
+            case 48:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 52;
+                }
+                else
+                    goto finish48;
+                break;
+            case 49:
+                if ( c >= 0x30 && c <= 0x37 ) {
+                    s = 50;
+                    r80 = p;
+                }
+                else
+                    return false;
+                break;
+            case 50:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 51;
+                }
+                else
+                    goto finish50;
+                break;
+            case 51:
+                goto finish51;
+            case 52:
+                goto finish52;
+            case 53:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 54;
+                }
+                else
+                    goto finish53;
+                break;
+            case 54:
+                goto finish54;
+            case 55:
+                if ( c == 0x65 ) {
+                    s = 56;
+                }
+                else
+                    return false;
+                break;
+            case 56:
+                if ( c == 0x66 ) {
+                    s = 57;
+                }
+                else
+                    return false;
+                break;
+            case 57:
+                if ( c == 0x67 ) {
+                    s = 58;
+                }
+                else
+                    return false;
+                break;
+            case 58:
+                if ( c == 0x73 ) {
+                    s = 59;
+                }
+                else
+                    return false;
+                break;
+            case 59:
+                if ( c == 0x73 ) {
+                    s = 48;
+                    r77 = p;
+                }
+                else
+                    return false;
+                break;
+            case 60:
+                if ( c == 0x6d ) {
+                    s = 61;
+                }
+                else
+                    return false;
+                break;
+            case 61:
+                if ( c >= 0x30 && c <= 0x37 ) {
+                    s = 62;
+                    r81 = p;
+                }
+                else
+                    return false;
+                break;
+            case 62:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 63;
+                }
+                else
+                    goto finish62;
+                break;
+            case 63:
+                goto finish63;
+            case 64:
+                if ( c >= 0x30 && c <= 0x37 ) {
+                    s = 65;
+                    r82 = p;
+                }
+                else
+                    return false;
+                break;
+            case 65:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 66;
+                }
+                else
+                    goto finish65;
+                break;
+            case 66:
+                goto finish66;
+            case 67:
+                goto finish67;
+            case 68:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x7a ) {
+                    s = 68;
+                    r66 = r70;
+                    r70 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 67;
+                    r66 = r70;
+                }
+                else
+                    goto finish68;
+                break;
+            case 69:
+                if ( c == 0x73 ) {
+                    s = 70;
+                    r83 = p;
+                }
+                else if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x7a ) {
+                    s = 68;
+                    r66 = r70;
+                    r70 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 67;
+                    r66 = r70;
+                }
+                else
+                    goto finish69;
+                break;
+            case 70:
+                if ( c == 0x74 ) {
+                    s = 71;
+                    r84 = p;
+                }
+                else if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x7a ) {
+                    s = 68;
+                    r66 = r83;
+                    r70 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 67;
+                    r66 = r83;
+                }
+                else
+                    goto finish70;
+                break;
+            case 71:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x7a ) {
+                    s = 73;
+                    r85 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 72;
+                }
+                else
+                    goto finish71;
+                break;
+            case 72:
+                goto finish72;
+            case 73:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5a || c == 0x5f || c >= 0x61 && c <= 0x7a ) {
+                    s = 68;
+                    r66 = r85;
+                    r70 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 67;
+                    r66 = r85;
+                }
+                else
+                    goto finish73;
+                break;
+            case 74:
+                goto finish74;
+            case 75:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 76;
+                }
+                else
+                    goto finish75;
+                break;
+            case 76:
+                goto finish76;
+            case 77:
+                goto finish77;
+            case 78:
+                goto finish78;
+            case 79:
+                if ( c >= 0x30 && c <= 0x39 || c == 0x5f ) {
+                    s = 79;
+                    r62 = r68;
+                    r68 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 20;
+                    r62 = r68;
+                }
+                else
+                    goto finish79;
+                break;
+            case 80:
+                goto finish80;
+            case 81:
+                if ( c == 0x78 ) {
+                    s = 85;
+                }
+                else if ( c == 0x75 ) {
+                    s = 86;
+                }
+                else if ( c == 0x55 ) {
+                    s = 87;
+                }
+                else if ( c == 0x22 || c == 0x27 || c == 0x3f || c == 0x5c || c >= 0x61 && c <= 0x62 || c == 0x66 || c == 0x6e || c == 0x72 || c == 0x74 || c == 0x76 ) {
+                    s = 88;
+                }
+                else
+                    return false;
+                break;
+            case 82:
+                if ( c == 0x27 ) {
+                    s = 83;
+                    r86 = p;
+                }
+                else
+                    return false;
+                break;
+            case 83:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 84;
+                }
+                else
+                    goto finish83;
+                break;
+            case 84:
+                goto finish84;
+            case 85:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 101;
+                }
+                else
+                    return false;
+                break;
+            case 86:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 97;
+                }
+                else
+                    return false;
+                break;
+            case 87:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 89;
+                }
+                else
+                    return false;
+                break;
+            case 88:
+                if ( c == 0x27 ) {
+                    s = 83;
+                    r86 = p;
+                }
+                else
+                    return false;
+                break;
+            case 89:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 90;
+                }
+                else
+                    return false;
+                break;
+            case 90:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 91;
+                }
+                else
+                    return false;
+                break;
+            case 91:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 92;
+                }
+                else
+                    return false;
+                break;
+            case 92:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 93;
+                }
+                else
+                    return false;
+                break;
+            case 93:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 94;
+                }
+                else
+                    return false;
+                break;
+            case 94:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 95;
+                }
+                else
+                    return false;
+                break;
+            case 95:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 96;
+                }
+                else
+                    return false;
+                break;
+            case 96:
+                if ( c == 0x27 ) {
+                    s = 83;
+                    r86 = p;
+                }
+                else
+                    return false;
+                break;
+            case 97:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 98;
+                }
+                else
+                    return false;
+                break;
+            case 98:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 99;
+                }
+                else
+                    return false;
+                break;
+            case 99:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 100;
+                }
+                else
+                    return false;
+                break;
+            case 100:
+                if ( c == 0x27 ) {
+                    s = 83;
+                    r86 = p;
+                }
+                else
+                    return false;
+                break;
+            case 101:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 102;
+                }
+                else
+                    return false;
+                break;
+            case 102:
+                if ( c == 0x27 ) {
+                    s = 83;
+                    r86 = p;
+                }
+                else
+                    return false;
+                break;
+            case 103:
+                if ( c == 0x78 ) {
+                    s = 108;
+                }
+                else if ( c == 0x75 ) {
+                    s = 109;
+                }
+                else if ( c == 0x55 ) {
+                    s = 110;
+                }
+                else if ( c == 0x22 || c == 0x27 || c == 0x3f || c == 0x5c || c >= 0x61 && c <= 0x62 || c == 0x66 || c == 0x6e || c == 0x72 || c == 0x74 || c == 0x76 ) {
+                    s = 107;
+                }
+                else
+                    return false;
+                break;
+            case 104:
+                if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 106;
+                }
+                else
+                    goto finish104;
+                break;
+            case 105:
+                if ( c == 0x5c ) {
+                    s = 103;
+                }
+                else if ( c == 0x22 ) {
+                    s = 104;
+                    r67 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 105;
+                }
+                else
+                    return false;
+                break;
+            case 106:
+                goto finish106;
+            case 107:
+                if ( c == 0x5c ) {
+                    s = 103;
+                }
+                else if ( c == 0x22 ) {
+                    s = 104;
+                    r67 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 105;
+                }
+                else
+                    return false;
+                break;
+            case 108:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 123;
+                }
+                else
+                    return false;
+                break;
+            case 109:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 119;
+                }
+                else
+                    return false;
+                break;
+            case 110:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 111;
+                }
+                else
+                    return false;
+                break;
+            case 111:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 112;
+                }
+                else
+                    return false;
+                break;
+            case 112:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 113;
+                }
+                else
+                    return false;
+                break;
+            case 113:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 114;
+                }
+                else
+                    return false;
+                break;
+            case 114:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 115;
+                }
+                else
+                    return false;
+                break;
+            case 115:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 116;
+                }
+                else
+                    return false;
+                break;
+            case 116:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 117;
+                }
+                else
+                    return false;
+                break;
+            case 117:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 118;
+                }
+                else
+                    return false;
+                break;
+            case 118:
+                if ( c == 0x5c ) {
+                    s = 103;
+                }
+                else if ( c == 0x22 ) {
+                    s = 104;
+                    r67 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 105;
+                }
+                else
+                    return false;
+                break;
+            case 119:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 120;
+                }
+                else
+                    return false;
+                break;
+            case 120:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 121;
+                }
+                else
+                    return false;
+                break;
+            case 121:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 122;
+                }
+                else
+                    return false;
+                break;
+            case 122:
+                if ( c == 0x5c ) {
+                    s = 103;
+                }
+                else if ( c == 0x22 ) {
+                    s = 104;
+                    r67 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 105;
+                }
+                else
+                    return false;
+                break;
+            case 123:
+                if ( c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x46 || c >= 0x61 && c <= 0x66 ) {
+                    s = 124;
+                }
+                else
+                    return false;
+                break;
+            case 124:
+                if ( c == 0x5c ) {
+                    s = 103;
+                }
+                else if ( c == 0x22 ) {
+                    s = 104;
+                    r67 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 105;
+                }
+                else
+                    return false;
+                break;
+            case 125:
+                goto finish125;
+            case 126:
+                goto finish126;
+            case 127:
+                goto finish127;
+            case 128:
+                goto finish128;
+            case 129:
+                goto finish129;
+            default:
+                assert(0);
+        }
+    }
+
+    switch ( s )
+    {
+        case 1: finish1:
+        case 129: finish129:
+            match = input[0 .. r56];
+            token = 0;
+            break;
+        case 2: finish2:
+        case 128: finish128:
+            match = input[0 .. r57];
+            token = 1;
+            break;
+        case 3: finish3:
+        case 127: finish127:
+            match = input[0 .. r58];
+            token = 2;
+            break;
+        case 4: finish4:
+        case 126: finish126:
+            match = input[0 .. r59];
+            token = 4;
+            break;
+        case 5: finish5:
+        case 125: finish125:
+            match = input[0 .. r60];
+            token = 5;
+            break;
+        case 104: finish104:
+        case 106: finish106:
+            match = input[0 .. r67];
+            token = 16;
+            break;
+        case 8: finish8:
+        case 80: finish80:
+            match = input[0 .. r61];
+            token = 14;
+            break;
+        case 9: finish9:
+        case 19: finish19:
+        case 20: finish20:
+        case 21: finish21:
+        case 22: finish22:
+            match = input[0 .. r62];
+            token = 22;
+            break;
+        case 10: finish10:
+        case 78: finish78:
+            match = input[0 .. r63];
+            token = 15;
+            break;
+        case 11: finish11:
+        case 77: finish77:
+            match = input[0 .. r64];
+            token = 27;
+            break;
+        case 12: finish12:
+        case 74: finish74:
+            match = input[0 .. r65];
+            token = 3;
+            break;
+        case 13: finish13:
+        case 14: finish14:
+        case 15: finish15:
+        case 16: finish16:
+        case 17: finish17:
+        case 67: finish67:
+            match = input[0 .. r66];
+            token = 18;
+            break;
+        case 23: finish23:
+        case 24: finish24:
+            match = input[0 .. r71];
+            token = 21;
+            break;
+        case 25: finish25:
+            match = input[0 .. r74];
+            token = 21;
+            break;
+        case 26: finish26:
+        case 27: finish27:
+            match = input[0 .. r73];
+            token = 20;
+            break;
+        case 28: finish28:
+            match = input[0 .. r75];
+            token = 20;
+            break;
+        case 29: finish29:
+        case 30: finish30:
+            match = input[0 .. r72];
+            token = 19;
+            break;
+        case 31: finish31:
+            match = input[0 .. r76];
+            token = 19;
+            break;
+        case 46: finish46:
+        case 47: finish47:
+            match = input[0 .. r79];
+            token = 7;
+            break;
+        case 48: finish48:
+        case 52: finish52:
+            match = input[0 .. r77];
+            token = 8;
+            break;
+        case 50: finish50:
+        case 51: finish51:
+            match = input[0 .. r80];
+            token = 10;
+            break;
+        case 53: finish53:
+        case 54: finish54:
+            match = input[0 .. r78];
+            token = 9;
+            break;
+        case 62: finish62:
+        case 63: finish63:
+            match = input[0 .. r81];
+            token = 12;
+            break;
+        case 65: finish65:
+        case 66: finish66:
+            match = input[0 .. r82];
+            token = 11;
+            break;
+        case 68: finish68:
+        case 69: finish69:
+            match = input[0 .. r70];
+            token = 18;
+            break;
+        case 70: finish70:
+            match = input[0 .. r83];
+            token = 18;
+            break;
+        case 71: finish71:
+        case 72: finish72:
+            match = input[0 .. r84];
+            token = 13;
+            break;
+        case 73: finish73:
+            match = input[0 .. r85];
+            token = 18;
+            break;
+        case 75: finish75:
+        case 76: finish76:
+            match = input[0 .. r69];
+            token = 6;
+            break;
+        case 79: finish79:
+            match = input[0 .. r68];
+            token = 22;
+            break;
+        case 83: finish83:
+        case 84: finish84:
+            match = input[0 .. r86];
+            token = 17;
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+// ((?[\t\n\r ]+)).*?
+bool wsLexer(string input, out uint token, out string match)
+{
+    uint s = 0;
+    static int r2=-1, r3=-1;
+
+    for ( size_t p = 0, q = 0, p_end = input.length; p < p_end; q = p )
+    {
+        dchar c = cast(dchar)input[p];
+        if ( c & 0x80 )
+            decode(input, p);
+        else
+            ++p;
+        switch ( s )
+        {
+            case 0:
+                if ( c >= 0x9 && c <= 0xa || c == 0xd || c == 0x20 ) {
+                    s = 1;
+                    r2 = p;
+                }
+                else
+                    return false;
+                break;
+            case 1:
+                if ( c >= 0x9 && c <= 0xa || c == 0xd || c == 0x20 ) {
+                    s = 3;
+                    r3 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 2;
+                }
+                else
+                    goto finish1;
+                break;
+            case 2:
+                goto finish2;
+            case 3:
+                if ( c >= 0x9 && c <= 0xa || c == 0xd || c == 0x20 ) {
+                    s = 3;
+                    r2 = r3;
+                    r3 = p;
+                }
+                else if ( c >= 0x9 && c <= 0x13 || c >= 0x20 && c <= 0x7e || c >= 0xa0 && c <= 0x24f || c >= 0x20a3 && c <= 0x20b5 ) {
+                    s = 2;
+                    r2 = r3;
+                }
+                else
+                    goto finish3;
+                break;
+            default:
+                assert(0);
+        }
+    }
+
+    switch ( s )
+    {
+        case 1: finish1:
+        case 2: finish2:
+            match = input[0 .. r2];
+            token = 0;
+            break;
+        case 3: finish3:
+            match = input[0 .. r3];
+            token = 0;
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+// generated code end
+
+#line 2996 "D:\src\ddbg_continued\src\expression\expression_apd.d"
+// Written in the D programming language
+
+/*
+ *  This file has been automatically generated by APaGeD v0.4.2 beta - Attributed Parser Generator for D.
+ *
+ *  Sections generated from custom input are marked as "generated code" and
+ *  are subject to the terms and conditions stated in one of these sections.
+ *  The remaining sections are part of the APaGeD package and subject
+ *  to the terms and conditions of the corresponding license.
+ *
+ *  Attributed Parser Generator for D
+ *  Copyright (c) 2007 Jascha Wetzel. All rights reserved
+ *  License: Artistic License 2.0
+ */
+
+
+version(Tango)
+{
+    import tango.text.convert.Layout;
+    import tango.text.Util;
+    import tango.io.Stdout;
+
+    private static Layout!(char) layout;
+
+    static this()
+    {
+        layout = new Layout!(char);
+    }
+
+    string format(string fmt, ...)
+    {
+        return layout.convert(_arguments, _argptr, fmt);
+    }
+
+    alias char[] string;
+}
+else
+{
+    import std.string;
+    import std.utf;
+    debug import std.stdio;
+}
+
+
+
+/**************************************************************************************************
+    Parser
+**************************************************************************************************/
+
+typedef uint Token;
+alias Token Symbol;
+
+const Token     EPSILON         = 1,
+                ALTERN          = 2,
+                EOS             = 3,
+                FIRST_TOKEN     = 4,
+                FIRST_NT        = 0x1000;
+
+// generated code start
+/*  Attributed Parser Generator for D
+ *  Copyright (c) 2007 Jascha Wetzel. All rights reserved
+ *  License: Artistic License 2.0, see license.txt
+ */
+
+const uint  MAX_INPUT_DUMP = 70,
+            LR_STACK_RESERVE = 100,
+            NODE_STACK_RESERVE = 20,
+            BRANCH_STACK_RESERVE = 100;
+
+/*******************************************************************************
+    Stack based on dynamic array
+*******************************************************************************/
+struct Stack(T)
+{
+    size_t  _top;
+    T[]     stack;
+
+    void push(T v)
+    {
+        if ( _top >= stack.length )
+            stack.length = stack.length*2+1;
+        stack[_top] = v;
+        ++_top;
+    }
+
+    void push(T[] vs)
+    {
+        size_t end = _top+vs.length;
+        if ( end > stack.length )
+            stack.length = end*2;
+        stack[_top..end] = vs;
+        _top = end;
+    }
+    alias push opCatAssign;
+
+    void pop(size_t num)
+    {
+        assert(_top>=num);
+        if ( num >= _top )
+            _top = 0;
+        else
+            _top -= num;
+    }
+
+    T pop()
+    {
+        assert(_top>0);
+        return stack[--_top];
+    }
+
+    T* popPtr()
+    {
+        assert(_top>0);
+        return &stack[--_top];
+    }
+
+    T top()
+    {
+        assert(_top>0);
+        return stack[_top-1];
+    }
+
+    T* topPtr()
+    {
+        assert(_top>0);
+        return &stack[_top-1];
+    }
+
+    bool empty()
+    {
+        return _top == 0;
+    }
+
+    void clear()
+    {
+        _top = 0;
+    }
+
+    size_t length()
+    {
+        return _top;
+    }
+
+    T[] array()
+    {
+        return stack[0.._top];
+    }
+
+    Stack dup()
+    {
+        Stack s;
+        s._top = _top;
+        s.stack = stack.dup;
+        return s;
+    }
+}
+
+/**************************************************************************************************
+    Information about rules needed for reduction and error handling
+**************************************************************************************************/
+align(1) struct RuleInfo
+{
+    bool    ast_node;
+    uint    symbol_count,
+            nt_count,
+            nt_index;
+    Symbol[]  symbols;
+}
+
+/**************************************************************************************************
+    Information about LALR(1) entries needed for debugging
+**************************************************************************************************/
+align(1) struct EntryInfo
+{
+    uint    rule_index,
+            pos;
+}
+
+/**************************************************************************************************
+    Exception thrown on parser error
+**************************************************************************************************/
+class ParserException : Exception
+{
+    uint    line,
+            column;
+    string  filename,
+            error_message,
+            detail;
+
+    this(uint line_, uint column_, string fname, string msg, string dtl="detail")
+    {
+        version(Tango)
+            super(format("{}({}:{}): {}{}", fname, line_, column_, msg, dtl !is null?"\n"~dtl:""));
+        else
+            super(format("%s(%d:%d): %s%s", fname, line_, column_, msg, dtl !is null?"\n"~dtl:""));
+        filename = fname;
+        error_message = msg;
+        line = line_;
+        column = column_;
+        detail = dtl;
+    }
+}
+
+/**************************************************************************************************
+    Wraps instantiation of the GLR parser class and the parse call.
+**************************************************************************************************/
+bool parse(string filename, string input, out SyntaxTree* root, bool detailed=false, bool recover=false, uint tab_width=4)
+{
+    GLRParser   g, w;
+    static if ( is(typeof(WhitespaceGrammar) : GLRParser) )
+        w = new WhitespaceGrammar;
+    g = new MainGrammar(w, tab_width);
+    bool succ = g.parse(filename, input, &root, detailed, recover);
+    return succ;
+}
+
+/**************************************************************************************************
+    GLR parser
+**************************************************************************************************/
+abstract class GLRParser
+{
+    struct LRState
+    {
+        uint    index,
+                line,
+                column;
+    }
+    
+    struct Node
+    {
+        SyntaxTree* node;
+        bool        sync;
+    }
+
+    struct LRBranch
+    {
+        Stack!(LRState) stack;
+        Stack!(Node)    node_stack;
+        string          input,
+                        lookahead,
+                        lookahead_ws;
+        uint            line,
+                        column,
+                        symbol;
+        bool            fatal_errors;
+        uint            action;
+        version(ProfileConflicts)
+            uint            last_conflict;
+    }
+    
+    string          filename;
+    uint            tab_width;
+    
+    // operational variables
+    string              match,
+                        match_ws,
+                        lookahead,
+                        lookahead_ws;
+    SyntaxTree*         syntax_root;
+    SyntaxTree[]        syntax_tree_pool;
+    size_t              pool_top;
+    Stack!(LRState)     stack;
+    Stack!(Node)        node_stack;
+    Stack!(LRBranch)    branch_stack;
+    ParserException[]   recovered_errors;
+    bool                recover_from_errors,
+                        detailed_errors;
+
+    version(ProfileConflicts) {
+        uint[uint]      rr_conflict_counts,
+                        sr_conflict_counts,
+                        shift_failed_counts,
+                        reduce_failed_counts;
+        uint            branch_stack_max;
+    }
+
+    // grammar data
+    GLRParser       ws_parser;
+    uint            first_nt;
+    RuleInfo[]      rule_infos;
+    string[][]      error_message_lists;
+    string[]        nt_names,
+                    lexeme_names;
+    EntryInfo[][]   entry_infos;
+
+    this(GLRParser ws, uint tabw)
+    {
+        ws_parser = ws;
+        tab_width = tabw;
+        stack.stack.length = LR_STACK_RESERVE;
+        node_stack.stack.length = NODE_STACK_RESERVE;
+        branch_stack.stack.length = BRANCH_STACK_RESERVE;
+    }
+
+    /**************************************************************************************************
+        Gets overridden with a first-longest-match lexical analizer.
+    **************************************************************************************************/
+    bool function(string, out uint, out string) lexer;
+
+    /**************************************************************************************************
+        Gets overridden with the main parser function.
+    **************************************************************************************************/
+    bool parse(string input) { return false; }
+    bool parseWS(ref string input) { return false; }
+
+    /**************************************************************************************************
+
+    **************************************************************************************************/
+    bool isErrorSynced(uint state);
+
+    /**************************************************************************************************
+
+    **************************************************************************************************/
+    T APDmin(T)(T a, T b) { return a<b?a:b; }
+    uint[] lookaheadForNT(uint nt_index, uint state);
+
+    /**************************************************************************************************
+        Count lines and columns in str
+    **************************************************************************************************/
+    uint countLocation(string str, ref uint col)
+    {
+        uint count;
+        dchar linefeed;
+        foreach ( c; str )
+        {
+            if ( c == 10 || c == 13 )
+            {
+                if ( linefeed == dchar.init || linefeed == c ) {
+                    ++count;
+                    col = 1;
+                    linefeed = c;
+                }
+                else
+                    linefeed = dchar.init;
+            }
+            else if ( c == 9 ) {
+                col += tab_width;
+                linefeed = dchar.init;
+            }
+            else {
+                ++col;
+                linefeed = dchar.init;
+            }
+        }
+        return count;
+    }
+
+    /**************************************************************************************************
+        Initiates the parse call.
+    **************************************************************************************************/
+    final bool parse(string fname, string input, SyntaxTree** root=null, bool detailed=false, bool recover=false)
+    {
+        filename = fname;
+        recover_from_errors = recover;
+        detailed_errors = detailed;
+
+        stack.clear;
+        node_stack.clear;
+        branch_stack.clear;
+        pool_top = 0;
+        syntax_tree_pool = null;
+        recovered_errors = null;
+
+        if ( input.length > 1 )
+        {
+            if ( input[0 .. 2] == "\xfe\xff" ) {
+                // UTF-16BE
+                input = input[2 .. $];
+            }
+            else if ( input[0 .. 2] == "\xff\xfe" )
+            {
+                if ( input.length > 3 && input[2 .. 4] == "\x00\x00" ) {
+                    // UTF-32LE
+                    input = input[4 .. $];
+                }
+                else {
+                    // UTF-16LE
+                    input = input[2 .. $];
+                }
+            }
+            else if ( input.length > 2 && input[0 .. 3] == "\xef\xbb\xbf" ) {
+                // UTF-8
+                input = input[3 .. $];
+            }
+            else if ( input.length > 3 && input[0 .. 4] == "\x00\x00\xfe\xff" ) {
+                // UTF-32BE
+                input = input[4 .. $];
+            }
+            else if ( input[0] > 0x7f )
+                return false;
+        }
+        
+        stack ~= LRState(0, 1, 1);
+        if ( parse(input) )
+        {
+            if ( syntax_root !is null && root !is null )
+            {
+                *root = syntax_root;
+                debug
+                {
+                    Stack!(SyntaxTree*) st;
+                    st.push(*root);
+                    while ( !st.empty )
+                    {
+                        SyntaxTree* pn = st.pop;
+                        foreach ( c; pn._ST_children ) {
+                            c.parent = pn;
+                            st.push(c);
+                        }
+                    }
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**************************************************************************************************
+        Create a node for the syntax tree. Used by the main parse function.
+    **************************************************************************************************/
+    debug void createNode(uint line, uint column, uint rule_index, uint nt_count, uint nt_index)
+    {
+        if ( pool_top >= syntax_tree_pool.length )
+            syntax_tree_pool.length = syntax_tree_pool.length*2+1;
+        auto pn = &syntax_tree_pool[pool_top];
+        ++pool_top;
+        pn._ST_rule = rule_index;
+        pn._ST_line_number = line;
+        pn._ST_column_number = column;
+        pn._ST_node_name = nt_names[nt_index];
+
+        if ( nt_count > 0 )
+        {
+            pn._ST_children.length = nt_count;
+            foreach ( i, n; node_stack.array[$-nt_count .. $] )
+                pn._ST_children[i] = n.node;
+            node_stack.pop(nt_count);
+        }
+        else {
+            pn._ST_match = match;
+            pn._ST_match_ws = match_ws;
+        }
+        node_stack ~= Node(pn, false);
+    }
+
+    else void createNode(uint line, uint column, uint rule_index, uint nt_count)
+    {
+        if ( pool_top >= syntax_tree_pool.length )
+            syntax_tree_pool.length = syntax_tree_pool.length*2+1;
+        auto pn = &syntax_tree_pool[pool_top];
+        ++pool_top;
+        pn._ST_rule = rule_index;
+        pn._ST_line_number = line;
+        pn._ST_column_number = column;
+
+        if ( nt_count > 0 )
+        {
+            pn._ST_children.length = nt_count;
+            foreach ( i, n; node_stack.array[$-nt_count .. $] )
+                pn._ST_children[i] = n.node;
+            node_stack.pop(nt_count);
+        }
+        else {
+            pn._ST_match = match;
+            pn._ST_match_ws = match_ws;
+        }
+        node_stack ~= Node(pn, false);
+    }
+
+    /**************************************************************************************************
+
+    **************************************************************************************************/
+    string ruleToString(RuleInfo* ri, int pos)
+    {
+        version(Tango)
+            string str = format("{} ->", nt_names[ri.nt_index]);
+        else
+            string str = format("%s ->", nt_names[ri.nt_index]);
+        
+        foreach ( i, s; ri.symbols )
+        {
+            string name;
+            if ( s == ALTERN )
+                name = "ALTERN";
+            else if ( s < FIRST_NT )
+                name = lexeme_names[s-EOS];
+            else
+                name = nt_names[s-FIRST_NT];
+            if ( i == pos )
+                str ~= " .";
+            version(Tango)
+                str ~= format(" {}", name);
+            else
+                str ~= format(" %s", name);
+        }
+        if ( pos == ri.symbols.length )
+            str ~= " .";
+        return str;
+    }
+
+    /**************************************************************************************************
+        Issue an error. Used by the main parse function.
+    **************************************************************************************************/
+    void error(string input, uint line, uint column, uint error_list, uint symbol, bool fatal=true)
+    {
+        // collect explicit error messages
+        string errors;
+        foreach ( i, err; error_message_lists[error_list] )
+        {
+            if ( i > 0 )
+                errors ~= "\n";
+            errors ~= err;
+        }
+
+        // construct automatic error message
+        // if no explicit error message available
+        if ( errors.length == 0 )
+        {
+            bool[string] expected_symbols;
+            EntryInfo[] eis = entry_infos[stack.top.index];
+            foreach ( ei; eis )
+            {
+                RuleInfo* ri = &rule_infos[ei.rule_index];
+                if ( ei.pos < ri.symbols.length )
+                {
+                    auto s = ri.symbols[ei.pos];
+                    if ( s < FIRST_NT )
+                        expected_symbols["\""~lexeme_names[s-EOS]~"\""] = true;
+                    else
+                        expected_symbols[nt_names[s-FIRST_NT]] = true;
+                }
+                else
+                {
+                    foreach ( token; lookaheadForNT(ri.nt_index, stack.top.index) ) {
+                        assert(token < FIRST_NT);
+                        expected_symbols["\""~lexeme_names[token-EOS]~"\""] = true;
+                    }
+                }
+            }
+
+            string expected_str;
+            auto last = expected_symbols.length-1;
+            foreach ( i, symname; expected_symbols.keys )
+            {
+                if ( i > 0 )
+                {
+                    if ( i == last )
+                        expected_str ~= " or ";
+                    else 
+                        expected_str ~= ", ";
+                }
+                expected_str ~= symname;
+            }
+            version(Tango)
+                errors = format("found \"{}\", expected {}", lookahead, expected_str);
+            else
+                errors = format("found \"%s\", expected %s", lookahead, expected_str);
+        }
+
+        // construct detail message
+        string detail;
+        if ( detailed_errors )
+        {
+            string          lr_stack;
+            foreach ( st; stack.array[1..$] )
+            {
+                version(Tango)
+                    lr_stack ~= format("---- State {}{} ({}:{}) ----\n", st.index, isErrorSynced(st.index)?"*":"", st.line, st.column);
+                else
+                    lr_stack ~= format("---- State %d%s (%d:%d) ----\n", st.index, isErrorSynced(st.index)?"*":"", st.line, st.column);
+                EntryInfo[] eis = entry_infos[st.index];
+                foreach ( ei; eis )
+                    lr_stack ~= ruleToString(&rule_infos[ei.rule_index], ei.pos)~"\n";
+            }
+            
+            string node_stack_str;
+            foreach ( i, n; node_stack.array )
+            {
+                if ( i > 0 )
+                    node_stack_str ~= " ";
+                node_stack_str ~= nt_names[rule_infos[n.node._ST_rule].nt_index];
+                if ( n.sync )
+                    node_stack_str ~= "*";
+            }
+
+            version(Tango)
+                detail = format("input: {}\nlookahead: {}\nlexeme: {}\nAST node stack:\n{}\nLR stack:\n{}",
+                    substitute(substitute(input[0..$>MAX_INPUT_DUMP?MAX_INPUT_DUMP:$], "\r", "\\r"), "\n", "\\n"),
+                    lookahead, lexeme_names[symbol-EOS],
+                    node_stack_str, lr_stack
+                );
+            else
+                detail = format("input: %s\nlookahead: %s\nlexeme: %s\nAST node stack:\n%s\nLR stack:\n%s",
+                    replace(replace(input[0..$>MAX_INPUT_DUMP?MAX_INPUT_DUMP:$], "\r", "\\r"), "\n", "\\n"),
+                    lookahead, lexeme_names[symbol-EOS],
+                    node_stack_str, lr_stack
+                );
+        }
+
+        // throw error
+        if ( fatal ) {
+            version(Tango) Stdout.flush;
+            throw new ParserException(line, column-lookahead.length, filename, errors, detail);
+        }
+        else
+        {
+            version(Tango)
+                debug(nonfatal) Stdout.flush.format("\n{}({}:{}): {}\n{}\n", filename, line, column-lookahead.length, errors, detail);
+            else
+                debug(nonfatal) writefln("\n%s(%d:%d): %s\n%s", filename, line, column-lookahead.length, errors, detail);
+        }
+    }
+}
+
+/**************************************************************************************************
+    Generated parsers
+**************************************************************************************************/
+class MainGrammar : public GLRParser
+{
+    const ushort[]  action_base =
+    [
+        0,23,45,0,67,96,125,154,171,198,222,228,245,273,277,291,305,319,347,375,381,389,7,397,414,
+        443,0,36,45,67,472,198,1,219,221,501,529,535,552,580,279,586,284,595,624,653,236,8,333,682,
+        0,711,9,740,543,769,771,779,781,789,791,799,801,809,811,819,821,829,831,71,839,844,852,142,
+        854,862,864,883,5,891,6,893,901,903
+    ];
+    const ubyte[]  action_check =
+    [
+        3,0,0,26,32,84,50,50,0,0,0,0,0,0,0,52,26,0,0,0,0,0,0,0,1,1,22,47,0,78,80,1,1,1,1,1,1,1,84,
+        27,1,1,1,1,1,1,1,2,28,84,84,1,27,2,2,2,2,2,2,2,84,28,2,2,2,2,2,2,2,4,29,84,84,2,84,4,4,4,4,
+        4,4,4,84,29,4,4,4,4,4,4,4,69,69,69,69,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+        5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,84,7,7,7,7,7,73,73,
+        73,73,84,84,84,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,31,84,84,84,
+        84,9,9,9,9,9,9,84,84,31,9,9,9,9,9,9,9,33,10,34,10,9,10,10,11,84,11,84,11,11,33,46,34,10,46,
+        46,46,46,46,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
+        12,12,12,12,13,84,13,14,13,13,14,84,40,14,14,40,84,42,84,13,42,15,84,14,15,40,84,15,15,84,
+        42,14,14,14,14,16,84,15,16,84,84,16,16,84,84,15,15,15,15,17,84,16,17,84,84,17,17,84,84,16,
+        16,16,16,48,84,17,48,48,48,48,48,84,84,17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,18,
+        18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,19,84,19,84,19,19,20,84,20,20,20,20,84,84,
+        21,19,21,21,21,21,20,20,23,84,23,23,23,23,21,21,84,84,84,84,84,84,23,23,24,24,24,24,24,24,
+        24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,
+        25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,30,30,30,30,30,30,30,30,
+        30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,35,35,35,35,35,35,35,35,35,
+        35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,36,84,36,84,36,36,37,84,37,84,
+        37,37,84,54,84,36,54,54,54,54,54,37,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
+        38,38,38,38,38,38,38,38,38,38,38,39,84,39,84,39,39,41,84,41,84,41,41,84,84,84,39,43,84,84,
+        84,84,41,43,43,43,43,43,43,84,84,84,43,43,43,43,43,43,43,84,84,84,84,43,44,44,44,44,44,44,
+        44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,
+        45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,49,49,49,49,49,49,49,49,
+        49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,51,51,51,51,51,51,51,51,51,
+        51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,53,53,53,53,53,53,53,53,53,53,
+        53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,55,84,56,55,84,56,55,55,56,56,57,
+        84,58,57,84,58,57,57,58,58,59,84,60,59,84,60,59,59,60,60,61,84,62,61,84,62,61,61,62,62,63,
+        84,64,63,84,64,63,63,64,64,65,84,66,65,84,66,65,65,66,66,67,84,68,67,84,68,67,67,68,68,70,
+        84,84,70,84,71,70,70,71,71,71,71,71,72,84,74,72,84,74,72,72,74,74,75,84,76,75,84,76,75,75,
+        76,76,84,84,84,84,84,84,74,74,74,74,84,77,84,84,77,75,75,77,77,79,84,81,79,84,81,79,79,81,
+        81,82,84,83,82,84,83,82,82,83,83
+    ];
+    const ushort[]  action_data =
+    [
+        0,129,258,295,287,384,267,179,258,258,258,258,258,258,258,266,295,258,258,258,258,258,258,
+        258,129,258,135,135,258,207,209,258,258,258,258,258,258,258,384,296,258,258,258,258,258,
+        258,258,257,289,384,384,258,296,257,257,257,257,257,257,257,384,289,257,257,257,257,257,
+        257,257,276,288,384,384,257,384,276,276,276,276,276,276,133,384,158,276,276,276,276,276,
+        276,276,311,311,311,311,276,385,385,134,385,385,385,385,385,385,385,385,385,385,385,385,
+        385,385,385,385,385,385,385,385,385,385,385,385,385,385,386,386,386,386,386,386,386,386,
+        386,386,386,386,386,386,386,386,386,386,386,135,386,386,386,386,386,386,386,386,386,297,
+        297,384,297,297,297,297,297,142,143,144,145,384,384,384,297,297,387,387,387,137,387,387,
+        387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
+        387,275,288,384,384,384,384,275,275,275,275,275,275,384,384,158,275,275,275,275,275,275,
+        275,290,139,294,280,275,140,280,281,384,281,384,281,281,290,265,294,280,265,175,177,265,
+        265,281,388,388,388,388,388,388,141,388,388,388,388,388,388,388,388,388,388,388,388,135,
+        142,143,144,145,388,388,388,388,388,282,384,282,300,282,282,300,384,277,300,300,277,384,
+        279,384,282,279,301,384,300,301,277,384,301,301,384,279,300,300,300,300,302,384,301,302,
+        384,384,302,302,384,384,301,301,301,301,303,384,302,303,384,384,303,303,384,384,302,302,
+        302,302,265,384,303,265,175,177,265,265,384,384,303,303,303,303,389,389,389,389,389,389,
+        147,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,
+        389,284,384,284,384,284,284,298,384,298,298,298,298,384,384,286,284,286,150,286,286,298,
+        298,299,384,299,299,299,299,152,286,384,384,384,384,384,384,299,299,385,385,153,385,385,
+        385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
+        385,385,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390,154,155,135,
+        142,143,144,145,390,390,390,390,390,391,391,391,391,391,391,391,391,391,391,391,391,391,
+        391,391,391,391,154,155,135,142,143,144,145,391,391,391,391,391,387,387,387,164,387,387,
+        387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
+        387,285,384,285,384,285,285,278,384,278,384,278,278,384,265,384,285,265,175,177,265,265,
+        278,389,389,389,389,389,389,167,389,389,389,389,389,389,389,389,389,389,389,389,389,389,
+        389,389,389,389,389,389,389,389,283,384,283,384,283,283,139,384,280,384,140,280,384,384,
+        384,283,172,384,384,384,384,280,186,187,188,189,190,191,384,384,384,192,193,135,312,312,
+        312,312,384,384,384,384,197,392,129,258,392,392,392,392,392,258,258,258,258,258,258,258,
+        392,392,258,258,258,258,258,258,258,392,392,392,392,258,387,387,387,174,387,387,387,387,
+        387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,393,
+        129,258,393,393,393,393,393,258,258,258,258,258,258,258,393,393,258,258,258,258,258,258,
+        258,393,393,393,393,258,394,129,258,394,394,394,394,394,258,258,258,258,258,258,258,394,
+        394,258,258,258,258,258,258,258,394,394,394,394,258,389,389,389,389,389,389,182,389,389,
+        389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,264,384,
+        263,264,384,263,264,264,263,263,260,384,269,260,384,269,260,260,269,269,270,384,271,270,
+        384,271,270,270,271,271,272,384,273,272,384,273,272,272,273,273,274,384,292,274,384,292,
+        274,274,292,292,293,384,256,293,384,256,293,293,256,256,259,384,268,259,384,268,259,259,
+        268,268,262,384,384,262,384,265,262,262,265,175,177,265,265,261,384,310,261,384,310,261,
+        261,310,310,308,384,304,308,384,304,308,308,304,304,384,384,384,384,384,384,203,206,208,
+        210,384,305,384,384,305,204,205,305,305,306,384,307,306,384,307,306,306,307,307,309,384,
+        291,309,384,291,309,309,291,291
+    ];
+    const ubyte[]  goto_base =
+    [
+        0,1,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,2,2,0,0,16,0,0,0,2,28,3,0,0,0,0,0,0,0,0,0,16,0,46,
+        3,0,2,3,3,39,0,28,0,0,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,0,22,29,0,0,0,0,0,0,0,0,0
+    ];
+    const ubyte[]  goto_check =
+    [
+        0,0,1,44,44,46,48,4,6,6,10,10,12,12,21,29,31,6,6,22,47,12,12,12,25,25,41,41,51,51,25,54,25,
+        25,25,25,30,30,71,49,49,73,30,49,30,30,30,30,43,74,84,43,43,84,84,84,84,84,84,84,84,43,84,
+        43,84,84,84,43
+    ];
+    const ubyte[]  goto_data =
+    [
+        3,4,2,45,4,57,56,43,8,10,40,41,18,10,37,35,32,20,21,23,48,20,21,38,28,10,42,41,52,4,29,55,
+        33,20,21,34,28,10,72,50,4,74,31,53,33,20,21,34,66,83,84,67,68,84,84,84,84,84,84,84,84,70,
+        84,71,84,84,84,73
+    ];
+
+    debug(parser) string indent;
+    
+    this(GLRParser ws=null, uint tab_width=4)
+    {
+        super(ws, tab_width);
+        lexer = &mainLexer;
+        first_nt = 32;
+        nt_names =
+        [
+            "Expr","Deref","DotChain","RefExpr","Args","Register","RegName","Cast","Type",
+            "BaseType","QuantList","Quantifier","TplParams","TplParams2","TplParam","Lit","StrLit",
+            "Ident","FQNIdent","Integer","IntegerSuffix","Sign","!LRstart"
+        ];
+        lexeme_names =
+        [
+            "EOS","\\*","\\(","\\)","\\.","\\[","\\]","\\.\\.","#(e[abcd]x|e[ds]i|e[bs]p|eip|efl)",
+            "#([abcd]x|[ds]i|[bs]p|(cdefgs)s)","#[abcd][hl]","#st[0-7]","#mm[0-7]","#xmm[0-7]",
+            "cast","!",",",
+            "\"(([^\"\\\\]*(\\\\(['\"\\?\\\\abfnrtv]|(x[0-9a-fA-F]{2})|(u[0-9a-fA-F]{4})|(U[0-9a-fA-F]{8})))?)*)\"",
+            "'(([^'\\\\]|(\\\\(['\"\\?\\\\abfnrtv]|(x[0-9a-fA-F]{2})|(u[0-9a-fA-F]{4})|(U[0-9a-fA-F]{8})))))'",
+            "[a-zA-Z_][_a-zA-Z0-9]*","0[xX][0-9a-fA-F_]+","0[bB][01_]+","0[0-7_]+",
+            "0|([1-9][0-9_]*)","L","u","U","[uU]","\\-"
+        ];
+        entry_infos =
+        [
+            cast(EntryInfo[])[EntryInfo(2,0)],[EntryInfo(1,1),EntryInfo(2,0)],[EntryInfo(1,2)],[EntryInfo(57,1)],[
+            EntryInfo(0,1),EntryInfo(20,0)],[EntryInfo(19,1)],[EntryInfo(19,2)],[EntryInfo(41,1)],[EntryInfo(19,3)],[
+            EntryInfo(19,4)],[EntryInfo(21,1),EntryInfo(24,0)],[EntryInfo(25,1)],[EntryInfo(26,1),EntryInfo(27,1)
+            ,EntryInfo(28,1)],[EntryInfo(26,2)],[EntryInfo(44,1)],[EntryInfo(45,1)],[EntryInfo(46,1)],[
+            EntryInfo(47,1)],[EntryInfo(28,2)],[EntryInfo(28,3)],[EntryInfo(42,1)],[EntryInfo(22,1),EntryInfo(43,1)
+            ,EntryInfo(30,0)],[EntryInfo(43,2)],[EntryInfo(43,3)],[EntryInfo(29,1)],[EntryInfo(29,2)],[
+            EntryInfo(39,1)],[EntryInfo(40,1)],[EntryInfo(33,1)],[EntryInfo(29,3),EntryInfo(32,0)],[
+            EntryInfo(31,1)],[EntryInfo(31,2),EntryInfo(32,0)],[EntryInfo(31,3)],[EntryInfo(34,1)],[
+            EntryInfo(38,1)],[EntryInfo(29,4)],[EntryInfo(29,5)],[EntryInfo(22,2)],[EntryInfo(27,2)],[
+            EntryInfo(27,3)],[EntryInfo(21,2)],[EntryInfo(23,1),EntryInfo(24,0)],[EntryInfo(23,2)],[
+            EntryInfo(0,2),EntryInfo(56,0)],[EntryInfo(4,1),EntryInfo(2,0)],[EntryInfo(4,2)],[EntryInfo(4,3)
+            ,EntryInfo(9,0)],[EntryInfo(7,1)],[EntryInfo(7,2),EntryInfo(9,0)],[EntryInfo(8,1),EntryInfo(2,0)],[
+            EntryInfo(10,1),EntryInfo(11,1)],[EntryInfo(10,2),EntryInfo(2,0)],[EntryInfo(10,3)],[EntryInfo(8,2)],[
+            EntryInfo(8,3),EntryInfo(9,0)],[EntryInfo(8,4)],[EntryInfo(7,3)],[EntryInfo(4,4)],[EntryInfo(13,1)],[
+            EntryInfo(14,1)],[EntryInfo(15,1)],[EntryInfo(16,1)],[EntryInfo(17,1)],[EntryInfo(18,1)],[
+            EntryInfo(36,1)],[EntryInfo(37,1)],[EntryInfo(0,3)],[EntryInfo(3,1)],[EntryInfo(12,1)],[
+            EntryInfo(55,1)],[EntryInfo(6,1)],[EntryInfo(5,1),EntryInfo(9,0)],[EntryInfo(5,2)],[EntryInfo(35,1)],[
+            EntryInfo(35,2),EntryInfo(54,0)],[EntryInfo(48,1),EntryInfo(49,1),EntryInfo(52,1)],[EntryInfo(48,2)],[
+            EntryInfo(49,2)],[EntryInfo(50,1)],[EntryInfo(50,2)],[EntryInfo(51,1)],[EntryInfo(51,2)],[
+            EntryInfo(53,1)],[EntryInfo(35,3)]
+        ];
+        rule_infos =
+        [
+            RuleInfo(true,3,3,0,[4097,4103,4098]),RuleInfo(true,2,1,1,[4,4097]),
+            RuleInfo(true,0,0,1,[]),RuleInfo(true,1,1,2,[4101]),RuleInfo(true,4,2,2,[5,4096,6,4099]),
+            RuleInfo(true,2,2,2,[4113,4099]),RuleInfo(true,1,1,2,[4111]),RuleInfo(true,3,2,3,[7,4113,4099]),
+            RuleInfo(true,4,2,3,[8,4100,9,4099]),RuleInfo(true,0,0,3,[]),RuleInfo(true,3,2,4,[4096,10,4096]),
+            RuleInfo(true,1,1,4,[4096]),RuleInfo(true,1,1,5,[4102]),RuleInfo(true,1,0,6,[11]),
+            RuleInfo(true,1,0,6,[12]),RuleInfo(true,1,0,6,[13]),RuleInfo(true,1,0,6,[14]),
+            RuleInfo(true,1,0,6,[15]),RuleInfo(true,1,0,6,[16]),RuleInfo(true,4,1,7,[17,5,4104,6]),
+            RuleInfo(true,0,0,7,[]),RuleInfo(true,2,2,8,[4105,4106]),RuleInfo(true,2,2,9,[4114,4108]),
+            RuleInfo(true,2,2,10,[4107,4106]),RuleInfo(true,0,0,10,[]),RuleInfo(true,1,0,11,[4]),
+            RuleInfo(true,2,0,11,[8,9]),RuleInfo(true,3,1,11,[8,4115,9]),RuleInfo(true,3,1,11,[8,4104,9]),
+            RuleInfo(true,5,2,12,[18,5,4110,4109,6]),RuleInfo(true,0,0,12,[]),
+            RuleInfo(true,3,2,13,[19,4110,4109]),RuleInfo(true,0,0,13,[]),RuleInfo(true,1,1,14,[4104]),
+            RuleInfo(true,1,1,14,[4112]),RuleInfo(true,3,3,15,[4117,4115,4116]),RuleInfo(true,1,0,15,[20]),
+            RuleInfo(true,1,0,15,[21]),RuleInfo(true,1,1,16,[4115]),RuleInfo(true,1,0,16,[20]),
+            RuleInfo(true,1,0,16,[21]),RuleInfo(true,1,0,17,[22]),RuleInfo(true,1,1,18,[4113]),
+            RuleInfo(true,3,2,18,[4114,7,4113]),RuleInfo(true,1,0,19,[23]),RuleInfo(true,1,0,19,[24]),
+            RuleInfo(true,1,0,19,[25]),RuleInfo(true,1,0,19,[26]),RuleInfo(true,2,0,20,[27,28]),
+            RuleInfo(true,2,0,20,[27,29]),RuleInfo(true,2,0,20,[28,27]),RuleInfo(true,2,0,20,[29,27]),
+            RuleInfo(true,1,0,20,[27]),RuleInfo(true,1,0,20,[30]),RuleInfo(true,0,0,20,[]),
+            RuleInfo(true,1,0,21,[31]),RuleInfo(true,0,0,21,[]),RuleInfo(true,1,1,22,[4096])
+        ];
+        error_message_lists = [
+            cast(string[])null,
+            ["(%d) ( expected"],
+            ["(%d) Type expected"],
+            ["(%d) ) expected"],
+            ["(%d) ], type or size expected"],
+            ["(%d) ] expected"],
+            ["(%d) Template parameters expected"],
+            ["(%d) Template parameter expected"],
+            ["(%d) Expression expected after ("],
+            ["(%d) Arguments expected after ["],
+            ["(%d) Second slice argument expected"]
+        ];
+    }
+
+    uint[] lookaheadForNT(uint nt_index, uint state)
+    {
+        uint[] tokens;
+        auto b = action_base[state];
+        auto m = APDmin(action_check.length, cast(size_t)b+first_nt);
+        foreach ( i, check; action_check[b .. m] )
+        {
+            if ( check == state && (action_data[b+i] & 384) == 256 )
+                tokens ~= i+EOS;
+        }
+        return tokens;
+    }
+
+    override bool isErrorSynced(uint state)
+    {
+        switch ( state )
+        {
+            case 0:
+                return true;
+            default:
+                break;
+        }
+        return false;
+    }
+
+    override bool parse(string input)
+    {
+        debug(parser) indent ~= " ";
+        scope(exit) debug(parser) indent = indent[0..$-1];
+
+        bool    fatal_errors = true;
+        uint    line = 1,
+                column = 1,
+                symbol;
+
+        void reduce(uint rule)
+        {
+            version(Tango)
+                debug(parser) Stdout.format("{}reduce {} {}\n", indent, rule, ruleToString(&rule_infos[rule], -1));
+            else
+                debug(parser) writefln("%sreduce %d %s", indent, rule, ruleToString(&rule_infos[rule], -1));
+            auto ri = &rule_infos[rule];
+            uint    reduce_line,
+                    reduce_column;
+            if ( ri.symbol_count > 0 ) {
+                reduce_line = stack.array[$-ri.symbol_count].line;
+                reduce_column = stack.array[$-ri.symbol_count].column;
+                stack.pop(ri.symbol_count);
+            }
+            else {
+                reduce_line = stack.top.line;
+                reduce_column = stack.top.column;
+            }
+
+            auto b = goto_base[stack.top.index];
+            b += ri.nt_index;
+            debug(parser)
+            {
+                if ( b < goto_check.length && goto_check[b] == stack.top.index ) {
+                    stack ~= LRState(goto_data[b], reduce_line, reduce_column);
+
+                version(Tango)
+                    Stdout.format("{}goto {}\n", indent, stack.top.index);
+                else
+                    writefln("%sgoto %d", indent, stack.top.index);
+                }
+                else
+                    assert(0);
+            }
+            else
+                stack ~= LRState(goto_data[b], reduce_line, reduce_column);
+            if ( ri.ast_node ) {
+                debug createNode(reduce_line, reduce_column, rule, ri.nt_count, ri.nt_index);
+                else createNode(reduce_line, reduce_column, rule, ri.nt_count);
+            }
+            else if ( ri.nt_count > 0 )
+                node_stack.pop(ri.nt_count);
+        }
+
+        void branch(uint action)
+        {
+            version(ProfileConflicts)
+            {
+                if ( branch_stack.length > branch_stack_max )
+                    branch_stack_max = branch_stack.length;
+            }
+            if ( (action & 128) > 0 )
+            {
+                version(ProfileConflicts)
+                    sr_conflict_counts[stack.top.index]++;
+                version(Tango) debug(parser) Stdout.format("{}branch shift conflict\n", indent);
+                else debug(parser) writefln("%sbranch shift conflict", indent);
+            }
+            else
+            {
+                version(ProfileConflicts)
+                    rr_conflict_counts[stack.top.index]++;
+                version(Tango) debug(parser) Stdout.format("{}branch reduce conflict\n", indent);
+                else debug(parser) writefln("%sbranch reduce conflict", indent);
+            }
+            version(ProfileConflicts)
+                branch_stack ~= LRBranch(
+                    stack.dup, node_stack.dup,
+                    input, lookahead, lookahead_ws,
+                    line, column, symbol, fatal_errors, 
+                    action, stack.top.index | (action & 384)
+                );
+            else
+                branch_stack ~= LRBranch(
+                    stack.dup, node_stack.dup,
+                    input, lookahead, lookahead_ws,
+                    line, column, symbol, fatal_errors, 
+                    action
+                );
+            fatal_errors = false;
+        }
+
+        string prev_input = input;
+        parseLoop: while ( true )
+        {
+            if ( symbol == 0 )
+            {
+            readSymbol:
+                match = lookahead;
+                match_ws = lookahead_ws;
+                lookahead_ws = input;
+                static if ( is(typeof(WhitespaceGrammar) : GLRParser) )
+                    ws_parser.parseWS(input);
+                version(Tango)
+                    debug(lexer) Stdout.format("WS: '{}'\n", lookahead_ws[0 .. $-input.length]);
+                else
+                    debug(lexer) writefln("WS: '%s'", lookahead_ws[0 .. $-input.length]);
+                symbol = EOS;
+                if ( input.length == 0 )
+                    lookahead = null;
+                else if ( lexer(input, symbol, lookahead) ) {
+                    symbol += FIRST_TOKEN;
+                    line += countLocation(lookahead_ws[0 .. $-input.length], column);
+                    lookahead_ws = lookahead_ws[0 .. $-input.length+lookahead.length];
+                }
+                if ( symbol == 0 )
+                    throw new ParserException(line, column, filename, "Invalid token", input[0..$>MAX_INPUT_DUMP?MAX_INPUT_DUMP:$]);
+                prev_input = input;
+                input = input[lookahead.length..$];
+            }
+            debug(parser)
+            {
+                string node_stack_str;
+                foreach ( n; node_stack.array )
+                    node_stack_str ~= " "~n.node._ST_node_name~(n.sync?"*":"");
+                version(Tango)
+                    Stdout.format("\n{}state {}\n{}nodes {}\n{}lkahd ({}) {}\n{}input ({}:{}) {}\n",
+                        indent, stack.top.index,
+                        indent, node_stack_str,
+                        indent, symbol, lookahead,
+                        indent, line, column,
+                        substitute(substitute(input[0..$>MAX_INPUT_DUMP?MAX_INPUT_DUMP:$], "\r", "\\r"), "\n", "\\n")
+                    );
+                else
+                    writefln("\n%sstate %d\n%snodes %s\n%slkahd (%d) %s\n%sinput (%d:%d) %s",
+                        indent, stack.top.index,
+                        indent, node_stack_str,
+                        indent, symbol, lookahead,
+                        indent, line, column,
+                        replace(replace(input[0..$>MAX_INPUT_DUMP?MAX_INPUT_DUMP:$], "\r", "\\r"), "\n", "\\n")
+                    );
+            }
+
+            auto state = stack.top.index;
+            auto b = action_base[state];
+            uint action = 384;
+            b += symbol-EOS;
+            if ( b < action_check.length && action_check[b] == state )
+                action = action_data[b];
+
+            actionSwitch: switch ( action & 384 )
+            {
+                case 128:
+                    action &= 127;
+                    version(Tango) debug(parser) Stdout.format("{}shift {}\n", indent, action);
+                    else debug(parser) writefln("%sshift %d", indent, action);
+                    stack ~= LRState(action, line, column);
+                    symbol = 0;
+                    continue parseLoop;
+                case 256:
+                    action &= 127;
+                    version(Tango) debug(parser) Stdout.format("{}reduce {} {}\n", indent, action, ruleToString(&rule_infos[action], -1));
+                    else debug(parser) writefln("%sreduce %d %s", indent, action, ruleToString(&rule_infos[action], -1));
+                    auto ri = &rule_infos[action];
+                    uint    reduce_line,
+                            reduce_column;
+                    if ( ri.symbol_count > 0 ) {
+                        reduce_line = stack.array[$-ri.symbol_count].line;
+                        reduce_column = stack.array[$-ri.symbol_count].column;
+                        stack.pop(ri.symbol_count);
+                    }
+                    else {
+                        reduce_line = stack.array[$-1].line;
+                        reduce_column = stack.array[$-1].column;
+                    }
+
+                    state = stack.top.index;
+                    b = goto_base[state];
+                    b += ri.nt_index;
+                    debug(parser)
+                    {
+                        if ( b < goto_check.length && goto_check[b] == state ) {
+                            stack ~= LRState(goto_data[b], reduce_line, reduce_column);
+                        version(Tango)
+                            Stdout.format("{}goto {}\n", indent, stack.top.index);
+                        else
+                            writefln("%sgoto %d", indent, stack.top.index);
+                        }
+                        else
+                            assert(0);
+                    }
+                    else
+                        stack ~= LRState(goto_data[b], reduce_line, reduce_column);
+                    if ( ri.ast_node ) {
+                        debug createNode(reduce_line, reduce_column, action, ri.nt_count, ri.nt_index);
+                        else createNode(reduce_line, reduce_column, action, ri.nt_count);
+                    }
+                    else if ( ri.nt_count > 0 )
+                        node_stack.pop(ri.nt_count);
+
+                    continue parseLoop;
+                case 384:
+                    action &= 127;
+                    if ( fatal_errors || action > 0 )
+                    {
+                        if ( recover_from_errors )
+                        {
+                            try error(prev_input, line, column, action, symbol);
+                            catch ( ParserException e )
+                                recovered_errors ~= e;
+                            version(Tango)
+                                debug(nonfatal) Stdout.format("recovering from error:\n{}\n", recovered_errors[$-1]);
+                            else
+                                debug(nonfatal) writefln("recovering from error:\n%s", recovered_errors[$-1]);
+                            while ( !stack.empty && !isErrorSynced(stack.top.index) )
+                                stack.pop;
+                            while ( !node_stack.empty && !node_stack.top.sync )
+                                node_stack.pop;
+                            symbol = 0;
+                            continue parseLoop;
+                        }
+                        else {
+                            input = prev_input;
+                            error(input, line, column, action, symbol);
+                        }
+                    }
+                    else
+                    {
+                        debug(nonfatal) {
+                            input = prev_input;
+                            error(input, line, column, action, symbol, false);
+                        }
+                    }
+                    if ( branch_stack.length == 0 ) {
+                        input = prev_input;
+                        return false;
+                    }
+                    auto prev = branch_stack.popPtr;
+                    stack           = prev.stack;
+                    node_stack      = prev.node_stack;
+                    input           = prev.input;
+                    prev_input      = input;
+                    lookahead       = prev.lookahead;
+                    lookahead_ws    = prev.lookahead_ws;
+                    line            = prev.line;
+                    column          = prev.column;
+                    symbol          = prev.symbol;
+                    fatal_errors    = prev.fatal_errors;
+                    action          = prev.action;
+
+                    version(ProfileConflicts)
+                    {
+                        if ( (prev.last_conflict & 128) > 0 )
+                            shift_failed_counts[prev.last_conflict & 127]++;
+                        else
+                            reduce_failed_counts[prev.last_conflict & 127]++;
+                    }
+                    goto actionSwitch;
+                default:
+                    break;
+            }
+
+            switch ( action )
+            {
+                case 0:
+                    version(Tango)
+                        debug(parser) Stdout.format("{}accept\n", indent);
+                    else
+                        debug(parser) writefln("%saccept", indent);
+                    syntax_root = node_stack.top.node;
+                    input = prev_input;
+                    return true;
+                default:
+                    assert(0);
+            }
+        }
+        assert(0);
+    }
+}
+
+class WhitespaceGrammar : public GLRParser
+{
+    const ubyte[]  action_base =
+    [
+        0,0,2
+    ];
+    const ubyte[]  action_check =
+    [
+        1,0,2
+    ];
+    const ubyte[]  action_data =
+    [
+        4,3,0
+    ];
+    const ubyte[]  goto_base =
+    [
+        0,0,0
+    ];
+    const ubyte[]  goto_check =
+    [
+        0
+    ];
+    const ubyte[]  goto_data =
+    [
+        2
+    ];
+
+    debug(parser) string indent;
+    
+    this(GLRParser ws=null, uint tab_width=4)
+    {
+        super(ws, tab_width);
+        lexer = &wsLexer;
+        first_nt = 5;
+        nt_names =
+        [
+            "Whitespace","!LRstart"
+        ];
+        lexeme_names =
+        [
+            "EOS","[\\t\\n\\r ]+"
+        ];
+        entry_infos =
+        [
+            cast(EntryInfo[])[],[EntryInfo(0,1)],[EntryInfo(1,1)]
+        ];
+        rule_infos =
+        [
+            RuleInfo(true,1,0,0,[4]),RuleInfo(true,1,1,1,[4096])
+        ];
+        error_message_lists = [
+            cast(string[])null
+        ];
+    }
+
+    uint[] lookaheadForNT(uint nt_index, uint state)
+    {
+        uint[] tokens;
+        auto b = action_base[state];
+        auto m = APDmin(action_check.length, cast(size_t)b+first_nt);
+        foreach ( i, check; action_check[b .. m] )
+        {
+            if ( check == state && (action_data[b+i] & 6) == 4 )
+                tokens ~= i+EOS;
+        }
+        return tokens;
+    }
+
+    override bool isErrorSynced(uint state)
+    {
+        switch ( state )
+        {
+            case 0:
+                return true;
+            default:
+                break;
+        }
+        return false;
+    }
+
+    override bool parseWS(ref string input)
+    {
+        stack.clear;
+        stack ~= LRState(0, 1, 1);
+
+        debug(parser) indent ~= " ";
+        scope(exit) debug(parser) indent = indent[0..$-1];
+
+        bool    fatal_errors = true;
+        uint    line = 1,
+                column = 1,
+                symbol;
+
+        void reduce(uint rule)
+        {
+            version(Tango)
+                debug(parser) Stdout.format("{}reduce {} {}\n", indent, rule, ruleToString(&rule_infos[rule], -1));
+            else
+                debug(parser) writefln("%sreduce %d %s", indent, rule, ruleToString(&rule_infos[rule], -1));
+            auto ri = &rule_infos[rule];
+            uint    reduce_line,
+                    reduce_column;
+            if ( ri.symbol_count > 0 ) {
+                reduce_line = stack.array[$-ri.symbol_count].line;
+                reduce_column = stack.array[$-ri.symbol_count].column;
+                stack.pop(ri.symbol_count);
+            }
+            else {
+                reduce_line = stack.top.line;
+                reduce_column = stack.top.column;
+            }
+
+            auto b = goto_base[stack.top.index];
+            b += ri.nt_index;
+            debug(parser)
+            {
+                if ( b < goto_check.length && goto_check[b] == stack.top.index ) {
+                    stack ~= LRState(goto_data[b], reduce_line, reduce_column);
+                }
+                else
+                    assert(0);
+            }
+            else
+                stack ~= LRState(goto_data[b], reduce_line, reduce_column);
+        }
+
+        void branch(uint action)
+        {
+            version(ProfileConflicts)
+            {
+                if ( branch_stack.length > branch_stack_max )
+                    branch_stack_max = branch_stack.length;
+            }
+            if ( (action & 2) > 0 )
+            {
+                version(ProfileConflicts)
+                    sr_conflict_counts[stack.top.index]++;
+            }
+            else
+            {
+                version(ProfileConflicts)
+                    rr_conflict_counts[stack.top.index]++;
+            }
+            version(ProfileConflicts)
+                branch_stack ~= LRBranch(
+                    stack.dup, node_stack.dup,
+                    input, lookahead, lookahead_ws,
+                    line, column, symbol, fatal_errors, 
+                    action, stack.top.index | (action & 6)
+                );
+            else
+                branch_stack ~= LRBranch(
+                    stack.dup, node_stack.dup,
+                    input, lookahead, lookahead_ws,
+                    line, column, symbol, fatal_errors, 
+                    action
+                );
+            fatal_errors = false;
+        }
+
+        string prev_input = input;
+        parseLoop: while ( true )
+        {
+            if ( symbol == 0 )
+            {
+            readSymbol:
+                match = lookahead;
+                match_ws = lookahead_ws;
+                symbol = EOS;
+                if ( input.length == 0 )
+                    lookahead = null;
+                else if ( lexer(input, symbol, lookahead) ) {
+                    symbol += FIRST_TOKEN;
+                }
+                if ( symbol == 0 )
+                    return false;
+                prev_input = input;
+                input = input[lookahead.length..$];
+            }
+
+            auto state = stack.top.index;
+            auto b = action_base[state];
+            uint action = 6;
+            b += symbol-EOS;
+            if ( b < action_check.length && action_check[b] == state )
+                action = action_data[b];
+
+            actionSwitch: switch ( action & 6 )
+            {
+                case 2:
+                    action &= 1;
+                    stack ~= LRState(action, line, column);
+                    symbol = 0;
+                    continue parseLoop;
+                case 4:
+                    action &= 1;
+                    auto ri = &rule_infos[action];
+                    uint    reduce_line,
+                            reduce_column;
+                    if ( ri.symbol_count > 0 ) {
+                        reduce_line = stack.array[$-ri.symbol_count].line;
+                        reduce_column = stack.array[$-ri.symbol_count].column;
+                        stack.pop(ri.symbol_count);
+                    }
+                    else {
+                        reduce_line = stack.array[$-1].line;
+                        reduce_column = stack.array[$-1].column;
+                    }
+
+                    state = stack.top.index;
+                    b = goto_base[state];
+                    b += ri.nt_index;
+                    debug(parser)
+                    {
+                        if ( b < goto_check.length && goto_check[b] == state ) {
+                            stack ~= LRState(goto_data[b], reduce_line, reduce_column);
+                        }
+                        else
+                            assert(0);
+                    }
+                    else
+                        stack ~= LRState(goto_data[b], reduce_line, reduce_column);
+
+                    continue parseLoop;
+                case 6:
+                    action &= 1;
+                    input = prev_input;
+                    if ( branch_stack.length == 0 ) {
+                        input = prev_input;
+                        return false;
+                    }
+                    auto prev = branch_stack.popPtr;
+                    stack           = prev.stack;
+                    node_stack      = prev.node_stack;
+                    input           = prev.input;
+                    prev_input      = input;
+                    lookahead       = prev.lookahead;
+                    lookahead_ws    = prev.lookahead_ws;
+                    line            = prev.line;
+                    column          = prev.column;
+                    symbol          = prev.symbol;
+                    fatal_errors    = prev.fatal_errors;
+                    action          = prev.action;
+
+                    version(ProfileConflicts)
+                    {
+                        if ( (prev.last_conflict & 2) > 0 )
+                            shift_failed_counts[prev.last_conflict & 1]++;
+                        else
+                            reduce_failed_counts[prev.last_conflict & 1]++;
+                    }
+                    goto actionSwitch;
+                default:
+                    break;
+            }
+
+            switch ( action )
+            {
+                case 0:
+                    input = prev_input;
+                    return true;
+                default:
+                    assert(0);
+            }
+        }
+        assert(0);
+    }
+}
+
+
+// generated code end