aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergio Queiroz <sqmedeiros@gmail.com>2017-07-06 16:01:44 -0300
committerSergio Queiroz <sqmedeiros@gmail.com>2017-07-06 16:01:44 -0300
commite2a8e1c789a7a769c83a66d6fd2f191b0e465cba (patch)
treee2aecc3d439e44db98439c26cf23625da1bedb3f
parenta36fe71ac0271d9013f76d9342f9a2fca40f64fc (diff)
downloadlpeglabel-e2a8e1c789a7a769c83a66d6fd2f191b0e465cba.tar.gz
lpeglabel-e2a8e1c789a7a769c83a66d6fd2f191b0e465cba.tar.bz2
lpeglabel-e2a8e1c789a7a769c83a66d6fd2f191b0e465cba.zip
Reintroducing the labeled ordered choice (tests without it passed)
-rw-r--r--lpcode.c35
-rw-r--r--lpprint.c8
-rw-r--r--lptree.c35
-rw-r--r--lptree.h4
-rw-r--r--lpvm.c11
-rw-r--r--lpvm.h3
-rw-r--r--relabel.lua30
7 files changed, 95 insertions, 31 deletions
diff --git a/lpcode.c b/lpcode.c
index a5cf2e2..f335dcb 100644
--- a/lpcode.c
+++ b/lpcode.c
@@ -220,7 +220,7 @@ int checkaux (TTree *tree, int pred) {
220 if (checkaux(sib2(tree), pred)) return 1; 220 if (checkaux(sib2(tree), pred)) return 1;
221 /* else return checkaux(sib1(tree), pred); */ 221 /* else return checkaux(sib1(tree), pred); */
222 tree = sib1(tree); goto tailcall; 222 tree = sib1(tree); goto tailcall;
223 case TRecov: /* labeled failure */ 223 case TRecov: case TLabChoice: /* labeled failure */
224 /* we do not know whether sib2 will be evaluated */ 224 /* we do not know whether sib2 will be evaluated */
225 tree = sib1(tree); goto tailcall; 225 tree = sib1(tree); goto tailcall;
226 case TCapture: case TGrammar: case TRule: 226 case TCapture: case TGrammar: case TRule:
@@ -264,7 +264,7 @@ int fixedlen (TTree *tree) {
264 /* else return fixedlen(sib2(tree)) + len; */ 264 /* else return fixedlen(sib2(tree)) + len; */
265 len += n1; tree = sib2(tree); goto tailcall; 265 len += n1; tree = sib2(tree); goto tailcall;
266 } 266 }
267 case TChoice: { 267 case TChoice: case TLabChoice: { /* labeled failure */
268 int n1 = fixedlen(sib1(tree)); 268 int n1 = fixedlen(sib1(tree));
269 int n2 = fixedlen(sib2(tree)); 269 int n2 = fixedlen(sib2(tree));
270 if (n1 != n2 || n1 < 0) 270 if (n1 != n2 || n1 < 0)
@@ -314,7 +314,7 @@ static int getfirst (TTree *tree, const Charset *follow, Charset *firstset) {
314 loopset(i, firstset->cs[i] = follow->cs[i]); /* follow = fullset(?) */ 314 loopset(i, firstset->cs[i] = follow->cs[i]); /* follow = fullset(?) */
315 return 1; 315 return 1;
316 } 316 }
317 case TChoice: { 317 case TChoice: case TLabChoice: { /*(?) labeled failure */
318 Charset csaux; 318 Charset csaux;
319 int e1 = getfirst(sib1(tree), follow, firstset); 319 int e1 = getfirst(sib1(tree), follow, firstset);
320 int e2 = getfirst(sib2(tree), follow, &csaux); 320 int e2 = getfirst(sib2(tree), follow, &csaux);
@@ -405,7 +405,7 @@ static int headfail (TTree *tree) {
405 if (!nofail(sib2(tree))) return 0; 405 if (!nofail(sib2(tree))) return 0;
406 /* else return headfail(sib1(tree)); */ 406 /* else return headfail(sib1(tree)); */
407 tree = sib1(tree); goto tailcall; 407 tree = sib1(tree); goto tailcall;
408 case TChoice: case TRecov: /* labeled failure */ 408 case TChoice: case TRecov: case TLabChoice: /* labeled failure */
409 if (!headfail(sib1(tree))) return 0; 409 if (!headfail(sib1(tree))) return 0;
410 /* else return headfail(sib2(tree)); */ 410 /* else return headfail(sib2(tree)); */
411 tree = sib2(tree); goto tailcall; 411 tree = sib2(tree); goto tailcall;
@@ -425,7 +425,7 @@ static int needfollow (TTree *tree) {
425 case TChar: case TSet: case TAny: 425 case TChar: case TSet: case TAny:
426 case TFalse: case TTrue: case TAnd: case TNot: 426 case TFalse: case TTrue: case TAnd: case TNot:
427 case TRunTime: case TGrammar: case TCall: case TBehind: 427 case TRunTime: case TGrammar: case TCall: case TBehind:
428 case TThrow: case TRecov: /* (?)labeled failure */ 428 case TThrow: case TRecov: case TLabChoice: /* (?)labeled failure */
429 return 0; 429 return 0;
430 case TChoice: case TRep: 430 case TChoice: case TRep:
431 return 1; 431 return 1;
@@ -460,7 +460,7 @@ int sizei (const Instruction *i) {
460 return 2; 460 return 2;
461 case IThrow: /* labeled failure */ 461 case IThrow: /* labeled failure */
462 return 1; 462 return 1;
463 case IRecov: 463 case IRecov: case ILabChoice:
464 return (CHARSETINSTSIZE - 1) + 2; /* labeled failure */ 464 return (CHARSETINSTSIZE - 1) + 2; /* labeled failure */
465 465
466 default: return 1; 466 default: return 1;
@@ -527,7 +527,7 @@ static int addoffsetinst (CompileState *compst, Opcode op) {
527 int i = addinstruction(compst, op, 0); /* instruction */ 527 int i = addinstruction(compst, op, 0); /* instruction */
528 addinstruction(compst, (Opcode)0, 0); /* open space for offset */ 528 addinstruction(compst, (Opcode)0, 0); /* open space for offset */
529 assert(op == ITestSet || sizei(&getinstr(compst, i)) == 2 || 529 assert(op == ITestSet || sizei(&getinstr(compst, i)) == 2 ||
530 op == IRecov); /* labeled failure */ 530 op == IRecov || op == ILabChoice); /* labeled failure */
531 return i; 531 return i;
532} 532}
533 533
@@ -750,6 +750,21 @@ static void coderecovery (CompileState *compst, TTree *p1, TTree *p2, int opt,
750 addinstruction(compst, IRet, 0); 750 addinstruction(compst, IRet, 0);
751 jumptohere(compst, pcommit); 751 jumptohere(compst, pcommit);
752} 752}
753
754static void codelabchoice (CompileState *compst, TTree *p1, TTree *p2, int opt,
755 const Charset *fl, const byte *cs) {
756 int emptyp2 = (p2->tag == TTrue);
757 int pcommit;
758 int test = NOINST;
759 int pchoice = addoffsetinst(compst, ILabChoice);
760 addcharset(compst, cs);
761 codegen(compst, p1, emptyp2, test, fullset);
762 pcommit = addoffsetinst(compst, ICommit);
763 jumptohere(compst, pchoice);
764 jumptohere(compst, test);
765 codegen(compst, p2, opt, NOINST, fl);
766 jumptohere(compst, pcommit);
767}
753/* labeled failure end */ 768/* labeled failure end */
754 769
755 770
@@ -988,6 +1003,10 @@ static void codegen (CompileState *compst, TTree *tree, int opt, int tt,
988 coderecovery(compst, sib1(tree), sib2(tree), opt, fl, treelabelset(tree)); 1003 coderecovery(compst, sib1(tree), sib2(tree), opt, fl, treelabelset(tree));
989 break; 1004 break;
990 } 1005 }
1006 case TLabChoice: { /* labeled failure */
1007 codelabchoice(compst, sib1(tree), sib2(tree), opt, fl, treelabelset(tree));
1008 break;
1009 }
991 default: assert(0); 1010 default: assert(0);
992 } 1011 }
993} 1012}
@@ -1010,7 +1029,7 @@ static void peephole (CompileState *compst) {
1010 switch (code[i].i.code) { 1029 switch (code[i].i.code) {
1011 case IChoice: case ICall: case ICommit: case IPartialCommit: 1030 case IChoice: case ICall: case ICommit: case IPartialCommit:
1012 case IBackCommit: case ITestChar: case ITestSet: 1031 case IBackCommit: case ITestChar: case ITestSet:
1013 case IRecov: /* labeled failure */ 1032 case IRecov: case ILabChoice: /* labeled failure */
1014 case ITestAny: { /* instructions with labels */ 1033 case ITestAny: { /* instructions with labels */
1015 jumptothere(compst, i, finallabel(code, i)); /* optimize label */ 1034 jumptothere(compst, i, finallabel(code, i)); /* optimize label */
1016 break; 1035 break;
diff --git a/lpprint.c b/lpprint.c
index ecaa7f1..342a2b6 100644
--- a/lpprint.c
+++ b/lpprint.c
@@ -61,7 +61,7 @@ void printinst (const Instruction *op, const Instruction *p) {
61 "choice", "jmp", "call", "open_call", 61 "choice", "jmp", "call", "open_call",
62 "commit", "partial_commit", "back_commit", "failtwice", "fail", "giveup", 62 "commit", "partial_commit", "back_commit", "failtwice", "fail", "giveup",
63 "fullcapture", "opencapture", "closecapture", "closeruntime", 63 "fullcapture", "opencapture", "closecapture", "closeruntime",
64 "throw", "recovery" /* labeled failure */ 64 "throw", "recovery", "labeled_choice" /* labeled failure */
65 }; 65 };
66 printf("%02ld: %s ", (long)(p - op), names[p->i.code]); 66 printf("%02ld: %s ", (long)(p - op), names[p->i.code]);
67 switch ((Opcode)p->i.code) { 67 switch ((Opcode)p->i.code) {
@@ -111,7 +111,7 @@ void printinst (const Instruction *op, const Instruction *p) {
111 printf("%d", p->i.aux); 111 printf("%d", p->i.aux);
112 break; 112 break;
113 } 113 }
114 case IRecov: { /* labeled failure */ 114 case IRecov: case ILabChoice: { /* labeled failure */
115 printjmp(op, p); 115 printjmp(op, p);
116 printcharset((p+2)->buff); 116 printcharset((p+2)->buff);
117 break; 117 break;
@@ -164,7 +164,7 @@ static const char *tagnames[] = {
164 "call", "opencall", "rule", "grammar", 164 "call", "opencall", "rule", "grammar",
165 "behind", 165 "behind",
166 "capture", "run-time", 166 "capture", "run-time",
167 "throw", "labeled-choice", "recov" /* labeled failure */ 167 "throw", "recov", "labeled-choice" /* labeled failure */
168}; 168};
169 169
170 170
@@ -223,7 +223,7 @@ void printtree (TTree *tree, int ident) {
223 default: { 223 default: {
224 int sibs = numsiblings[tree->tag]; 224 int sibs = numsiblings[tree->tag];
225 printf("\n"); 225 printf("\n");
226 if (tree->tag == TRecov) { /* labeled failure */ 226 if (tree->tag == TRecov || tree->tag == TLabChoice) { /* labeled failure */
227 printcharset(treelabelset(tree)); 227 printcharset(treelabelset(tree));
228 printf("\n"); 228 printf("\n");
229 } 229 }
diff --git a/lptree.c b/lptree.c
index fcf5ff9..19d6b1a 100644
--- a/lptree.c
+++ b/lptree.c
@@ -28,7 +28,7 @@ const byte numsiblings[] = {
28 0, 0, 2, 1, /* call, opencall, rule, grammar */ 28 0, 0, 2, 1, /* call, opencall, rule, grammar */
29 1, /* behind */ 29 1, /* behind */
30 1, 1, /* capture, runtime capture */ 30 1, 1, /* capture, runtime capture */
31 0, 2 /* labeled failure throw, recovery */ 31 0, 2, 2 /* labeled failure throw, recovery, labeled choice */
32}; 32};
33 33
34 34
@@ -734,16 +734,28 @@ static int lp_throw (lua_State *L) {
734static int lp_recovery (lua_State *L) { 734static int lp_recovery (lua_State *L) {
735 int n = lua_gettop(L); 735 int n = lua_gettop(L);
736 TTree *tree = newrootlab2sib(L, TRecov); 736 TTree *tree = newrootlab2sib(L, TRecov);
737 int i;
737 luaL_argcheck(L, n >= 3, 3, "non-nil value expected"); 738 luaL_argcheck(L, n >= 3, 3, "non-nil value expected");
738 if (n == 2) { /* catches fail as default */ 739 for (i = 3; i <= n; i++) {
739 /*setlabel(treelabelset(tree), LFAIL); recovery does not catch regular fail */ 740 int d = luaL_checkinteger(L, i);
740 } else { 741 luaL_argcheck(L, d >= 1 && d < MAXLABELS, i, "the number of a label must be between 1 and 255");
741 int i; 742 setlabel(treelabelset(tree), (byte)d);
742 for (i = 3; i <= n; i++) { 743 }
743 int d = luaL_checkinteger(L, i); 744 return 1;
744 luaL_argcheck(L, d >= 1 && d < MAXLABELS, i, "the number of a label must be between 1 and 255"); 745}
745 setlabel(treelabelset(tree), (byte)d); 746
746 } 747
748/*
749** labeled choice function
750*/
751static int lp_labchoice (lua_State *L) {
752 int n = lua_gettop(L);
753 TTree *tree = newrootlab2sib(L, TLabChoice);
754 int i;
755 for (i = 3; i <= n; i++) {
756 int d = luaL_checkinteger(L, i);
757 luaL_argcheck(L, d >= 1 && d < MAXLABELS, i, "the number of a label must be between 1 and 255");
758 setlabel(treelabelset(tree), (byte)d);
747 } 759 }
748 return 1; 760 return 1;
749} 761}
@@ -1083,7 +1095,7 @@ static int verifyrule (lua_State *L, TTree *tree, int *passed, int npassed,
1083 return nb; 1095 return nb;
1084 /* else return verifyrule(L, sib2(tree), passed, npassed, nb); */ 1096 /* else return verifyrule(L, sib2(tree), passed, npassed, nb); */
1085 tree = sib2(tree); goto tailcall; 1097 tree = sib2(tree); goto tailcall;
1086 case TChoice: case TRecov: /* must check both children */ /* labeled failure */ 1098 case TChoice: case TRecov: case TLabChoice: /* must check both children */ /* labeled failure */
1087 nb = verifyrule(L, sib1(tree), passed, npassed, nb); 1099 nb = verifyrule(L, sib1(tree), passed, npassed, nb);
1088 /* return verifyrule(L, sib2(tree), passed, npassed, nb); */ 1100 /* return verifyrule(L, sib2(tree), passed, npassed, nb); */
1089 tree = sib2(tree); goto tailcall; 1101 tree = sib2(tree); goto tailcall;
@@ -1337,6 +1349,7 @@ static struct luaL_Reg pattreg[] = {
1337 {"type", lp_type}, 1349 {"type", lp_type},
1338 {"T", lp_throw}, /* labeled failure throw */ 1350 {"T", lp_throw}, /* labeled failure throw */
1339 {"Rec", lp_recovery}, /* labeled failure recovery */ 1351 {"Rec", lp_recovery}, /* labeled failure recovery */
1352 {"Lc", lp_labchoice}, /* labeled failure choice */
1340 {NULL, NULL} 1353 {NULL, NULL}
1341}; 1354};
1342 1355
diff --git a/lptree.h b/lptree.h
index e4e8901..d89da4d 100644
--- a/lptree.h
+++ b/lptree.h
@@ -36,7 +36,9 @@ typedef enum TTag {
36 TRunTime, /* run-time capture: 'key' is Lua function; 36 TRunTime, /* run-time capture: 'key' is Lua function;
37 'sib1' is capture body */ 37 'sib1' is capture body */
38 TThrow, /* labeled failure: 'label' = l */ 38 TThrow, /* labeled failure: 'label' = l */
39 TRecov /* labed failure: 'sib1' // 'sib2' */ 39 TRecov, /* labed failure: 'sib1' //{labels} 'sib2' */
40 /* the set of labels is stored in next CHARSETSIZE bytes */
41 TLabChoice /* labed failure: 'sib1' /{labels} 'sib2' */
40 /* the set of labels is stored in next CHARSETSIZE bytes */ 42 /* the set of labels is stored in next CHARSETSIZE bytes */
41} TTag; 43} TTag;
42 44
diff --git a/lpvm.c b/lpvm.c
index 911b4c5..d2b1f55 100644
--- a/lpvm.c
+++ b/lpvm.c
@@ -277,6 +277,17 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
277 p += 2; 277 p += 2;
278 continue; 278 continue;
279 } 279 }
280 case ILabChoice: { /* labeled failure */
281 if (stack == stacklimit)
282 stack = doublestack(L, &stacklimit, ptop);
283 stack->p = p + getoffset(p);
284 stack->s = s;
285 stack->ls = (const Labelset *) ((p + 2)->buff);
286 stack->caplevel = captop;
287 stack++;
288 p += (CHARSETINSTSIZE - 1) + 2;
289 continue;
290 }
280 case IRecov: { /* labeled failure */ 291 case IRecov: { /* labeled failure */
281 if (stack == stacklimit) 292 if (stack == stacklimit)
282 stack = doublestack(L, &stacklimit, ptop); 293 stack = doublestack(L, &stacklimit, ptop);
diff --git a/lpvm.h b/lpvm.h
index bcfc22f..713626e 100644
--- a/lpvm.h
+++ b/lpvm.h
@@ -35,7 +35,8 @@ typedef enum Opcode {
35 ICloseCapture, 35 ICloseCapture,
36 ICloseRunTime, 36 ICloseRunTime,
37 IThrow, /* "fails" with a specific label labeled failure */ 37 IThrow, /* "fails" with a specific label labeled failure */
38 IRecov /* stack a recovery; next fail with label 'f' will jump to 'offset' */ 38 IRecov, /* stack a recovery; next fail with label 'f' will jump to 'offset' */
39 ILabChoice /* stack a choice; next fail with label 'f' will jump to 'offset' */
39} Opcode; 40} Opcode;
40 41
41 42
diff --git a/relabel.lua b/relabel.lua
index b02c95d..cfe5f2e 100644
--- a/relabel.lua
+++ b/relabel.lua
@@ -31,7 +31,7 @@ local errinfo = {
31 {"NoPatt", "no pattern found"}, 31 {"NoPatt", "no pattern found"},
32 {"ExtraChars", "unexpected characters after the pattern"}, 32 {"ExtraChars", "unexpected characters after the pattern"},
33 33
34 {"ExpPatt1", "expected a pattern after '/' or '//{...}'"}, 34 {"ExpPatt1", "expected a pattern after '/' and '//{...}', or the label(s) after '/{' and '//{'"},
35 35
36 {"ExpPatt2", "expected a pattern after '&'"}, 36 {"ExpPatt2", "expected a pattern after '&'"},
37 {"ExpPatt3", "expected a pattern after '!'"}, 37 {"ExpPatt3", "expected a pattern after '!'"},
@@ -221,10 +221,28 @@ local function choicerec (...)
221 local n = #t 221 local n = #t
222 local p = t[1] 222 local p = t[1]
223 local i = 2 223 local i = 2
224 while i + 1 <= n do 224 --print("eu")
225 -- t[i] == false when there are no labels 225 --for i, v in ipairs(t) do
226 p = t[i] and mm.Rec(p, t[i+1], unpack(t[i])) or mt.__add(p, t[i+1]) 226 -- print(i, v)
227 i = i + 2 227 --end
228 --print"fim"
229
230 while i + 2 <= n do
231 -- t[i] is '/' or '//'
232 -- t[i+1] == false when there are no labels
233 -- t[i+2] is a pattern
234 if t[i] == '/' then
235 if not t[i+1] then
236 p = mt.__add(p, t[i+2])
237 --print("foi aqui", t[i], t[i+1], t[i+2])
238 --p:pcode()
239 else
240 p = mm.Lc(p, t[i+2], unpack(t[i+1]))
241 end
242 else -- t[i] is '//'
243 p = mm.Rec(p, t[i+2], unpack(t[i+1]))
244 end
245 i = i + 3
228 end 246 end
229 247
230 return p 248 return p
@@ -232,7 +250,7 @@ end
232 250
233local exp = m.P{ "Exp", 251local exp = m.P{ "Exp",
234 Exp = S * ( m.V"Grammar" 252 Exp = S * ( m.V"Grammar"
235 + (m.V"Seq" * (S * (("//" * m.Ct(m.V"Labels")) + ("/" * m.Cc(false))) 253 + (m.V"Seq" * (S * ((m.C(m.P"//" + "/") * m.Ct(m.V"Labels")) + (m.C"/" * m.Cc(false)))
236 * expect(S * m.V"Seq", "ExpPatt1") 254 * expect(S * m.V"Seq", "ExpPatt1")
237 )^0 255 )^0
238 ) / choicerec); 256 ) / choicerec);