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 }