1 module epsilon.predicates; 2 3 import EAG = epsilon.eag; 4 import log; 5 import runtime; 6 import std.bitmanip : BitArray; 7 8 void Check() 9 in (EAG.Performed(EAG.analysed)) 10 { 11 struct EdgeRecord 12 { 13 size_t Dest; 14 int Next; 15 } 16 17 int[] HNont; 18 EdgeRecord[] Edge; 19 int NextEdge; 20 size_t[] Stack; 21 int Top; 22 BitArray CoPred; 23 BitArray Pred; 24 25 void NewEdge(int From, size_t To) 26 { 27 Edge[NextEdge].Dest = To; 28 Edge[NextEdge].Next = HNont[From]; 29 HNont[From] = NextEdge; 30 ++NextEdge; 31 } 32 33 void PutCoPred(size_t N) 34 { 35 if (!CoPred[N]) 36 { 37 CoPred[N] = true; 38 Stack[Top] = N; 39 ++Top; 40 } 41 } 42 43 void BuiltEdge() 44 { 45 for (size_t N = EAG.firstHNont; N < EAG.NextHNont; ++N) 46 HNont[N] = -1; 47 foreach (N; EAG.All.bitsSet) 48 { 49 if (!EAG.Null[N]) 50 PutCoPred(N); 51 52 EAG.Alt A = EAG.HNont[N].Def.Sub; 53 54 do 55 { 56 for (EAG.Factor F = A.Sub; F !is null; F = F.Next) 57 if (cast(EAG.Term) F) 58 PutCoPred(N); 59 else if (auto nont = cast(EAG.Nont) F) 60 NewEdge(nont.Sym, N); 61 A = A.Next; 62 } 63 while (A !is null); 64 } 65 } 66 67 void ClearStack() 68 { 69 while (Top > 0) 70 { 71 --Top; 72 73 int Dep = HNont[Stack[Top]]; 74 75 while (Dep >= 0) 76 { 77 PutCoPred(Edge[Dep].Dest); 78 Dep = Edge[Dep].Next; 79 } 80 } 81 } 82 83 EAG.History &= ~EAG.predicates; 84 HNont = new int[EAG.NextHNont]; 85 Edge = new EdgeRecord[EAG.NONont + 1]; 86 NextEdge = 0; 87 Stack = new size_t[EAG.NextHNont]; 88 Top = 0; 89 CoPred = BitArray(); 90 CoPred.length = EAG.NextHNont + 1; 91 BuiltEdge; 92 ClearStack; 93 Pred = EAG.Prod - CoPred; 94 Pred[EAG.StartSym] = false; 95 EAG.Pred = Pred; 96 EAG.History |= EAG.predicates; 97 List; 98 } 99 100 private void List() 101 in (EAG.Performed(EAG.analysed | EAG.predicates)) 102 { 103 import std.algorithm : map; 104 import std.format : format; 105 106 info!"predicates in %s: %s"(EAG.BaseName, EAG.Pred.count); 107 if (EAG.Pred.count == 0) 108 return; 109 110 string[] items; 111 112 foreach (N; EAG.Pred.bitsSet) 113 if (EAG.HNont[N].anonymous) 114 items ~= format!"EBNF expression in %s\n%s"(EAG.NamedHNontRepr(N), EAG.HNont[N].Def.Sub.Pos); 115 else 116 items ~= format!"%s\n%s"(EAG.HNontRepr(N), EAG.HNont[N].Def.Sub.Pos); 117 118 trace!"predicate occurrences in %s:%-(\n%s%)"(EAG.BaseName, items); 119 }