aboutsummaryrefslogtreecommitdiff
path: root/lptree.c
diff options
context:
space:
mode:
authorSérgio Queiroz <sqmedeiros@gmail.com>2017-12-15 13:50:35 -0300
committerSérgio Queiroz <sqmedeiros@gmail.com>2017-12-15 13:50:35 -0300
commitbc071e9fe431347832fd424eb327357f38e60bfd (patch)
tree9a34ad8d53074b002322484504e756b542b3bdf7 /lptree.c
parent26c1b9aa78e10b2ed2d36d151033fe94254fa8c5 (diff)
downloadlpeglabel-bc071e9fe431347832fd424eb327357f38e60bfd.tar.gz
lpeglabel-bc071e9fe431347832fd424eb327357f38e60bfd.tar.bz2
lpeglabel-bc071e9fe431347832fd424eb327357f38e60bfd.zip
Updating the recovery mechanism when a label is thrown
Diffstat (limited to 'lptree.c')
-rw-r--r--lptree.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/lptree.c b/lptree.c
index fea2ecf..1e8de3e 100644
--- a/lptree.c
+++ b/lptree.c
@@ -52,20 +52,24 @@ static const char *val2str (lua_State *L, int idx) {
52** translate a key to its rule address in the tree. Raises an 52** translate a key to its rule address in the tree. Raises an
53** error if key does not exist. 53** error if key does not exist.
54*/ 54*/
55static void fixonecall (lua_State *L, int postable, TTree *g, TTree *t) { 55static void fixonecall (lua_State *L, int postable, TTree *g, TTree *t, byte tag) { /* labeled failure */
56 int n; 56 int n;
57 lua_rawgeti(L, -1, t->key); /* get rule's name */ 57 lua_rawgeti(L, -1, t->key); /* get rule's name */
58 lua_gettable(L, postable); /* query name in position table */ 58 lua_gettable(L, postable); /* query name in position table */
59 n = lua_tonumber(L, -1); /* get (absolute) position */ 59 n = lua_tonumber(L, -1); /* get (absolute) position */
60 lua_pop(L, 1); /* remove position */ 60 lua_pop(L, 1); /* remove position */
61 if (n == 0) { /* no position? */ 61 if (tag == TOpenCall) {
62 lua_rawgeti(L, -1, t->key); /* get rule's name again */ 62 if (n == 0) { /* no position? */
63 luaL_error(L, "rule '%s' undefined in given grammar", val2str(L, -1)); 63 lua_rawgeti(L, -1, t->key); /* get rule's name again */
64 luaL_error(L, "rule '%s' undefined in given grammar", val2str(L, -1));
65 }
66 t->tag = TCall;
67 t->u.s.ps = n - (t - g); /* position relative to node */
68 assert(sib2(t)->tag == TRule);
69 sib2(t)->key = t->key; /* fix rule's key */
70 } else if (n != 0) { /* labeled failure */
71 t->u.s.ps = n - (t - g); /* position relative to node */
64 } 72 }
65 t->tag = TCall;
66 t->u.s.ps = n - (t - g); /* position relative to node */
67 assert(sib2(t)->tag == TRule);
68 sib2(t)->key = t->key; /* fix rule's key */
69} 73}
70 74
71 75
@@ -105,13 +109,18 @@ static void finalfix (lua_State *L, int postable, TTree *g, TTree *t) {
105 return; 109 return;
106 case TOpenCall: { 110 case TOpenCall: {
107 if (g != NULL) /* inside a grammar? */ 111 if (g != NULL) /* inside a grammar? */
108 fixonecall(L, postable, g, t); 112 fixonecall(L, postable, g, t, TOpenCall);
109 else { /* open call outside grammar */ 113 else { /* open call outside grammar */
110 lua_rawgeti(L, -1, t->key); 114 lua_rawgeti(L, -1, t->key);
111 luaL_error(L, "rule '%s' used outside a grammar", val2str(L, -1)); 115 luaL_error(L, "rule '%s' used outside a grammar", val2str(L, -1));
112 } 116 }
113 break; 117 break;
114 } 118 }
119 case TThrow: { /* labeled failure */
120 if (g != NULL) /* inside a grammar? */
121 fixonecall(L, postable, g, t, TThrow);
122 break;
123 }
115 case TSeq: case TChoice: 124 case TSeq: case TChoice:
116 correctassociativity(t); 125 correctassociativity(t);
117 break; 126 break;
@@ -521,7 +530,7 @@ static TTree *newroot2sib (lua_State *L, int tag) {
521static TTree *newthrowleaf (lua_State *L, int lab) { 530static TTree *newthrowleaf (lua_State *L, int lab) {
522 TTree *tree = newtree(L, 1); 531 TTree *tree = newtree(L, 1);
523 tree->tag = TThrow; 532 tree->tag = TThrow;
524 tree->u.label = lab; 533 tree->u.s.ps = 0;
525 return tree; 534 return tree;
526} 535}
527 536
@@ -726,8 +735,7 @@ static int lp_throw (lua_State *L) {
726 TTree * tree; 735 TTree * tree;
727 luaL_checkstring(L, -1); 736 luaL_checkstring(L, -1);
728 tree = newthrowleaf(L, 0); 737 tree = newthrowleaf(L, 0);
729 tree->u.label = addtonewktable(L, 0, 1); 738 tree->key = addtonewktable(L, 0, 1);
730 tree->key = tree->u.label;
731 /*printf("lp_throw %d %s\n", tree->key, lua_tostring(L, 1));*/ 739 /*printf("lp_throw %d %s\n", tree->key, lua_tostring(L, 1));*/
732 return 1; 740 return 1;
733} 741}