diff options
author | Sergio Queiroz <sqmedeiros@gmail.com> | 2015-09-11 15:01:10 -0300 |
---|---|---|
committer | Sergio Queiroz <sqmedeiros@gmail.com> | 2015-09-11 15:01:10 -0300 |
commit | 8ac31b94b88227222b189c447aeea1b4131eed18 (patch) | |
tree | 8a913ad00c03d15cd2cb5bcedd10ddba65b01e3b | |
parent | ce9f1486d1d11699e8099d13c6f65fabe372385d (diff) | |
download | lpeglabel-8ac31b94b88227222b189c447aeea1b4131eed18.tar.gz lpeglabel-8ac31b94b88227222b189c447aeea1b4131eed18.tar.bz2 lpeglabel-8ac31b94b88227222b189c447aeea1b4131eed18.zip |
Result of an unsuccessful matching is label + subject
-rw-r--r-- | examples/listId1.lua | 6 | ||||
-rw-r--r-- | lptree.c | 8 | ||||
-rw-r--r-- | lpvm.c | 10 | ||||
-rw-r--r-- | lpvm.h | 2 |
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 | ||
10 | function mymatch (g, s) | 10 | function 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 |
@@ -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 | } |
@@ -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, 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 */ |
@@ -54,7 +54,7 @@ typedef union Instruction { | |||
54 | 54 | ||
55 | void printpatt (Instruction *p, int n); | 55 | void printpatt (Instruction *p, int n); |
56 | const char *match (lua_State *L, const char *o, const char *s, const char *e, | 56 | const 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 |