1 module pegged.cutter; 2 3 import pegged.grammar; 4 5 @safe: 6 7 void optimize(TParseTree)(ref TParseTree p, string[] force = null, string[] keep = null) 8 { 9 import std.algorithm : canFind, endsWith, startsWith; 10 import std..string : indexOf; 11 12 if (p.children.length == 0) 13 return; 14 bool processed = true; 15 while (processed) 16 { 17 processed = false; 18 ParseTree[] new_children; 19 foreach (ref child; p.children) 20 { 21 if (force !is null && force.canFind(child.name)) 22 { 23 } 24 else if (keep !is null && keep.canFind(child.name)) 25 { 26 new_children ~= child; 27 continue; 28 } 29 else if (child.children.length != 1) 30 { 31 new_children ~= child; 32 continue; 33 } 34 foreach (ref grand_child; child.children) 35 { 36 new_children ~= grand_child; 37 } 38 processed = true; 39 } 40 p.children = new_children; 41 } 42 foreach (ref child; p.children) 43 { 44 optimize!TParseTree(child, force, keep); 45 } 46 } 47 48 void cutNodes(TParseTree)(ref TParseTree p, string[] names1 = null, string[] names2 = null) 49 { 50 import std.algorithm : canFind, endsWith, startsWith; 51 import std..string : indexOf; 52 53 if (p.name.endsWith(`_`)) 54 { 55 p.matches.length = 0; 56 p.name = p.name[0 .. $ - 1]; 57 } 58 else if (names2 !is null && names2.canFind(p.name)) 59 { 60 p.matches.length = 0; 61 } 62 if (p.children.length == 0) 63 return; 64 bool processed = true; 65 while (processed) 66 { 67 processed = false; 68 ParseTree[] new_children; 69 foreach (ref child; p.children) 70 { 71 if (child.name == "any") 72 { 73 } 74 else if (child.name.canFind('!')) 75 { 76 } 77 else if (names1 !is null && names1.canFind(child.name)) 78 { 79 } 80 else if (child.name.indexOf("._") == -1) 81 { 82 new_children ~= child; 83 continue; 84 } 85 foreach (ref grand_child; child.children) 86 { 87 new_children ~= grand_child; 88 } 89 processed = true; 90 } 91 p.children = new_children; 92 } 93 foreach (ref child; p.children) 94 { 95 cutNodes!TParseTree(child, names1, names2); 96 } 97 }