1 module epsilon.eag;
2 
3 import io : Position;
4 import runtime;
5 import std.algorithm;
6 import std.bitmanip;
7 import symbols : SymbolTable;
8 
9 const nil = 0;
10 const empty = 0;
11 size_t History;
12 const firstParam = 0;
13 const firstHAlt = 0;
14 const firstHFactor = 0;
15 
16 enum
17 {
18     analysed = 1 << 0,
19     predicates = 1 << 1,
20     parsable = 1 << 2,
21     isSLAG = 1 << 3,
22     isSweep = 1 << 4,
23     hasEvaluator = 1 << 5,
24 }
25 
26 struct ParamsDesc
27 {
28     int Params;
29     Position Pos;
30 
31     public string toString() const @safe
32     {
33         import std.format : format;
34 
35         return format!"%s"(params);
36     }
37 
38     ParamRecord[] params() const nothrow @safe
39     {
40         const length = ParamBuf[Params .. $]
41             .map!"a.Affixform"
42             .countUntil(nil);
43 
44         return ParamBuf[Params .. Params + length];
45     }
46 }
47 
48 struct ParamRecord
49 {
50     int Affixform;
51     Position Pos;
52     bool isDef;
53 
54     public string toString() const pure @safe
55     {
56         import std.format : format;
57 
58         if (Affixform == nil)
59             return "Param()";
60         return format!"Param(%s, %s)"(isDef ? "def" : "app", Affixform);
61     }
62 }
63 
64 ParamRecord[] ParamBuf;
65 int NextParam;
66 const firstNode = 1;
67 const firstVar = 1;
68 
69 struct ScopeDesc
70 {
71     int Beg;
72     int End;
73 
74     public string toString() const pure @safe
75     {
76         import std.format : format;
77 
78         return format!"Scope(Beg=%s, End=%s)"(Beg, End);
79     }
80 }
81 
82 struct VarRecord
83 {
84     int Sym;
85     int Num;
86     int Neg;
87     Position Pos;
88     bool Def;
89 
90     public string toString() const @safe
91     {
92         import std.format : format;
93 
94         return format!"Variable(Sym=%s, Num=%s, Neg=%s, Def=%s)\n%s"(Sym, Num, Neg, Def, Pos);
95     }
96 }
97 
98 int[] NodeBuf;
99 int NextNode;
100 VarRecord[] Var;
101 int NextVar;
102 int Scope;
103 
104 class Rule
105 {
106     Alt Sub;
107 }
108 
109 class Alt
110 {
111     int Ind;
112     int Up;
113     Alt Next;
114     Factor Sub;
115     Factor Last;
116     ParamsDesc Formal;
117     ParamsDesc Actual;
118     ScopeDesc Scope;
119     Position Pos;
120 
121     public override string toString() const @safe
122     {
123         import std.format : format;
124 
125         string[] items;
126 
127         items ~= format!"Ind=%s"(Ind);
128         items ~= format!"Up=%s"(Up);
129         // TODO: Next, Sub, Last
130         items ~= format!"Formal=%s"(Formal);
131         items ~= format!"Actual=%s"(Actual);
132         items ~= Scope.toString;
133         return format!"Alt(%-(%s, %))"(items);
134     }
135 }
136 
137 void assign(Alt lhs, Alt rhs) @nogc nothrow pure @safe
138 in (lhs !is null)
139 in (rhs !is null)
140 {
141     lhs.Ind = rhs.Ind;
142     lhs.Up = rhs.Up;
143     lhs.Next = rhs.Next;
144     lhs.Sub = rhs.Sub;
145     lhs.Last = rhs.Last;
146     lhs.Formal = rhs.Formal;
147     lhs.Actual = rhs.Actual;
148     lhs.Scope = rhs.Scope;
149     lhs.Pos = rhs.Pos;
150 }
151 
152 class Grp : Rule
153 {
154 }
155 
156 class Opt : Rule
157 {
158     Position EmptyAltPos;
159     ScopeDesc Scope;
160     ParamsDesc Formal;
161 }
162 
163 class Rep : Rule
164 {
165     Position EmptyAltPos;
166     ScopeDesc Scope;
167     ParamsDesc Formal;
168 }
169 
170 class Factor
171 {
172     int Ind;
173     Factor Prev;
174     Factor Next;
175 }
176 
177 class Term : Factor
178 {
179     int Sym;
180     Position Pos;
181 }
182 
183 class Nont : Factor
184 {
185     int Sym;
186     ParamsDesc Actual;
187     Position Pos;
188 
189 }
190 
191 void assign(Nont lhs, Nont rhs) @nogc nothrow pure @safe
192 in (lhs !is null)
193 in (rhs !is null)
194 {
195     lhs.Ind = rhs.Ind;
196     lhs.Prev = rhs.Prev;
197     lhs.Next = rhs.Next;
198     lhs.Sym = rhs.Sym;
199     lhs.Actual = rhs.Actual;
200     lhs.Pos = rhs.Pos;
201 }
202 
203 int NextHAlt;
204 int NextHFactor;
205 int NOAlt;
206 int NOTerm;
207 int NONont;
208 int NOOpt;
209 int NORep;
210 int NOGrp;
211 const firstDom = 0;
212 int[] DomBuf;
213 int NextDom;
214 int CurSig;
215 const firstMAlt = 1;
216 const firstMemb = 1;
217 
218 struct MAltRecord
219 {
220     int Left;
221     int Right;
222     int Arity;
223     int Next;
224 }
225 
226 MAltRecord[] MAlt;
227 int NextMAlt;
228 int MaxMArity;
229 int[] MembBuf;
230 int NextMemb;
231 const firstMTerm = 1;
232 const firstMNont = 1;
233 const firstHTerm = 0;
234 const firstHNont = 0;
235 
236 struct MTermRecord
237 {
238     int Id;
239 }
240 
241 struct MNontRecord
242 {
243     int Id;
244     int MRule;
245     int Last;
246     bool IsToken;
247 }
248 
249 struct HTermRecord
250 {
251     int Id;
252 }
253 
254 struct HNontRecord
255 {
256     int Id;
257     int NamedId;
258     int Sig;
259     Rule Def;
260     bool IsToken;
261 
262     bool anonymous() const @nogc nothrow pure @safe
263     {
264         return Id < 0;
265     }
266 }
267 
268 MTermRecord[] MTerm;
269 int NextMTerm;
270 MNontRecord[] MNont;
271 int NextMNont;
272 HTermRecord[] HTerm;
273 int NextHTerm;
274 HNontRecord[] HNont;
275 int NextHNont;
276 int NextAnonym;
277 
278 // for technical reasons there can be gaps in the HNont array,
279 // so the set All defines the valid entries
280 BitArray All;
281 BitArray Prod;
282 BitArray Reach;
283 BitArray Null;
284 BitArray Pred;
285 int StartSym;
286 string BaseName;
287 SymbolTable symbolTable;
288 
289 void Expand() nothrow @safe
290 {
291     size_t NewLen(size_t ArrayLen)
292     {
293         assert(ArrayLen < DIV(int.max, 2));
294 
295         return 2 * ArrayLen + 1;
296     }
297 
298     if (NextParam >= ParamBuf.length)
299     {
300         auto ParamBuf1 = new ParamRecord[NewLen(ParamBuf.length)];
301 
302         for (size_t i = firstParam; i < ParamBuf.length; ++i)
303             ParamBuf1[i] = ParamBuf[i];
304         ParamBuf = ParamBuf1;
305     }
306     if (NextMTerm >= MTerm.length)
307     {
308         auto MTerm1 = new MTermRecord[NewLen(MTerm.length)];
309 
310         for (size_t i = firstMTerm; i < MTerm.length; ++i)
311             MTerm1[i] = MTerm[i];
312         MTerm = MTerm1;
313     }
314     if (NextMNont >= MNont.length)
315     {
316         auto MNont1 = new MNontRecord[NewLen(MNont.length)];
317 
318         for (size_t i = firstMNont; i < MNont.length; ++i)
319             MNont1[i] = MNont[i];
320         MNont = MNont1;
321     }
322     if (NextHTerm >= HTerm.length)
323     {
324         auto HTerm1 = new HTermRecord[NewLen(HTerm.length)];
325 
326         for (size_t i = firstHTerm; i < HTerm.length; ++i)
327             HTerm1[i] = HTerm[i];
328         HTerm = HTerm1;
329     }
330     if (NextHNont >= HNont.length)
331     {
332         auto HNont1 = new HNontRecord[NewLen(HNont.length)];
333 
334         for (size_t i = firstHNont; i < HNont.length; ++i)
335             HNont1[i] = HNont[i];
336         HNont = HNont1;
337     }
338     if (NextDom >= DomBuf.length)
339     {
340         auto DomBuf1 = new int[NewLen(DomBuf.length)];
341 
342         for (size_t i = firstDom; i < DomBuf.length; ++i)
343             DomBuf1[i] = DomBuf[i];
344         DomBuf = DomBuf1;
345     }
346     if (NextMAlt >= MAlt.length)
347     {
348         auto MAlt1 = new MAltRecord[NewLen(MAlt.length)];
349 
350         for (size_t i = firstMAlt; i < MAlt.length; ++i)
351             MAlt1[i] = MAlt[i];
352         MAlt = MAlt1;
353     }
354     if (NextMemb >= MembBuf.length)
355     {
356         auto MembBuf1 = new int[NewLen(MembBuf.length)];
357 
358         for (size_t i = firstMemb; i < MembBuf.length; ++i)
359             MembBuf1[i] = MembBuf[i];
360         MembBuf = MembBuf1;
361     }
362     if (NextNode >= NodeBuf.length)
363     {
364         auto NodeBuf1 = new int[NewLen(NodeBuf.length)];
365 
366         for (size_t i = firstNode; i < NodeBuf.length; ++i)
367             NodeBuf1[i] = NodeBuf[i];
368         NodeBuf = NodeBuf1;
369     }
370     if (NextVar >= Var.length)
371     {
372         auto Var1 = new VarRecord[NewLen(Var.length)];
373 
374         for (size_t i = firstVar; i < Var.length; ++i)
375             Var1[i] = Var[i];
376         Var = Var1;
377     }
378 }
379 
380 void AppParam(int Affixform, Position Pos) nothrow @safe
381 {
382     ParamBuf[NextParam].Affixform = Affixform;
383     ParamBuf[NextParam].Pos = Pos;
384     ++NextParam;
385     if (NextParam >= ParamBuf.length)
386         Expand;
387 }
388 
389 int FindMTerm(int Id) nothrow @safe
390 {
391     int Sym = firstMTerm;
392 
393     MTerm[NextMTerm].Id = Id;
394     while (Id != MTerm[Sym].Id)
395         ++Sym;
396     if (Sym == NextMTerm)
397     {
398         ++NextMTerm;
399         if (NextMTerm >= MTerm.length)
400             Expand;
401     }
402     return Sym;
403 }
404 
405 int FindMNont(int Id) nothrow @safe
406 {
407     int Sym = firstMNont;
408 
409     MNont[NextMNont].Id = Id;
410     while (Id != MNont[Sym].Id)
411         ++Sym;
412     if (Sym == NextMNont)
413     {
414         MNont[NextMNont].MRule = nil;
415         MNont[NextMNont].Last = nil;
416         MNont[NextMNont].IsToken = false;
417         ++NextMNont;
418         if (NextMNont >= MNont.length)
419             Expand;
420     }
421     return Sym;
422 }
423 
424 int FindHTerm(int Id) nothrow @safe
425 {
426     int Sym = firstHTerm;
427 
428     HTerm[NextHTerm].Id = Id;
429     while (Id != HTerm[Sym].Id)
430         ++Sym;
431     if (Sym == NextHTerm)
432     {
433         ++NextHTerm;
434         if (NextHTerm >= HTerm.length)
435             Expand;
436     }
437     return Sym;
438 }
439 
440 int FindHNont(int Id) nothrow @safe
441 {
442     int Sym = firstHNont;
443 
444     HNont[NextHNont].Id = Id;
445     while (Id != HNont[Sym].Id)
446         ++Sym;
447     if (Sym == NextHNont)
448     {
449         HNont[NextHNont].NamedId = Id;
450         HNont[NextHNont].Sig = -1;
451         HNont[NextHNont].Def = null;
452         HNont[NextHNont].IsToken = false;
453         ++NextHNont;
454         if (NextHNont >= HNont.length)
455             Expand;
456     }
457     return Sym;
458 }
459 
460 int NewAnonymNont(int Id) nothrow @safe
461 {
462     HNont[NextHNont].Id = NextAnonym;
463     HNont[NextHNont].NamedId = Id;
464     HNont[NextHNont].Sig = -1;
465     HNont[NextHNont].Def = null;
466     HNont[NextHNont].IsToken = false;
467     --NextAnonym;
468     ++NextHNont;
469     if (NextHNont >= HNont.length)
470         Expand;
471     return NextHNont - 1;
472 }
473 
474 void AppDom(char Dir, int Dom) nothrow @safe
475 {
476     if (Dir == '-')
477         Dom = -Dom;
478     DomBuf[NextDom] = Dom;
479     ++NextDom;
480     if (NextDom >= DomBuf.length)
481         Expand;
482 }
483 
484 bool WellMatched(int Sig1, int Sig2) @nogc nothrow @safe
485 {
486     if (Sig1 == Sig2)
487         return true;
488     while (DomBuf[Sig1] == DomBuf[Sig2] && DomBuf[Sig1] != nil && DomBuf[Sig2] != nil)
489     {
490         ++Sig1;
491         ++Sig2;
492     }
493     return DomBuf[Sig1] == nil && DomBuf[Sig2] == nil;
494 }
495 
496 bool SigOK(int Sym) nothrow @safe
497 {
498     if (HNont[Sym].Sig < 0)
499     {
500         HNont[Sym].Sig = CurSig;
501         DomBuf[NextDom] = nil;
502         ++NextDom;
503         if (NextDom >= DomBuf.length)
504             Expand;
505         CurSig = NextDom;
506         return true;
507     }
508     DomBuf[NextDom] = nil;
509     NextDom = CurSig;
510     return WellMatched(HNont[Sym].Sig, CurSig);
511 }
512 
513 int NewMAlt(int Sym, int Right) nothrow @safe
514 {
515     int Arity;
516     int i;
517 
518     MAlt[NextMAlt].Next = nil;
519     if (MNont[Sym].MRule == nil)
520         MNont[Sym].MRule = NextMAlt;
521     else
522         MAlt[MNont[Sym].Last].Next = NextMAlt;
523     MNont[Sym].Last = NextMAlt;
524     MAlt[NextMAlt].Left = Sym;
525     MAlt[NextMAlt].Right = Right;
526     i = Right;
527     Arity = 0;
528     while (MembBuf[i] != 0)
529     {
530         if (MembBuf[i] > 0)
531             ++Arity;
532         ++i;
533     }
534     MAlt[NextMAlt].Arity = Arity;
535     if (Arity > MaxMArity)
536         MaxMArity = Arity;
537     ++NextMAlt;
538     if (NextMAlt >= MAlt.length)
539         Expand;
540     return NextMAlt - 1;
541 }
542 
543 void AppMemb(int Val) nothrow @safe
544 {
545     MembBuf[NextMemb] = Val;
546     ++NextMemb;
547     if (NextMemb >= MembBuf.length)
548         Expand;
549 }
550 
551 int FindVar(int Sym, int Num, Position Pos, bool Def) nothrow @safe
552 {
553     int V = Scope;
554 
555     Var[NextVar].Sym = Sym;
556     Var[NextVar].Num = Num;
557     while (Var[V].Sym != Sym || Var[V].Num != Num)
558         ++V;
559     if (V == NextVar)
560     {
561         V = Scope;
562         Var[NextVar].Num = -Num;
563         while (Var[V].Sym != Sym || Var[V].Num != -Num)
564             ++V;
565         if (V != NextVar)
566         {
567             Var[V].Neg = NextVar;
568             Var[NextVar].Neg = V;
569         }
570         else
571         {
572             Var[NextVar].Neg = nil;
573         }
574         V = NextVar;
575         Var[NextVar].Num = Num;
576         Var[NextVar].Pos = Pos;
577         Var[NextVar].Def = Def;
578         ++NextVar;
579         if (NextVar >= Var.length)
580             Expand;
581     }
582     else
583     {
584         Var[V].Def = Var[V].Def || Def;
585     }
586     return V;
587 }
588 
589 void NewTerm(ref Factor F, int Sym, Position Pos) nothrow @safe
590 {
591     Term F1 = new Term;
592 
593     ++NOTerm;
594     F1.Next = null;
595     F1.Sym = Sym;
596     F1.Pos = Pos;
597     F1.Ind = NextHFactor;
598     ++NextHFactor;
599     if (F is null)
600     {
601         F = F1;
602         F.Prev = null;
603     }
604     else
605     {
606         F.Next = F1;
607         F1.Prev = F;
608         F = F.Next;
609     }
610 }
611 
612 void NewNont(ref Factor F, int Sym, ParamsDesc Actual, Position Pos) nothrow @safe
613 {
614     Nont F1 = new Nont;
615 
616     ++NONont;
617     F1.Next = null;
618     F1.Sym = Sym;
619     F1.Actual = Actual;
620     F1.Pos = Pos;
621     F1.Ind = NextHFactor;
622     ++NextHFactor;
623     if (F is null)
624     {
625         F = F1;
626         F.Prev = null;
627     }
628     else
629     {
630         F.Next = F1;
631         F1.Prev = F;
632         F = F.Next;
633     }
634 }
635 
636 void NewGrp(int Sym, Alt Sub) nothrow @safe
637 {
638     if (HNont[Sym].Def is null)
639     {
640         Grp N = new Grp;
641 
642         ++NOGrp;
643         N.Sub = Sub;
644         HNont[Sym].Def = N;
645     }
646     else
647     {
648         Alt A = (cast(Grp) HNont[Sym].Def).Sub;
649 
650         while (A.Next !is null)
651             A = A.Next;
652         A.Next = Sub;
653     }
654 }
655 
656 void NewOpt(int Sym, Alt Sub, ParamsDesc Formal, Position Pos) nothrow @safe
657 {
658     Opt N = new Opt;
659 
660     ++NOOpt;
661     N.Sub = Sub;
662     N.EmptyAltPos = Pos;
663     N.Scope.Beg = nil;
664     N.Scope.End = nil;
665     N.Formal = Formal;
666     HNont[Sym].Def = N;
667 }
668 
669 void NewRep(int Sym, Alt Sub, ParamsDesc Formal, Position Pos) nothrow @safe
670 {
671     Rep N = new Rep;
672 
673     ++NORep;
674     N.Sub = Sub;
675     N.EmptyAltPos = Pos;
676     N.Scope.Beg = nil;
677     N.Scope.End = nil;
678     N.Formal = Formal;
679     HNont[Sym].Def = N;
680 }
681 
682 void NewAlt(ref Alt A, int Sym, ParamsDesc Formal, ParamsDesc Actual, Factor Sub,
683         Factor Last, Position Pos) nothrow @safe
684 {
685     Alt A1 = new Alt;
686 
687     ++NOAlt;
688     A1.Next = null;
689     A1.Up = Sym;
690     A1.Scope.Beg = nil;
691     A1.Scope.End = nil;
692     A1.Formal = Formal;
693     A1.Actual = Actual;
694     A1.Sub = Sub;
695     A1.Last = Last;
696     A1.Pos = Pos;
697     A1.Ind = NextHAlt;
698     ++NextHAlt;
699     if (A is null)
700     {
701         A = A1;
702     }
703     else
704     {
705         A.Next = A1;
706         A = A.Next;
707     }
708 }
709 
710 public string HTermRepr(int Term) @nogc nothrow @safe
711 {
712     return symbolTable.symbol(HTerm[Term].Id);
713 }
714 
715 public string HNontRepr(size_t Nont) @safe
716 {
717     import std.format : format;
718 
719     if (HNont[Nont].anonymous)
720         return format!"A%s"(-HNont[Nont].Id);
721     return symbolTable.symbol(HNont[Nont].Id);
722 }
723 
724 public string VarRepr(int V) nothrow @safe
725 {
726     import std.math : abs;
727 
728     string result;
729 
730     if (Var[V].Num < 0)
731         result ~= '!';
732     result ~= symbolTable.symbol(MNont[Var[V].Sym].Id);
733     if (abs(Var[V].Num) > 1)
734         result ~= symbolTable.symbol(abs(Var[V].Num) - 2);
735     return result;
736 }
737 
738 public string NamedHNontRepr(size_t Nont) @nogc nothrow @safe
739 {
740     return symbolTable.symbol(HNont[Nont].NamedId);
741 }
742 
743 bool Performed(size_t Needed) @safe
744 {
745     import log : error;
746 
747     Needed = Needed & ~History;
748     if (Needed == 0)
749         return true;
750     if (Needed & analysed)
751         error!"analyse a specification first";
752     if (Needed & predicates)
753         error!"check for predicates first";
754     if (Needed & parsable)
755         error!"test for ELL1 attribute first";
756     if (Needed & isSLAG)
757         error!"test for SLAG attribute first";
758     if (Needed & isSweep)
759         error!"test for single-sweep attribute first";
760     if (Needed & hasEvaluator)
761         error!"generate an evaluator first";
762     return false;
763 }
764 
765 void Init() nothrow
766 {
767     ParamBuf = new ParamRecord[1023];
768     NextParam = firstParam;
769     ParamBuf[NextParam].Affixform = nil;
770     ++NextParam;
771 
772     MTerm = new MTermRecord[255];
773     NextMTerm = firstMTerm;
774 
775     MNont = new MNontRecord[255];
776     NextMNont = firstMNont;
777 
778     HTerm = new HTermRecord[255];
779     NextHTerm = firstHTerm;
780 
781     HNont = new HNontRecord[255];
782     NextHNont = firstHNont;
783     NextAnonym = -1;
784 
785     DomBuf = new int[255];
786     NextDom = firstDom;
787     DomBuf[NextDom] = nil;
788     ++NextDom;
789     CurSig = NextDom;
790 
791     MAlt = new MAltRecord[255];
792     NextMAlt = firstMAlt;
793 
794     MembBuf = new int[255];
795     NextMemb = firstMemb;
796 
797     NodeBuf = new int[1023];
798     NextNode = firstNode;
799 
800     Var = new VarRecord[511];
801     NextVar = firstVar;
802     Scope = NextVar;
803 
804     NextHAlt = firstHAlt;
805     NextHFactor = firstHFactor;
806     Null.length = 0;
807     Prod.length = 0;
808     Pred.length = 0;
809     NOAlt = 0;
810     NOTerm = 0;
811     NONont = 0;
812     NOGrp = 0;
813     NOOpt = 0;
814     NORep = 0;
815     History = 0;
816     BaseName = "nothing";
817     MaxMArity = 0;
818 
819     symbolTable = new SymbolTable;
820 }
821 
822 static this() @safe
823 {
824     import log : info;
825 
826     History = 0;
827     BaseName = "nothing";
828     info!"Epsilon 1.02   JoDe/SteWe  22.11.96";
829 }