diff options
author | Sérgio Queiroz <sqmedeiros@gmail.com> | 2017-12-15 13:50:35 -0300 |
---|---|---|
committer | Sérgio Queiroz <sqmedeiros@gmail.com> | 2017-12-15 13:50:35 -0300 |
commit | bc071e9fe431347832fd424eb327357f38e60bfd (patch) | |
tree | 9a34ad8d53074b002322484504e756b542b3bdf7 /lptree.c | |
parent | 26c1b9aa78e10b2ed2d36d151033fe94254fa8c5 (diff) | |
download | lpeglabel-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.c | 32 |
1 files changed, 20 insertions, 12 deletions
@@ -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 | */ |
55 | static void fixonecall (lua_State *L, int postable, TTree *g, TTree *t) { | 55 | static 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) { | |||
521 | static TTree *newthrowleaf (lua_State *L, int lab) { | 530 | static 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 | } |