diff options
Diffstat (limited to 'lptree.c')
-rw-r--r-- | lptree.c | 27 |
1 files changed, 23 insertions, 4 deletions
@@ -28,7 +28,7 @@ const byte numsiblings[] = { | |||
28 | 0, 0, 2, 1, /* call, opencall, rule, grammar */ | 28 | 0, 0, 2, 1, /* call, opencall, rule, grammar */ |
29 | 1, /* behind */ | 29 | 1, /* behind */ |
30 | 1, 1, /* capture, runtime capture */ | 30 | 1, 1, /* capture, runtime capture */ |
31 | 0, 2 /* labeled failure throw, labeled choice */ | 31 | 0, 2, 2 /* labeled failure throw, labeled choice, recovery */ |
32 | }; | 32 | }; |
33 | 33 | ||
34 | 34 | ||
@@ -525,12 +525,12 @@ static TTree *newthrowleaf (lua_State *L, int lab) { | |||
525 | return tree; | 525 | return tree; |
526 | } | 526 | } |
527 | 527 | ||
528 | static TTree *newlabchoice (lua_State *L) { | 528 | static TTree *newrootlab2sib (lua_State *L, int tag) { |
529 | int s1, s2; | 529 | int s1, s2; |
530 | TTree *tree1 = getpatt(L, 1, &s1); | 530 | TTree *tree1 = getpatt(L, 1, &s1); |
531 | TTree *tree2 = getpatt(L, 2, &s2); | 531 | TTree *tree2 = getpatt(L, 2, &s2); |
532 | TTree *tree = newtree(L, bytes2slots(LABELSETSIZE) + 1 + s1 + s2); /* create new tree */ | 532 | TTree *tree = newtree(L, bytes2slots(LABELSETSIZE) + 1 + s1 + s2); /* create new tree */ |
533 | tree->tag = TLabChoice; | 533 | tree->tag = tag; |
534 | tree->u.s.ps = 1 + s1; | 534 | tree->u.s.ps = 1 + s1; |
535 | tree->u.s.plab = 1 + s1 + s2; | 535 | tree->u.s.plab = 1 + s1 + s2; |
536 | memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); | 536 | memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); |
@@ -733,7 +733,7 @@ static int lp_throw (lua_State *L) { | |||
733 | */ | 733 | */ |
734 | static int lp_labchoice (lua_State *L) { | 734 | static int lp_labchoice (lua_State *L) { |
735 | int n = lua_gettop(L); | 735 | int n = lua_gettop(L); |
736 | TTree *tree = newlabchoice(L); | 736 | TTree *tree = newrootlab2sib(L, TLabChoice); |
737 | int i; | 737 | int i; |
738 | for (i = 3; i <= n; i++) { | 738 | for (i = 3; i <= n; i++) { |
739 | int d = luaL_checkinteger(L, i); | 739 | int d = luaL_checkinteger(L, i); |
@@ -742,6 +742,24 @@ static int lp_labchoice (lua_State *L) { | |||
742 | } | 742 | } |
743 | return 1; | 743 | return 1; |
744 | } | 744 | } |
745 | |||
746 | |||
747 | static int lp_recovery (lua_State *L) { | ||
748 | int n = lua_gettop(L); | ||
749 | TTree *tree = newrootlab2sib(L, TRecov); | ||
750 | if (n == 2) { /* catches fail as default */ | ||
751 | setlabel(treelabelset(tree), LFAIL); | ||
752 | } else { | ||
753 | int i; | ||
754 | for (i = 3; i <= n; i++) { | ||
755 | int d = luaL_checkinteger(L, i); | ||
756 | luaL_argcheck(L, d >= 0 && d < MAXLABELS, i, "the number of a label must be between 0 and 255"); | ||
757 | setlabel(treelabelset(tree), (byte)d); | ||
758 | } | ||
759 | } | ||
760 | return 1; | ||
761 | } | ||
762 | |||
745 | /* labeled failure end */ | 763 | /* labeled failure end */ |
746 | 764 | ||
747 | 765 | ||
@@ -1325,6 +1343,7 @@ static struct luaL_Reg pattreg[] = { | |||
1325 | {"type", lp_type}, | 1343 | {"type", lp_type}, |
1326 | {"T", lp_throw}, /* labeled failure throw */ | 1344 | {"T", lp_throw}, /* labeled failure throw */ |
1327 | {"Lc", lp_labchoice}, /* labeled failure choice */ | 1345 | {"Lc", lp_labchoice}, /* labeled failure choice */ |
1346 | {"Rec", lp_recovery}, /* labeled failure choice */ | ||
1328 | {NULL, NULL} | 1347 | {NULL, NULL} |
1329 | }; | 1348 | }; |
1330 | 1349 | ||