1 module rules; 2 3 import std.uni; 4 import std.format : format; 5 import std.array : back, front; 6 import std.string : indexOf; 7 import std.typecons : Flag; 8 9 alias StoreRulePart = Flag!"StoreRulePart"; 10 11 class RulePart { 12 StoreRulePart storeThis; 13 string name; 14 string storeName; 15 16 this(string name) { 17 this.name = name; 18 19 auto hashIdx = this.name.indexOf('#'); 20 if(hashIdx != -1) { 21 this.storeThis = StoreRulePart.yes; 22 this.storeName = this.name[hashIdx + 1 .. $]; 23 this.name = this.name[0 .. hashIdx]; 24 } 25 } 26 27 bool terminal() pure const @safe { 28 return this.name.front.isLower(); 29 } 30 31 bool nonterminal() pure const @safe { 32 return this.name.front.isUpper(); 33 } 34 35 override string toString() pure const @safe { 36 if(this.storeThis == StoreRulePart.yes) { 37 return format("%s#%s", this.name, this.storeName); 38 } else { 39 return this.name; 40 } 41 } 42 } 43 44 class SubRule { 45 RulePart[] elements; 46 47 string name; 48 49 this(string name) { 50 this.name = name; 51 } 52 53 override string toString() pure const @safe { 54 string rslt = this.name ~ " : "; 55 foreach(it; this.elements) { 56 rslt ~= it.toString() ~ " "; 57 } 58 59 return rslt; 60 } 61 } 62 63 class Rule { 64 SubRule[] subRules; 65 string name; 66 bool isExtern; 67 68 this(string name) { 69 this.name = name; 70 } 71 72 this(string name, bool e) { 73 this.name = name; 74 this.isExtern = e; 75 } 76 77 override string toString() pure const @safe { 78 string rslt = this.name ~ " : \n"; 79 foreach(it; this.subRules) { 80 rslt ~= "\t" ~ it.toString() ~ "\n"; 81 } 82 83 return rslt; 84 } 85 } 86