diff options
author | Sergio Medeiros <sqmedeiros@gmail.com> | 2014-11-13 16:54:52 -0300 |
---|---|---|
committer | Sergio Medeiros <sqmedeiros@gmail.com> | 2014-11-13 16:54:52 -0300 |
commit | a5a4b257e626847be3be4878c603adb51cbb420f (patch) | |
tree | 264346e52b60a17f7d610bca787528920d1f69c5 | |
parent | 4d9fd92a7fcd124b2dc62e149bf218a6d2f5d711 (diff) | |
download | lpeglabel-a5a4b257e626847be3be4878c603adb51cbb420f.tar.gz lpeglabel-a5a4b257e626847be3be4878c603adb51cbb420f.tar.bz2 lpeglabel-a5a4b257e626847be3be4878c603adb51cbb420f.zip |
'match' function now returns the 'nil' plus a list of labels
-rw-r--r-- | lptree.c | 14 | ||||
-rw-r--r-- | lpvm.c | 19 | ||||
-rw-r--r-- | lpvm.h | 2 |
3 files changed, 22 insertions, 13 deletions
@@ -1142,13 +1142,23 @@ static int lp_match (lua_State *L) { | |||
1142 | const char *s = luaL_checklstring(L, SUBJIDX, &l); | 1142 | const char *s = luaL_checklstring(L, SUBJIDX, &l); |
1143 | size_t i = initposition(L, l); | 1143 | size_t i = initposition(L, l); |
1144 | int ptop = lua_gettop(L); | 1144 | int ptop = lua_gettop(L); |
1145 | Labelset labelf; /* labeled failure */ | ||
1145 | lua_pushnil(L); /* initialize subscache */ | 1146 | lua_pushnil(L); /* initialize subscache */ |
1146 | lua_pushlightuserdata(L, capture); /* initialize caplistidx */ | 1147 | lua_pushlightuserdata(L, capture); /* initialize caplistidx */ |
1147 | lua_getfenv(L, 1); /* initialize penvidx */ | 1148 | lua_getfenv(L, 1); /* initialize penvidx */ |
1148 | r = match(L, s, s + i, s + l, code, capture, ptop); | 1149 | r = match(L, s, s + i, s + l, code, capture, ptop, &labelf); |
1149 | if (r == NULL) { | 1150 | if (r == NULL) { |
1151 | int j = 0; | ||
1152 | int n = 1; | ||
1150 | lua_pushnil(L); | 1153 | lua_pushnil(L); |
1151 | return 1; | 1154 | while (j < (int) MAXLABELS) { |
1155 | if (labelf & (1 << j)) { | ||
1156 | lua_pushinteger(L, j); | ||
1157 | n++; | ||
1158 | } | ||
1159 | j++; | ||
1160 | } | ||
1161 | return n; | ||
1152 | } | 1162 | } |
1153 | return getcaptures(L, s, r, ptop); | 1163 | return getcaptures(L, s, r, ptop); |
1154 | } | 1164 | } |
@@ -146,7 +146,7 @@ static int removedyncap (lua_State *L, Capture *capture, | |||
146 | ** Opcode interpreter | 146 | ** Opcode interpreter |
147 | */ | 147 | */ |
148 | const char *match (lua_State *L, const char *o, const char *s, const char *e, | 148 | const char *match (lua_State *L, const char *o, const char *s, const char *e, |
149 | Instruction *op, Capture *capture, int ptop) { | 149 | Instruction *op, Capture *capture, int ptop, Labelset *labelf) { |
150 | Stack stackbase[INITBACK]; | 150 | Stack stackbase[INITBACK]; |
151 | Stack *stacklimit = stackbase + INITBACK; | 151 | Stack *stacklimit = stackbase + INITBACK; |
152 | Stack *stack = stackbase; /* point to first empty slot in stack */ | 152 | Stack *stack = stackbase; /* point to first empty slot in stack */ |
@@ -154,7 +154,6 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
154 | int captop = 0; /* point to first empty slot in captures */ | 154 | int captop = 0; /* point to first empty slot in captures */ |
155 | int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ | 155 | int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ |
156 | const Instruction *p = op; /* current instruction */ | 156 | const Instruction *p = op; /* current instruction */ |
157 | Labelset labelf; /* labeled failure */ | ||
158 | stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++; | 157 | stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++; |
159 | lua_pushlightuserdata(L, stackbase); | 158 | lua_pushlightuserdata(L, stackbase); |
160 | for (;;) { | 159 | for (;;) { |
@@ -184,7 +183,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
184 | case IAny: { | 183 | case IAny: { |
185 | if (s < e) { p++; s++; } | 184 | if (s < e) { p++; s++; } |
186 | else { | 185 | else { |
187 | labelf = LFAIL; /* labeled failure */ | 186 | *labelf = LFAIL; /* labeled failure */ |
188 | goto fail; | 187 | goto fail; |
189 | } | 188 | } |
190 | continue; | 189 | continue; |
@@ -197,7 +196,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
197 | case IChar: { | 196 | case IChar: { |
198 | if ((byte)*s == p->i.aux && s < e) { p++; s++; } | 197 | if ((byte)*s == p->i.aux && s < e) { p++; s++; } |
199 | else { | 198 | else { |
200 | labelf = LFAIL; /* labeled failure */ | 199 | *labelf = LFAIL; /* labeled failure */ |
201 | goto fail; | 200 | goto fail; |
202 | } | 201 | } |
203 | continue; | 202 | continue; |
@@ -212,7 +211,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
212 | if (testchar((p+1)->buff, c) && s < e) | 211 | if (testchar((p+1)->buff, c) && s < e) |
213 | { p += CHARSETINSTSIZE; s++; } | 212 | { p += CHARSETINSTSIZE; s++; } |
214 | else { | 213 | else { |
215 | labelf = LFAIL; /* labeled failure */ | 214 | *labelf = LFAIL; /* labeled failure */ |
216 | goto fail; | 215 | goto fail; |
217 | } | 216 | } |
218 | continue; | 217 | continue; |
@@ -227,7 +226,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
227 | case IBehind: { | 226 | case IBehind: { |
228 | int n = p->i.aux; | 227 | int n = p->i.aux; |
229 | if (n > s - o) { | 228 | if (n > s - o) { |
230 | labelf = LFAIL; /* labeled failure */ | 229 | *labelf = LFAIL; /* labeled failure */ |
231 | goto fail; | 230 | goto fail; |
232 | } | 231 | } |
233 | s -= n; p++; | 232 | s -= n; p++; |
@@ -298,7 +297,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
298 | continue; | 297 | continue; |
299 | } | 298 | } |
300 | case IThrow: { /* labeled failure */ | 299 | case IThrow: { /* labeled failure */ |
301 | labelf = (p+1)->labels; | 300 | *labelf = (p+1)->labels; |
302 | goto fail; | 301 | goto fail; |
303 | } | 302 | } |
304 | case IFailTwice: | 303 | case IFailTwice: |
@@ -306,14 +305,14 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
306 | stack--; | 305 | stack--; |
307 | /* go through */ | 306 | /* go through */ |
308 | case IFail: | 307 | case IFail: |
309 | labelf = LFAIL; /* labeled failure */ | 308 | *labelf = LFAIL; /* labeled failure */ |
310 | fail: { /* pattern failed: try to backtrack */ | 309 | fail: { /* pattern failed: try to backtrack */ |
311 | do { /* remove pending calls */ | 310 | do { /* remove pending calls */ |
312 | assert(stack > getstackbase(L, ptop)); | 311 | assert(stack > getstackbase(L, ptop)); |
313 | s = (--stack)->s; | 312 | s = (--stack)->s; |
314 | /*printf("fail (s == NULL => %d), labelf=%d stack->ls=%d (stack-> == giveup %d)\n", | 313 | /*printf("fail (s == NULL => %d), labelf=%d stack->ls=%d (stack-> == giveup %d)\n", |
315 | s == NULL, labelf, stack->ls, stack->p == &giveup);*/ | 314 | s == NULL, labelf, stack->ls, stack->p == &giveup);*/ |
316 | } while (s == NULL || (!(stack->ls & labelf) && stack->p != &giveup)); | 315 | } while (s == NULL || (!(stack->ls & *labelf) && stack->p != &giveup)); |
317 | if (ndyncap > 0) /* is there matchtime captures? */ | 316 | if (ndyncap > 0) /* is there matchtime captures? */ |
318 | ndyncap -= removedyncap(L, capture, stack->caplevel, captop); | 317 | ndyncap -= removedyncap(L, capture, stack->caplevel, captop); |
319 | captop = stack->caplevel; | 318 | captop = stack->caplevel; |
@@ -330,7 +329,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e, | |||
330 | fr -= rem; /* 'rem' items were popped from Lua stack */ | 329 | fr -= rem; /* 'rem' items were popped from Lua stack */ |
331 | res = resdyncaptures(L, fr, s - o, e - o); /* get result */ | 330 | res = resdyncaptures(L, fr, s - o, e - o); /* get result */ |
332 | if (res == -1) { /* fail? */ | 331 | if (res == -1) { /* fail? */ |
333 | labelf = LFAIL; /* labeled failure */ | 332 | *labelf = LFAIL; /* labeled failure */ |
334 | goto fail; | 333 | goto fail; |
335 | } | 334 | } |
336 | s = o + res; /* else update current position */ | 335 | s = o + res; /* else update current position */ |
@@ -55,7 +55,7 @@ typedef union Instruction { | |||
55 | int getposition (lua_State *L, int t, int i); | 55 | int getposition (lua_State *L, int t, int i); |
56 | void printpatt (Instruction *p, int n); | 56 | void printpatt (Instruction *p, int n); |
57 | const char *match (lua_State *L, const char *o, const char *s, const char *e, | 57 | const char *match (lua_State *L, const char *o, const char *s, const char *e, |
58 | Instruction *op, Capture *capture, int ptop); | 58 | Instruction *op, Capture *capture, int ptop, Labelset *labelf); |
59 | int verify (lua_State *L, Instruction *op, const Instruction *p, | 59 | int verify (lua_State *L, Instruction *op, const Instruction *p, |
60 | Instruction *e, int postable, int rule); | 60 | Instruction *e, int postable, int rule); |
61 | void checkrule (lua_State *L, Instruction *op, int from, int to, | 61 | void checkrule (lua_State *L, Instruction *op, int from, int to, |