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