void GenCode (Node p, int indent, BitArray isChecked) { Node p2; BitArray s1, s2; while (p != null) { switch (p.typ) { case Node.nt: { Indent(indent); gen.Write(p.sym.name + "("); CopySourcePart(p.pos, 0); gen.WriteLine(");"); break; } case Node.t: { Indent(indent); if (isChecked[p.sym.n]) gen.WriteLine("Get();"); else gen.WriteLine("Expect({0});", p.sym.n); break; } case Node.wt: { Indent(indent); s1 = tab.Expected(p.next, curSy); s1.Or(tab.allSyncSets); gen.WriteLine("ExpectWeak({0}, {1});", p.sym.n, NewCondSet(s1)); break; } case Node.any: { Indent(indent); gen.WriteLine("Get();"); break; } case Node.eps: break; // nothing case Node.rslv: break; // nothing case Node.sem: { CopySourcePart(p.pos, indent); break; } case Node.sync: { Indent(indent); GenErrorMsg(syncErr, curSy); s1 = (BitArray)p.set.Clone(); gen.Write("while (!("); GenCond(s1, p); gen.Write(")) {"); gen.Write("SynErr({0}); Get();", errorNr); gen.WriteLine("}"); break; } case Node.alt: { s1 = tab.First(p); bool equal = Sets.Equals(s1, isChecked); bool useSwitch = UseSwitch(p); if (useSwitch) { Indent(indent); gen.WriteLine("switch (la.kind) {"); } p2 = p; while (p2 != null) { s1 = tab.Expected(p2.sub, curSy); Indent(indent); if (useSwitch) { PutCaseLabels(s1); gen.WriteLine("{"); } else if (p2 == p) { gen.Write("if ("); GenCond(s1, p2.sub); gen.WriteLine(") {"); } else if (p2.down == null && equal) { gen.WriteLine("} else {"); } else { gen.Write("} else if ("); GenCond(s1, p2.sub); gen.WriteLine(") {"); } s1.Or(isChecked); //if (p2.sub.typ == Node.rslv) GenCode(p2.sub.next, indent + 1, s1); //else GenCode(p2.sub, indent + 1, s1); GenCode(p2.sub, indent + 1, s1); if (useSwitch) { Indent(indent); gen.WriteLine("\tbreak;"); Indent(indent); gen.WriteLine("}"); } p2 = p2.down; } Indent(indent); if (equal) { gen.WriteLine("}"); } else { GenErrorMsg(altErr, curSy); if (useSwitch) { gen.WriteLine("default: SynErr({0}); break;", errorNr); Indent(indent); gen.WriteLine("}"); } else { gen.Write("} "); gen.WriteLine("else SynErr({0});", errorNr); } } break; } case Node.iter: { Indent(indent); p2 = p.sub; gen.Write("while ("); if (p2.typ == Node.wt) { s1 = tab.Expected(p2.next, curSy); s2 = tab.Expected(p.next, curSy); gen.Write("WeakSeparator({0},{1},{2}) ", p2.sym.n, NewCondSet(s1), NewCondSet(s2)); s1 = new BitArray(tab.terminals.Count); // for inner structure if (p2.up || p2.next == null) p2 = null; else p2 = p2.next; } else { s1 = tab.First(p2); GenCond(s1, p2); } gen.WriteLine(") {"); GenCode(p2, indent + 1, s1); Indent(indent); gen.WriteLine("}"); break; } case Node.opt: //if (p.sub.typ == Node.rslv) s1 = tab.First(p.sub.next); //else s1 = tab.First(p.sub); s1 = tab.First(p.sub); Indent(indent); gen.Write("if ("); GenCond(s1, p.sub); gen.WriteLine(") {"); //if (p.sub.typ == Node.rslv) GenCode(p.sub.next, indent + 1, s1); //else GenCode(p.sub, indent + 1, s1); GenCode(p.sub, indent + 1, s1); Indent(indent); gen.WriteLine("}"); break; } if (p.typ != Node.eps && p.typ != Node.sem && p.typ != Node.sync) isChecked.SetAll(false); // = new BitArray(tab.terminals.Count); if (p.up) break; p = p.next; } }
void GenCode(Node p, int indent, BitArray isChecked) { Node p2; BitArray s1, s2; while (p != null) { switch (p.typ) { case Node.nt: { Indent(indent); gen.Write(p.sym.name + "("); CopySourcePart(p.pos, 0); gen.WriteLine(");"); break; } case Node.t: { Indent(indent); // assert: if isChecked[p.sym.n] is true, then isChecked contains only p.sym.n if (isChecked[p.sym.n]) { gen.WriteLine("Get();"); } else { gen.WriteLine("Expect({0});", p.sym.n); } break; } case Node.wt: { Indent(indent); s1 = tab.Expected(p.next, curSy); s1.Or(tab.allSyncSets); gen.WriteLine("ExpectWeak({0}, {1});", p.sym.n, NewCondSet(s1)); break; } case Node.any: { Indent(indent); int acc = Sets.Elements(p.set); if (tab.terminals.Count == (acc + 1) || (acc > 0 && Sets.Equals(p.set, isChecked))) { // either this ANY accepts any terminal (the + 1 = end of file), or exactly what's allowed here gen.WriteLine("Get();"); } else { GenErrorMsg(altErr, curSy); if (acc > 0) { gen.Write("if ("); GenCond(p.set, p); gen.WriteLine(") Get(); else SynErr({0});", errorNr); } else { gen.WriteLine("SynErr({0}); // ANY node that matches no symbol", errorNr); } } break; } case Node.eps: break; // nothing case Node.rslv: break; // nothing case Node.sem: { CopySourcePart(p.pos, indent); break; } case Node.sync: { Indent(indent); GenErrorMsg(syncErr, curSy); s1 = (BitArray)p.set.Clone(); gen.Write("while (!("); GenCond(s1, p); gen.Write(")) {"); gen.Write("SynErr({0}); Get();", errorNr); gen.WriteLine("}"); break; } case Node.alt: { s1 = tab.First(p); bool equal = Sets.Equals(s1, isChecked); bool useSwitch = UseSwitch(p); if (useSwitch) { Indent(indent); gen.WriteLine("switch (la.kind) {"); } p2 = p; while (p2 != null) { s1 = tab.Expected(p2.sub, curSy); Indent(indent); if (useSwitch) { PutCaseLabels(s1); gen.WriteLine("{"); } else if (p2 == p) { gen.Write("if ("); GenCond(s1, p2.sub); gen.WriteLine(") {"); } else if (p2.down == null && equal) { gen.WriteLine("} else {"); } else { gen.Write("} else if ("); GenCond(s1, p2.sub); gen.WriteLine(") {"); } GenCode(p2.sub, indent + 1, s1); if (useSwitch) { Indent(indent); gen.WriteLine("\tbreak;"); Indent(indent); gen.WriteLine("}"); } p2 = p2.down; } Indent(indent); if (equal) { gen.WriteLine("}"); } else { GenErrorMsg(altErr, curSy); if (useSwitch) { gen.WriteLine("default: SynErr({0}); break;", errorNr); Indent(indent); gen.WriteLine("}"); } else { gen.Write("} "); gen.WriteLine("else SynErr({0});", errorNr); } } break; } case Node.iter: { Indent(indent); p2 = p.sub; gen.Write("while ("); if (p2.typ == Node.wt) { s1 = tab.Expected(p2.next, curSy); s2 = tab.Expected(p.next, curSy); gen.Write("WeakSeparator({0},{1},{2}) ", p2.sym.n, NewCondSet(s1), NewCondSet(s2)); s1 = new BitArray(tab.terminals.Count); // for inner structure if (p2.up || p2.next == null) { p2 = null; } else { p2 = p2.next; } } else { s1 = tab.First(p2); GenCond(s1, p2); } gen.WriteLine(") {"); GenCode(p2, indent + 1, s1); Indent(indent); gen.WriteLine("}"); break; } case Node.opt: s1 = tab.First(p.sub); Indent(indent); gen.Write("if ("); GenCond(s1, p.sub); gen.WriteLine(") {"); GenCode(p.sub, indent + 1, s1); Indent(indent); gen.WriteLine("}"); break; } if (p.typ != Node.eps && p.typ != Node.sem && p.typ != Node.sync) { isChecked.SetAll(false); // = new BitArray(tab.terminals.Count); } if (p.up) { break; } p = p.next; } }
void GenCode(Node p, int indent, BitArray isChecked) { Node p2; BitArray s1, s2; while (p != null) { switch (p.typ) { case Node.nt: { // generate a production method call ... Indent(indent); GenAstBuilder(p, indent); gen.Write("{0}{1}(", p.sym.name, PROD_SUFFIX); CopySourcePart(p.pos, 0); // ... with actual arguments gen.WriteLine(");"); break; } case Node.t: { GenSymboltableCheck(p, indent); Indent(indent); // assert: if isChecked[p.sym.n] is true, then isChecked contains only p.sym.n if (isChecked[p.sym.n]) { GenAstBuilder(p, indent); gen.WriteLine("Get();"); } else { GenAutocomplete(p.sym.n, indent, "T"); GenAutocompleteSymboltable(p, indent, "T"); GenAstBuilder(p, indent); gen.WriteLine("Expect({0}); // {1}", p.sym.n, p.sym.name); } break; } case Node.wt: { GenSymboltableCheck(p, indent); Indent(indent); s1 = tab.Expected(p.next, curSy); s1.Or(tab.allSyncSets); int ncs1 = NewCondSet(s1); Symbol ncs1sym = (Symbol)tab.terminals[ncs1]; GenAutocomplete(p.sym.n, indent, "WT"); GenAutocompleteSymboltable(p, indent, "WT"); GenAstBuilder(p, indent); gen.WriteLine("ExpectWeak({0}, {1}); // {2} followed by {3}", p.sym.n, ncs1, p.sym.name, ncs1sym.name); break; } case Node.any: { Indent(indent); int acc = Sets.Elements(p.set); if (tab.terminals.Count == (acc + 1) || (acc > 0 && Sets.Equals(p.set, isChecked))) { // either this ANY accepts any terminal (the + 1 = end of file), or exactly what's allowed here gen.WriteLine("Get();"); } else { GenErrorMsg(altErr, curSy); if (acc > 0) { GenAutocomplete(p.set, p, indent, "ANY"); gen.Write("if ("); GenCond(p.set, p); gen.WriteLine(") Get(); else SynErr({0});", errorNr); } else { gen.WriteLine("SynErr({0}); // ANY node that matches no symbol", errorNr); } } break; } case Node.eps: break; // nothing case Node.rslv: break; // nothing case Node.sem: { CopySourcePart(p.pos, indent); break; } case Node.sync: { Indent(indent); GenErrorMsg(syncErr, curSy); s1 = (BitArray)p.set.Clone(); gen.Write("while (!("); GenCond(s1, p); gen.Write(")) {"); gen.Write("SynErr({0}); Get();", errorNr); gen.WriteLine("}"); break; } case Node.alt: { s1 = tab.First(p); bool equal = Sets.Equals(s1, isChecked); // intellisense p2 = p; Indent(indent); while (p2 != null) { s1 = tab.Expected(p2.sub, curSy); GenAutocomplete(s1, p2.sub, indent, "ALT"); GenAutocompleteSymboltable(p2.sub, indent, "ALT"); p2 = p2.down; } // end intellisense bool useSwitch = UseSwitch(p); if (useSwitch) { gen.WriteLine("switch (la.kind) {"); } p2 = p; while (p2 != null) { s1 = tab.Expected(p2.sub, curSy); if (useSwitch) { PutCaseLabels(s1, indent); gen.WriteLine("{"); } else if (p2 == p) { gen.Write("if ("); GenCond(s1, p2.sub); gen.WriteLine(") {"); } else if (p2.down == null && equal) { Indent(indent); gen.WriteLine("} else {"); } else { Indent(indent); gen.Write("} else if ("); GenCond(s1, p2.sub); gen.WriteLine(") {"); } GenCode(p2.sub, indent + 1, s1); if (useSwitch) { Indent(indent); gen.WriteLine("\tbreak;"); Indent(indent); gen.WriteLine("}"); } p2 = p2.down; } Indent(indent); if (equal) { gen.WriteLine("}"); } else { GenErrorMsg(altErr, curSy); if (useSwitch) { gen.WriteLine("default: SynErr({0}); break;", errorNr); Indent(indent); gen.WriteLine("}"); } else { gen.Write("} "); gen.WriteLine("else SynErr({0});", errorNr); } } break; } case Node.iter: { Indent(indent); p2 = p.sub; Node pac = p2; BitArray sac = (BitArray)tab.First(pac); GenAutocomplete(sac, pac, indent, "ITER start"); GenAutocompleteSymboltable(pac, indent, "ITER start"); gen.Write("while ("); if (p2.typ == Node.wt) { s1 = tab.Expected(p2.next, curSy); s2 = tab.Expected(p.next, curSy); gen.Write("WeakSeparator({0},{1},{2}) ", p2.sym.n, NewCondSet(s1), NewCondSet(s2)); s1 = new BitArray(tab.terminals.Count); // for inner structure if (p2.up || p2.next == null) { p2 = null; } else { p2 = p2.next; } } else { s1 = tab.First(p2); GenCond(s1, p2); } gen.WriteLine(") {"); GenCode(p2, indent + 1, s1); Indent(indent + 1); GenAutocomplete(sac, pac, 0, "ITER end"); GenAutocompleteSymboltable(pac, indent, "ITER end"); Indent(indent); gen.WriteLine("}"); break; } case Node.opt: s1 = tab.First(p.sub); Indent(indent); GenAutocomplete(s1, p.sub, indent, "OPT"); gen.Write("if ("); GenCond(s1, p.sub); gen.WriteLine(") {"); GenCode(p.sub, indent + 1, s1); Indent(indent); gen.WriteLine("}"); break; } if (p.typ != Node.eps && p.typ != Node.sem && p.typ != Node.sync) { isChecked.SetAll(false); // = new BitArray(tab.terminals.Count); } if (p.up) { break; } p = p.next; } }