1 module pry.grammar.printer; 2 3 import pry.grammar.ast; 4 import std.stdio, std.conv, std.format; 5 6 class PrettyPrinter : Visitor { 7 string modToString(Modifier mod) { 8 if(mod.min == 1 && mod.max == 1) 9 return ""; 10 if(mod.min == 0 && mod.max == 1) 11 return "?"; 12 if(mod.min == 0 && mod.max == uint.max) 13 return "*"; 14 if(mod.min == 1 && mod.max == uint.max) 15 return "+"; 16 return format("{%d,%d}", mod.min, mod.max); 17 } 18 19 override void visit(Grammar grammar) { 20 writefln("%s:", grammar.name); 21 foreach(d; grammar.defs) 22 d.accept(this); 23 } 24 25 override void visit(Definition def) { 26 string type = def.type == "" ? "" : format(": %s", def.type); 27 writef("%s %s <- ", def.name, type); 28 def.ast.accept(this); 29 writeln(); 30 } 31 32 override void visit(Sequence seq) { 33 foreach(ast; seq.seq) ast.accept(this); 34 } 35 36 override void visit(Alternative alt) { 37 writef("%s(", alt.ignored ? ":" : ""); 38 foreach(i, ast; alt.alt) { 39 if(i != 0) write(" / "); 40 ast.accept(this); 41 } 42 writef(")%s", modToString(alt.mod)); 43 } 44 45 override void visit(Map map) { 46 map.ast.accept(this); 47 writef("%s", map.code); 48 } 49 50 override void visit(NegativeLookahead neg) { 51 write("!"); 52 neg.ast.accept(this); 53 } 54 55 override void visit(PositiveLookahead pos) { 56 write("&"); 57 pos.ast.accept(this); 58 } 59 60 override void visit(SimpleSequence seq) { 61 writef("%s", seq.ignored ? ":" : ""); 62 foreach(ast; seq.seq) 63 ast.accept(this); 64 } 65 66 override void visit(CharClass charClass) { 67 writef("%s%s%s", charClass.ignored ? ":" : "", 68 to!string(charClass.set), modToString(charClass.mod)); 69 } 70 71 override void visit(Literal literal) { 72 writef("%s'%s'%s", literal.ignored ? "^" : "", literal.lit, 73 modToString(literal.mod)); 74 } 75 76 override void visit(Reference reference) { 77 writef("%s%s%s", reference.ignored ? ":" : "", reference.name, 78 modToString(reference.mod)); 79 } 80 81 override void visit(Combinator combinator) { 82 writef("$%s(", combinator.combinator); 83 foreach(i, arg; combinator.args) { 84 if(i != 0) write(","); 85 arg.accept(this); 86 } 87 write(")"); 88 } 89 } 90 91 void prettyPrint(Grammar grammar) { 92 auto pp = new PrettyPrinter(); 93 grammar.accept(pp); 94 }