public static string genProgram(ProgramDecl program) { var ctx = new GenContext(); ctx.prg = program; genProgram(ctx, program); return ctx.output.ToString(); }
private static void genBaseClass(GenContext ctx, ProgramDecl program) { ctx.Appendfnl("public abstract partial class {0}", program.baseClass.name); ctx.Appendfnl("{{"); ctx.IncreaseIndent(); ctx.Appendfnl("public {0} Parent {{ get; set; }}", program.baseClass.name); ctx.Appendfnl("public abstract void ReplaceChildNode({0} childNode, {0} newNode);", program.baseClass.name, program.baseClass.name); ctx.DecreaseIndent(); ctx.Appendfnl("}}"); }
private static void genWalker(GenContext ctx, ProgramDecl program) { ctx.Appendfnl("public class {0}", program.walker.name); ctx.Appendfnl("{{"); ctx.IncreaseIndent(); foreach (var node in program.nodes) { if (node is NodeVariantsDecl) { genWalkerVariants(ctx, (NodeVariantsDecl)node); } else { genWalkerConcrete(ctx, (NodeConcreteDecl)node); } } ctx.DecreaseIndent(); ctx.Appendfnl("}}"); }
private static void genProgram(GenContext ctx, ProgramDecl program) { ctx.Appendfnl("namespace {0}", string.Join(".", program.ns.ids)); ctx.Appendfnl("{{"); ctx.IncreaseIndent(); if (program.baseClass != null) { genBaseClass(ctx, program); } foreach (var node in program.nodes) { genNode(ctx, node); } if (program.walker != null) { genWalker(ctx, program); } if (program.printer != null) { genPrinter(ctx, program); } ctx.DecreaseIndent(); ctx.Appendfnl("}}"); }
private static void GenPrinterHeader(GenContext ctx, ProgramDecl program, List<AttributeDecl> printedAttributes, string typeName) { var attrFormats = string.Join(", ", printedAttributes.Select((x, i) => x.id + "={" + i + "}")); var attrRefs = string.Join(", ", printedAttributes.Select(x => "__node." + x.id)); if (attrFormats != "") { attrFormats = " " + attrFormats; } if (attrRefs != "") { attrRefs = ", " + attrRefs; } ctx.Appendfnl("public override void walk{0}(global::{1}.{0} __node)", typeName, string.Join(".", program.ns.ids)); ctx.Appendfnl("{{"); ctx.Appendfnl(" if (!atNewLine)"); ctx.Appendfnl(" {{"); ctx.Appendfnl(" NewLine();"); ctx.Appendfnl(" }}"); ctx.Appendfnl(" Appendf(\"({0}{1}\"{2});", typeName, attrFormats, attrRefs); ctx.Appendfnl(" IncreaseIndent();"); ctx.Appendfnl(" base.walk{0}(__node);", typeName); ctx.Appendfnl(" Appendf(\")\");"); ctx.Appendfnl(" DecreaseIndent();"); ctx.Appendfnl("}}"); }
private static void genPrinter(GenContext ctx, ProgramDecl program) { if (program.walker == null) { throw new InvalidOperationException("Walker must be specified in order to use printer"); } ctx.Appendfnl("public class {0} : {1}", program.printer.name, program.walker.name); ctx.Appendfnl("{{"); ctx.IncreaseIndent(); ctx.Appendfnl("global::System.IO.TextWriter writer;"); ctx.Appendfnl("int indentLevel = 0;"); ctx.Appendfnl("bool atNewLine = true;"); ctx.Appendfnl("void IncreaseIndent()"); ctx.Appendfnl("{{"); ctx.Appendfnl(" ++indentLevel;"); ctx.Appendfnl("}}"); ctx.Appendfnl("void DecreaseIndent()"); ctx.Appendfnl("{{"); ctx.Appendfnl(" --indentLevel;"); ctx.Appendfnl("}}"); ctx.Appendfnl("void PrintIndent()"); ctx.Appendfnl("{{"); ctx.Appendfnl(" for (int i = 0; i < indentLevel; ++i)"); ctx.Appendfnl(" {{"); ctx.Appendfnl(" writer.Write(\" \");"); ctx.Appendfnl(" }}"); ctx.Appendfnl("}}"); ctx.Appendfnl("void NewLine()"); ctx.Appendfnl("{{"); ctx.Appendfnl(" writer.Write(\"\\n\");"); ctx.Appendfnl(" atNewLine = true;"); ctx.Appendfnl("}}"); ctx.Appendfnl("public void Appendf(string format, params object[] args)"); ctx.Appendfnl("{{"); ctx.Appendfnl(" if (atNewLine)"); ctx.Appendfnl(" {{"); ctx.Appendfnl(" PrintIndent();"); ctx.Appendfnl(" atNewLine = false;"); ctx.Appendfnl(" }}"); ctx.Appendfnl(" writer.Write(format, args);"); ctx.Appendfnl("}}"); ctx.Appendfnl("public void Appendfnl(string format, params object[] args)"); ctx.Appendfnl("{{"); ctx.Appendfnl(" if (atNewLine)"); ctx.Appendfnl(" {{"); ctx.Appendfnl(" PrintIndent();"); ctx.Appendfnl(" atNewLine = false;"); ctx.Appendfnl(" }}"); ctx.Appendfnl(" writer.Write(format, args);"); ctx.Appendfnl(" NewLine();"); ctx.Appendfnl("}}"); ctx.Appendfnl("public static string PrintAst(global::{0}.{1} __node)", string.Join(".", program.ns.ids), program.printer.root); ctx.Appendfnl("{{"); ctx.Appendfnl(" var sw = new global::System.IO.StringWriter();"); ctx.Appendfnl(" var printer = new {0}(sw);", program.printer.name); ctx.Appendfnl(" printer.walk{0}(__node);", program.printer.root); ctx.Appendfnl(" return sw.ToString();"); ctx.Appendfnl("}}"); ctx.Appendfnl(""); ctx.Appendfnl("public {0}(global::System.IO.TextWriter writer)", program.printer.name); ctx.Appendfnl("{{"); ctx.Appendfnl(" this.writer = writer;"); ctx.Appendfnl("}}"); foreach (var type in program.nodes) { if (type is NodeVariantsDecl) { var theType = (NodeVariantsDecl)type; foreach (var variant in theType.variants) { var printedAttributes = type.attributes.Concat(variant.attributes).Where(x => x.printed).ToList(); var typeName = variant.id; GenPrinterHeader(ctx, program, printedAttributes, typeName); } } else if (type is NodeConcreteDecl) { var theType = (NodeConcreteDecl)type; var printedAttributes = theType.attributes.Where(x => x.printed).ToList(); var typeName = theType.id; GenPrinterHeader(ctx, program, printedAttributes, typeName); } else { throw new InvalidOperationException(); } } ctx.DecreaseIndent(); ctx.Appendfnl("}}"); }
public ProgramDecl program() { EnterRule_program(); EnterRule("program", 1); TraceIn("program", 1); ProgramDecl r = default(ProgramDecl); NamespaceDecl namespaceDecl1 = default(NamespaceDecl); BaseClassDecl baseClassDecl2 = default(BaseClassDecl); WalkerDecl walkerDecl3 = default(WalkerDecl); PrinterDecl printerDecl4 = default(PrinterDecl); NodeDecl node5 = default(NodeDecl); try { DebugEnterRule(GrammarFileName, "program"); DebugLocation(16, 10); try { // ADL.g:17:5: ( namespaceDecl baseClassDecl ( walkerDecl )? ( printerDecl )? ( node )+ EOF ) DebugEnterAlt(1); // ADL.g:17:7: namespaceDecl baseClassDecl ( walkerDecl )? ( printerDecl )? ( node )+ EOF { DebugLocation(17, 7); PushFollow(Follow._namespaceDecl_in_program57); namespaceDecl1=namespaceDecl(); PopFollow(); DebugLocation(17, 22); r = new ProgramDecl { ns = namespaceDecl1 }; DebugLocation(18, 5); PushFollow(Follow._baseClassDecl_in_program66); baseClassDecl2=baseClassDecl(); PopFollow(); DebugLocation(18, 19); r.baseClass = baseClassDecl2; DebugLocation(19, 5); // ADL.g:19:5: ( walkerDecl )? int alt1=2; try { DebugEnterSubRule(1); try { DebugEnterDecision(1, false); int LA1_1 = input.LA(1); if ((LA1_1==WALKER)) { alt1 = 1; } } finally { DebugExitDecision(1); } switch (alt1) { case 1: DebugEnterAlt(1); // ADL.g:19:6: walkerDecl { DebugLocation(19, 6); PushFollow(Follow._walkerDecl_in_program75); walkerDecl3=walkerDecl(); PopFollow(); DebugLocation(19, 17); r.walker = walkerDecl3; } break; } } finally { DebugExitSubRule(1); } DebugLocation(20, 5); // ADL.g:20:5: ( printerDecl )? int alt2=2; try { DebugEnterSubRule(2); try { DebugEnterDecision(2, false); int LA2_1 = input.LA(1); if ((LA2_1==PRINTER)) { alt2 = 1; } } finally { DebugExitDecision(2); } switch (alt2) { case 1: DebugEnterAlt(1); // ADL.g:20:6: printerDecl { DebugLocation(20, 6); PushFollow(Follow._printerDecl_in_program86); printerDecl4=printerDecl(); PopFollow(); DebugLocation(20, 18); r.printer = printerDecl4; } break; } } finally { DebugExitSubRule(2); } DebugLocation(21, 5); // ADL.g:21:5: ( node )+ int cnt3=0; try { DebugEnterSubRule(3); while (true) { int alt3=2; try { DebugEnterDecision(3, false); int LA3_1 = input.LA(1); if ((LA3_1==ID)) { alt3 = 1; } } finally { DebugExitDecision(3); } switch (alt3) { case 1: DebugEnterAlt(1); // ADL.g:21:6: node { DebugLocation(21, 6); PushFollow(Follow._node_in_program97); node5=node(); PopFollow(); DebugLocation(22, 9); r.nodes.Add(node5); } break; default: if (cnt3 >= 1) goto loop3; EarlyExitException eee3 = new EarlyExitException( 3, input ); DebugRecognitionException(eee3); throw eee3; } cnt3++; } loop3: ; } finally { DebugExitSubRule(3); } DebugLocation(25, 8); Match(input,EOF,Follow._EOF_in_program116); } } catch (RecognitionException re) { ReportError(re); Recover(input,re); } finally { TraceOut("program", 1); LeaveRule("program", 1); LeaveRule_program(); } DebugLocation(25, 10); } finally { DebugExitRule(GrammarFileName, "program"); } return r; }