diff options
Diffstat (limited to 'lptree.c')
-rw-r--r-- | lptree.c | 94 |
1 files changed, 50 insertions, 44 deletions
@@ -34,7 +34,6 @@ const byte numsiblings[] = { | |||
34 | 34 | ||
35 | static TTree *newgrammar (lua_State *L, int arg); | 35 | static TTree *newgrammar (lua_State *L, int arg); |
36 | 36 | ||
37 | |||
38 | /* | 37 | /* |
39 | ** returns a reasonable name for value at index 'idx' on the stack | 38 | ** returns a reasonable name for value at index 'idx' on the stack |
40 | */ | 39 | */ |
@@ -63,7 +62,7 @@ static void fixonecall (lua_State *L, int postable, TTree *g, TTree *t) { | |||
63 | luaL_error(L, "rule '%s' undefined in given grammar", val2str(L, -1)); | 62 | luaL_error(L, "rule '%s' undefined in given grammar", val2str(L, -1)); |
64 | } | 63 | } |
65 | t->tag = TCall; | 64 | t->tag = TCall; |
66 | t->u.ps = n - (t - g); /* position relative to node */ | 65 | t->u.s.ps = n - (t - g); /* position relative to node */ |
67 | assert(sib2(t)->tag == TRule); | 66 | assert(sib2(t)->tag == TRule); |
68 | sib2(t)->key = t->key; | 67 | sib2(t)->key = t->key; |
69 | } | 68 | } |
@@ -80,13 +79,13 @@ static void correctassociativity (TTree *tree) { | |||
80 | TTree *t1 = sib1(tree); | 79 | TTree *t1 = sib1(tree); |
81 | assert(tree->tag == TChoice || tree->tag == TSeq); | 80 | assert(tree->tag == TChoice || tree->tag == TSeq); |
82 | while (t1->tag == tree->tag) { | 81 | while (t1->tag == tree->tag) { |
83 | int n1size = tree->u.ps - 1; /* t1 == Op t11 t12 */ | 82 | int n1size = tree->u.s.ps - 1; /* t1 == Op t11 t12 */ |
84 | int n11size = t1->u.ps - 1; | 83 | int n11size = t1->u.s.ps - 1; |
85 | int n12size = n1size - n11size - 1; | 84 | int n12size = n1size - n11size - 1; |
86 | memmove(sib1(tree), sib1(t1), n11size * sizeof(TTree)); /* move t11 */ | 85 | memmove(sib1(tree), sib1(t1), n11size * sizeof(TTree)); /* move t11 */ |
87 | tree->u.ps = n11size + 1; | 86 | tree->u.s.ps = n11size + 1; |
88 | sib2(tree)->tag = tree->tag; | 87 | sib2(tree)->tag = tree->tag; |
89 | sib2(tree)->u.ps = n12size + 1; | 88 | sib2(tree)->u.s.ps = n12size + 1; |
90 | } | 89 | } |
91 | } | 90 | } |
92 | 91 | ||
@@ -375,16 +374,6 @@ static TTree *newleaf (lua_State *L, int tag) { | |||
375 | } | 374 | } |
376 | 375 | ||
377 | 376 | ||
378 | /* labeled failure begin */ | ||
379 | static TTree *newlabelleaf (lua_State *L, Labelset ls) { | ||
380 | TTree *tree = newtree(L, 1); | ||
381 | tree->tag = TThrow; | ||
382 | tree->labels = ls; | ||
383 | return tree; | ||
384 | } | ||
385 | /* labeled failure end */ | ||
386 | |||
387 | |||
388 | static TTree *newcharset (lua_State *L) { | 377 | static TTree *newcharset (lua_State *L) { |
389 | TTree *tree = newtree(L, bytes2slots(CHARSETSIZE) + 1); | 378 | TTree *tree = newtree(L, bytes2slots(CHARSETSIZE) + 1); |
390 | tree->tag = TSet; | 379 | tree->tag = TSet; |
@@ -398,7 +387,7 @@ static TTree *newcharset (lua_State *L) { | |||
398 | ** 'sibsize'); returns position for second sibling | 387 | ** 'sibsize'); returns position for second sibling |
399 | */ | 388 | */ |
400 | static TTree *seqaux (TTree *tree, TTree *sib, int sibsize) { | 389 | static TTree *seqaux (TTree *tree, TTree *sib, int sibsize) { |
401 | tree->tag = TSeq; tree->u.ps = sibsize + 1; | 390 | tree->tag = TSeq; tree->u.s.ps = sibsize + 1; |
402 | memcpy(sib1(tree), sib, sibsize * sizeof(TTree)); | 391 | memcpy(sib1(tree), sib, sibsize * sizeof(TTree)); |
403 | return sib2(tree); | 392 | return sib2(tree); |
404 | } | 393 | } |
@@ -412,7 +401,7 @@ static TTree *seqaux (TTree *tree, TTree *sib, int sibsize) { | |||
412 | static void fillseq (TTree *tree, int tag, int n, const char *s) { | 401 | static void fillseq (TTree *tree, int tag, int n, const char *s) { |
413 | int i; | 402 | int i; |
414 | for (i = 0; i < n - 1; i++) { /* initial n-1 copies of Seq tag; Seq ... */ | 403 | for (i = 0; i < n - 1; i++) { /* initial n-1 copies of Seq tag; Seq ... */ |
415 | tree->tag = TSeq; tree->u.ps = 2; | 404 | tree->tag = TSeq; tree->u.s.ps = 2; |
416 | sib1(tree)->tag = tag; | 405 | sib1(tree)->tag = tag; |
417 | sib1(tree)->u.n = s ? (byte)s[i] : 0; | 406 | sib1(tree)->u.n = s ? (byte)s[i] : 0; |
418 | tree = sib2(tree); | 407 | tree = sib2(tree); |
@@ -519,7 +508,7 @@ static TTree *newroot2sib (lua_State *L, int tag) { | |||
519 | TTree *tree2 = getpatt(L, 2, &s2); | 508 | TTree *tree2 = getpatt(L, 2, &s2); |
520 | TTree *tree = newtree(L, 1 + s1 + s2); /* create new tree */ | 509 | TTree *tree = newtree(L, 1 + s1 + s2); /* create new tree */ |
521 | tree->tag = tag; | 510 | tree->tag = tag; |
522 | tree->u.ps = 1 + s1; | 511 | tree->u.s.ps = 1 + s1; |
523 | memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); | 512 | memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); |
524 | memcpy(sib2(tree), tree2, s2 * sizeof(TTree)); | 513 | memcpy(sib2(tree), tree2, s2 * sizeof(TTree)); |
525 | joinktables(L, 1, sib2(tree), 2); | 514 | joinktables(L, 1, sib2(tree), 2); |
@@ -527,6 +516,32 @@ static TTree *newroot2sib (lua_State *L, int tag) { | |||
527 | } | 516 | } |
528 | 517 | ||
529 | 518 | ||
519 | /* labeled failure begin */ | ||
520 | static TTree *newthrowleaf (lua_State *L, int lab) { | ||
521 | TTree *tree = newtree(L, 1); | ||
522 | tree->tag = TThrow; | ||
523 | tree->u.label = lab; | ||
524 | return tree; | ||
525 | } | ||
526 | |||
527 | static TTree *newlabchoice (lua_State *L) { | ||
528 | int s1, s2; | ||
529 | TTree *tree1 = getpatt(L, 1, &s1); | ||
530 | TTree *tree2 = getpatt(L, 2, &s2); | ||
531 | TTree *tree = newtree(L, bytes2slots(LABELSETSIZE) + 1 + s1 + s2); /* create new tree */ | ||
532 | tree->tag = TLabChoice; | ||
533 | tree->u.s.ps = 1 + s1; | ||
534 | tree->u.s.plab = 1 + s1 + s2; | ||
535 | memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); | ||
536 | memcpy(sib2(tree), tree2, s2 * sizeof(TTree)); | ||
537 | loopset(i, treelabelset(tree)[i] = 0); | ||
538 | joinktables(L, 1, sib2(tree), 2); | ||
539 | return tree; | ||
540 | } | ||
541 | /* labeled failure end */ | ||
542 | |||
543 | |||
544 | |||
530 | static int lp_P (lua_State *L) { | 545 | static int lp_P (lua_State *L) { |
531 | luaL_checkany(L, 1); | 546 | luaL_checkany(L, 1); |
532 | getpatt(L, 1, NULL); | 547 | getpatt(L, 1, NULL); |
@@ -548,7 +563,7 @@ static int lp_seq (lua_State *L) { | |||
548 | else if (tree1->tag == TTrue) | 563 | else if (tree1->tag == TTrue) |
549 | lua_pushvalue(L, 2); /* true . x = x */ | 564 | lua_pushvalue(L, 2); /* true . x = x */ |
550 | else | 565 | else |
551 | newroot2sib(L, TSeq); | 566 | newroot2sib(L, TSeq); |
552 | return 1; | 567 | return 1; |
553 | } | 568 | } |
554 | 569 | ||
@@ -599,12 +614,12 @@ static int lp_star (lua_State *L) { | |||
599 | /* size = (choice + seq + tree1 + true) * n, but the last has no seq */ | 614 | /* size = (choice + seq + tree1 + true) * n, but the last has no seq */ |
600 | tree = newtree(L, n * (size1 + 3) - 1); | 615 | tree = newtree(L, n * (size1 + 3) - 1); |
601 | for (; n > 1; n--) { /* repeat (n - 1) times */ | 616 | for (; n > 1; n--) { /* repeat (n - 1) times */ |
602 | tree->tag = TChoice; tree->u.ps = n * (size1 + 3) - 2; | 617 | tree->tag = TChoice; tree->u.s.ps = n * (size1 + 3) - 2; |
603 | sib2(tree)->tag = TTrue; | 618 | sib2(tree)->tag = TTrue; |
604 | tree = sib1(tree); | 619 | tree = sib1(tree); |
605 | tree = seqaux(tree, tree1, size1); | 620 | tree = seqaux(tree, tree1, size1); |
606 | } | 621 | } |
607 | tree->tag = TChoice; tree->u.ps = size1 + 1; | 622 | tree->tag = TChoice; tree->u.s.ps = size1 + 1; |
608 | sib2(tree)->tag = TTrue; | 623 | sib2(tree)->tag = TTrue; |
609 | memcpy(sib1(tree), tree1, size1 * sizeof(TTree)); | 624 | memcpy(sib1(tree), tree1, size1 * sizeof(TTree)); |
610 | } | 625 | } |
@@ -647,7 +662,7 @@ static int lp_sub (lua_State *L) { | |||
647 | else { | 662 | else { |
648 | TTree *tree = newtree(L, 2 + s1 + s2); | 663 | TTree *tree = newtree(L, 2 + s1 + s2); |
649 | tree->tag = TSeq; /* sequence of... */ | 664 | tree->tag = TSeq; /* sequence of... */ |
650 | tree->u.ps = 2 + s2; | 665 | tree->u.s.ps = 2 + s2; |
651 | sib1(tree)->tag = TNot; /* ...not... */ | 666 | sib1(tree)->tag = TNot; /* ...not... */ |
652 | memcpy(sib1(sib1(tree)), t2, s2 * sizeof(TTree)); /* ...t2 */ | 667 | memcpy(sib1(sib1(tree)), t2, s2 * sizeof(TTree)); /* ...t2 */ |
653 | memcpy(sib2(tree), t1, s1 * sizeof(TTree)); /* ... and t1 */ | 668 | memcpy(sib2(tree), t1, s1 * sizeof(TTree)); /* ... and t1 */ |
@@ -703,18 +718,12 @@ static int lp_behind (lua_State *L) { | |||
703 | 718 | ||
704 | /* labeled failure begin */ | 719 | /* labeled failure begin */ |
705 | /* | 720 | /* |
706 | ** Throws a label or a set of labels | 721 | ** Throws a label |
707 | */ | 722 | */ |
708 | static int lp_throw (lua_State *L) { | 723 | static int lp_throw (lua_State *L) { |
709 | int n = lua_gettop(L); | 724 | int label = luaL_checkinteger(L, -1); |
710 | Labelset ls = 0; | 725 | luaL_argcheck(L, label >= 0 && label < MAXLABELS, -1, "max or min label index exceeded"); |
711 | int i; | 726 | newthrowleaf(L, label); |
712 | for (i = 1; i <= n; i++) { | ||
713 | long long int d = (long long int)luaL_checkinteger(L, i); | ||
714 | luaL_argcheck(L, d >= 0 && d < (long long int)MAXLABELS, i, "invalid label index"); | ||
715 | setlabel(ls, d); | ||
716 | } | ||
717 | newlabelleaf(L, ls); | ||
718 | return 1; | 727 | return 1; |
719 | } | 728 | } |
720 | 729 | ||
@@ -722,17 +731,14 @@ static int lp_throw (lua_State *L) { | |||
722 | ** labeled choice function | 731 | ** labeled choice function |
723 | */ | 732 | */ |
724 | static int lp_labchoice (lua_State *L) { | 733 | static int lp_labchoice (lua_State *L) { |
725 | TTree *tree; | ||
726 | int n = lua_gettop(L); | 734 | int n = lua_gettop(L); |
735 | TTree *tree = newlabchoice(L); | ||
727 | int i; | 736 | int i; |
728 | Labelset ls = 0; | ||
729 | for (i = 3; i <= n; i++) { | 737 | for (i = 3; i <= n; i++) { |
730 | long long int d = (long long int)luaL_checkinteger(L, i); | 738 | int d = luaL_checkinteger(L, i); |
731 | luaL_argcheck(L, d >= 0 && d < (long long int)MAXLABELS, i, "invalid label index"); | 739 | luaL_argcheck(L, d >= 0 && d < MAXLABELS, i, "max or min label index exceeded"); |
732 | setlabel(ls, d); | 740 | setlabel(treelabelset(tree), (byte)d); |
733 | } | 741 | } |
734 | tree = newroot2sib(L, TLabChoice); | ||
735 | tree->labels = ls; | ||
736 | return 1; | 742 | return 1; |
737 | } | 743 | } |
738 | /* labeled failure end */ | 744 | /* labeled failure end */ |
@@ -883,7 +889,7 @@ static int lp_constcapture (lua_State *L) { | |||
883 | tree = sib1(tree); | 889 | tree = sib1(tree); |
884 | for (i = 1; i <= n - 1; i++) { | 890 | for (i = 1; i <= n - 1; i++) { |
885 | tree->tag = TSeq; | 891 | tree->tag = TSeq; |
886 | tree->u.ps = 3; /* skip TCapture and its sibling */ | 892 | tree->u.s.ps = 3; /* skip TCapture and its sibling */ |
887 | auxemptycap(sib1(tree), Cconst); | 893 | auxemptycap(sib1(tree), Cconst); |
888 | sib1(tree)->key = addtoktable(L, i); | 894 | sib1(tree)->key = addtoktable(L, i); |
889 | tree = sib2(tree); | 895 | tree = sib2(tree); |
@@ -985,7 +991,7 @@ static void buildgrammar (lua_State *L, TTree *grammar, int frule, int n) { | |||
985 | nd->tag = TRule; | 991 | nd->tag = TRule; |
986 | nd->key = 0; | 992 | nd->key = 0; |
987 | nd->cap = i; /* rule number */ | 993 | nd->cap = i; /* rule number */ |
988 | nd->u.ps = rulesize + 1; /* point to next rule */ | 994 | nd->u.s.ps = rulesize + 1; /* point to next rule */ |
989 | memcpy(sib1(nd), rn, rulesize * sizeof(TTree)); /* copy rule */ | 995 | memcpy(sib1(nd), rn, rulesize * sizeof(TTree)); /* copy rule */ |
990 | mergektable(L, ridx, sib1(nd)); /* merge its ktable into new one */ | 996 | mergektable(L, ridx, sib1(nd)); /* merge its ktable into new one */ |
991 | nd = sib2(nd); /* move to next rule */ | 997 | nd = sib2(nd); /* move to next rule */ |
@@ -1213,8 +1219,8 @@ static int lp_match (lua_State *L) { | |||
1213 | long long int j = 0; | 1219 | long long int j = 0; |
1214 | int n = 1; | 1220 | int n = 1; |
1215 | lua_pushnil(L); | 1221 | lua_pushnil(L); |
1216 | while (j < (long long int) MAXLABELS) { | 1222 | while (j < MAXLABELS) { |
1217 | if (labelf & (1ULL << j)) { | 1223 | if (testlabel(labelf.cs, j)) { |
1218 | lua_pushinteger(L, j); | 1224 | lua_pushinteger(L, j); |
1219 | n++; | 1225 | n++; |
1220 | break; /* Changing the semantics: only one label */ | 1226 | break; /* Changing the semantics: only one label */ |