aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergio Queiroz <sqmedeiros@gmail.com>2015-09-11 15:01:10 -0300
committerSergio Queiroz <sqmedeiros@gmail.com>2015-09-11 15:01:10 -0300
commit8ac31b94b88227222b189c447aeea1b4131eed18 (patch)
tree8a913ad00c03d15cd2cb5bcedd10ddba65b01e3b
parentce9f1486d1d11699e8099d13c6f65fabe372385d (diff)
downloadlpeglabel-8ac31b94b88227222b189c447aeea1b4131eed18.tar.gz
lpeglabel-8ac31b94b88227222b189c447aeea1b4131eed18.tar.bz2
lpeglabel-8ac31b94b88227222b189c447aeea1b4131eed18.zip
Result of an unsuccessful matching is label + subject
-rw-r--r--examples/listId1.lua6
-rw-r--r--lptree.c8
-rw-r--r--lpvm.c10
-rw-r--r--lpvm.h2
4 files changed, 19 insertions, 7 deletions
diff --git a/examples/listId1.lua b/examples/listId1.lua
index e075bd1..0bf26a1 100644
--- a/examples/listId1.lua
+++ b/examples/listId1.lua
@@ -8,12 +8,12 @@ local g = m.P{
8} 8}
9 9
10function mymatch (g, s) 10function mymatch (g, s)
11 local r, e = g:match(s) 11 local r, e, sfail = g:match(s)
12 if not r then 12 if not r then
13 if e == 1 then 13 if e == 1 then
14 return r, "Error: expecting an identifier" 14 return r, "Error: expecting an identifier before '" .. sfail .. "'"
15 elseif e == 2 then 15 elseif e == 2 then
16 return r, "Error: expecting ','" 16 return r, "Error: expecting ',' before '" .. sfail .. "'"
17 else 17 else
18 return r, "Error" 18 return r, "Error"
19 end 19 end
diff --git a/lptree.c b/lptree.c
index cbdd4df..ee76af7 100644
--- a/lptree.c
+++ b/lptree.c
@@ -1198,10 +1198,12 @@ static int lp_match (lua_State *L) {
1198 size_t i = initposition(L, l); 1198 size_t i = initposition(L, l);
1199 int ptop = lua_gettop(L); 1199 int ptop = lua_gettop(L);
1200 Labelset labelf; /* labeled failure */ 1200 Labelset labelf; /* labeled failure */
1201 const char *sfail = NULL; /* labeled failure */
1201 lua_pushnil(L); /* initialize subscache */ 1202 lua_pushnil(L); /* initialize subscache */
1202 lua_pushlightuserdata(L, capture); /* initialize caplistidx */ 1203 lua_pushlightuserdata(L, capture); /* initialize caplistidx */
1203 lua_getfenv(L, 1); /* initialize penvidx */ 1204 lua_getfenv(L, 1); /* initialize penvidx */
1204 r = match(L, s, s + i, s + l, code, capture, ptop, &labelf); /* labeled failure */ 1205 r = match(L, s, s + i, s + l, code, capture, ptop, &labelf, &sfail); /* labeled failure */
1206 /*printf("sfail = %s\n", sfail);*/
1205 if (r == NULL) { /* labeled failure begin */ 1207 if (r == NULL) { /* labeled failure begin */
1206 int j = 0; 1208 int j = 0;
1207 int n = 1; 1209 int n = 1;
@@ -1210,10 +1212,12 @@ static int lp_match (lua_State *L) {
1210 if (labelf & (1 << j)) { 1212 if (labelf & (1 << j)) {
1211 lua_pushinteger(L, j); 1213 lua_pushinteger(L, j);
1212 n++; 1214 n++;
1215 break; /* Changing the semantics: only one label */
1213 } 1216 }
1214 j++; 1217 j++;
1215 } 1218 }
1216 return n; 1219 lua_pushstring(L, sfail); /* Pushing the subject where the failure occurred */
1220 return n + 1;
1217 } /* labeled failure end */ 1221 } /* labeled failure end */
1218 return getcaptures(L, s, r, ptop); 1222 return getcaptures(L, s, r, ptop);
1219} 1223}
diff --git a/lpvm.c b/lpvm.c
index a9198ba..3ae22f5 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -146,7 +146,7 @@ static int removedyncap (lua_State *L, Capture *capture,
146** Opcode interpreter 146** Opcode interpreter
147*/ 147*/
148const char *match (lua_State *L, const char *o, const char *s, const char *e, 148const char *match (lua_State *L, const char *o, const char *s, const char *e,
149 Instruction *op, Capture *capture, int ptop, Labelset *labelf) { /* labeled failure */ 149 Instruction *op, Capture *capture, int ptop, Labelset *labelf, const char **sfail) { /* labeled failure */
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 */
@@ -184,6 +184,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
184 if (s < e) { p++; s++; } 184 if (s < e) { p++; s++; }
185 else { 185 else {
186 *labelf = LFAIL; /* labeled failure */ 186 *labelf = LFAIL; /* labeled failure */
187 *sfail = s;
187 goto fail; 188 goto fail;
188 } 189 }
189 continue; 190 continue;
@@ -197,6 +198,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
197 if ((byte)*s == p->i.aux && s < e) { p++; s++; } 198 if ((byte)*s == p->i.aux && s < e) { p++; s++; }
198 else { 199 else {
199 *labelf = LFAIL; /* labeled failure */ 200 *labelf = LFAIL; /* labeled failure */
201 *sfail = s;
200 goto fail; 202 goto fail;
201 } 203 }
202 continue; 204 continue;
@@ -212,6 +214,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
212 { p += CHARSETINSTSIZE; s++; } 214 { p += CHARSETINSTSIZE; s++; }
213 else { 215 else {
214 *labelf = LFAIL; /* labeled failure */ 216 *labelf = LFAIL; /* labeled failure */
217 *sfail = s;
215 goto fail; 218 goto fail;
216 } 219 }
217 continue; 220 continue;
@@ -227,6 +230,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
227 int n = p->i.aux; 230 int n = p->i.aux;
228 if (n > s - o) { 231 if (n > s - o) {
229 *labelf = LFAIL; /* labeled failure */ 232 *labelf = LFAIL; /* labeled failure */
233 *sfail = s;
230 goto fail; 234 goto fail;
231 } 235 }
232 s -= n; p++; 236 s -= n; p++;
@@ -297,6 +301,8 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
297 } 301 }
298 case IThrow: { /* labeled failure */ 302 case IThrow: { /* labeled failure */
299 *labelf = (p+1)->labels; 303 *labelf = (p+1)->labels;
304 *sfail = s;
305 /*printf("s = %s, sfail = %s\n", s, *sfail);*/
300 goto fail; 306 goto fail;
301 } 307 }
302 case IFailTwice: 308 case IFailTwice:
@@ -305,6 +311,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
305 /* go through */ 311 /* go through */
306 case IFail: 312 case IFail:
307 *labelf = LFAIL; /* labeled failure */ 313 *labelf = LFAIL; /* labeled failure */
314 *sfail = s;
308 fail: { /* pattern failed: try to backtrack */ 315 fail: { /* pattern failed: try to backtrack */
309 do { /* remove pending calls */ 316 do { /* remove pending calls */
310 assert(stack > getstackbase(L, ptop)); 317 assert(stack > getstackbase(L, ptop));
@@ -327,6 +334,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
327 res = resdyncaptures(L, fr, s - o, e - o); /* get result */ 334 res = resdyncaptures(L, fr, s - o, e - o); /* get result */
328 if (res == -1) { /* fail? */ 335 if (res == -1) { /* fail? */
329 *labelf = LFAIL; /* labeled failure */ 336 *labelf = LFAIL; /* labeled failure */
337 *sfail = (const char *) s; /* TODO: ??? */
330 goto fail; 338 goto fail;
331 } 339 }
332 s = o + res; /* else update current position */ 340 s = o + res; /* else update current position */
diff --git a/lpvm.h b/lpvm.h
index c996e22..cec9f5a 100644
--- a/lpvm.h
+++ b/lpvm.h
@@ -54,7 +54,7 @@ typedef union Instruction {
54 54
55void printpatt (Instruction *p, int n); 55void printpatt (Instruction *p, int n);
56const char *match (lua_State *L, const char *o, const char *s, const char *e, 56const char *match (lua_State *L, const char *o, const char *s, const char *e,
57 Instruction *op, Capture *capture, int ptop, Labelset *labelf); /* labeled failure */ 57 Instruction *op, Capture *capture, int ptop, Labelset *labelf, const char **sfail); /* labeled failure */
58 58
59 59
60#endif 60#endif