Mercurial > projects > ddbg_continued
view 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 source
// 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