aboutsummaryrefslogtreecommitdiff
path: root/lpcode.c
diff options
context:
space:
mode:
authorSergio Queiroz <sqmedeiros@gmail.com>2017-07-06 11:21:56 -0300
committerSergio Queiroz <sqmedeiros@gmail.com>2017-07-06 11:21:56 -0300
commit8ee42c29131e1c7de48575d6d8a9b24ea6977cbd (patch)
tree4267e0cf0609a909be1f2eaea17d11b0efc12c98 /lpcode.c
parentaad9b29e755d67d6cb4e4b861111df0d173819ce (diff)
downloadlpeglabel-8ee42c29131e1c7de48575d6d8a9b24ea6977cbd.tar.gz
lpeglabel-8ee42c29131e1c7de48575d6d8a9b24ea6977cbd.tar.bz2
lpeglabel-8ee42c29131e1c7de48575d6d8a9b24ea6977cbd.zip
Updating lpeglabel to the codebase of LPeg 1.0.1
Diffstat (limited to 'lpcode.c')
-rw-r--r--lpcode.c87
1 files changed, 58 insertions, 29 deletions
diff --git a/lpcode.c b/lpcode.c
index b2dbba2..a5cf2e2 100644
--- a/lpcode.c
+++ b/lpcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lpcode.c,v 1.23 2015/06/12 18:36:47 roberto Exp $ 2** $Id: lpcode.c,v 1.24 2016/09/15 17:46:13 roberto Exp $
3** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) 3** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license)
4*/ 4*/
5 5
@@ -126,6 +126,27 @@ int tocharset (TTree *tree, Charset *cs) {
126 126
127 127
128/* 128/*
129** Visit a TCall node taking care to stop recursion. If node not yet
130** visited, return 'f(sib2(tree))', otherwise return 'def' (default
131** value)
132*/
133static int callrecursive (TTree *tree, int f (TTree *t), int def) {
134 int key = tree->key;
135 assert(tree->tag == TCall);
136 assert(sib2(tree)->tag == TRule);
137 if (key == 0) /* node already visited? */
138 return def; /* return default value */
139 else { /* first visit */
140 int result;
141 tree->key = 0; /* mark call as already visited */
142 result = f(sib2(tree)); /* go to called rule */
143 tree->key = key; /* restore tree */
144 return result;
145 }
146}
147
148
149/*
129** Check whether a pattern tree has captures 150** Check whether a pattern tree has captures
130*/ 151*/
131int hascaptures (TTree *tree) { 152int hascaptures (TTree *tree) {
@@ -134,14 +155,17 @@ int hascaptures (TTree *tree) {
134 case TCapture: case TRunTime: 155 case TCapture: case TRunTime:
135 return 1; 156 return 1;
136 case TCall: 157 case TCall:
137 tree = sib2(tree); goto tailcall; /* return hascaptures(sib2(tree)); */ 158 return callrecursive(tree, hascaptures, 0);
159 case TRule: /* do not follow siblings */
160 tree = sib1(tree); goto tailcall;
138 case TOpenCall: assert(0); 161 case TOpenCall: assert(0);
139 default: { 162 default: {
140 switch (numsiblings[tree->tag]) { 163 switch (numsiblings[tree->tag]) {
141 case 1: /* return hascaptures(sib1(tree)); */ 164 case 1: /* return hascaptures(sib1(tree)); */
142 tree = sib1(tree); goto tailcall; 165 tree = sib1(tree); goto tailcall;
143 case 2: 166 case 2:
144 if (hascaptures(sib1(tree))) return 1; 167 if (hascaptures(sib1(tree)))
168 return 1;
145 /* else return hascaptures(sib2(tree)); */ 169 /* else return hascaptures(sib2(tree)); */
146 tree = sib2(tree); goto tailcall; 170 tree = sib2(tree); goto tailcall;
147 default: assert(numsiblings[tree->tag] == 0); return 0; 171 default: assert(numsiblings[tree->tag] == 0); return 0;
@@ -211,39 +235,42 @@ int checkaux (TTree *tree, int pred) {
211 235
212/* 236/*
213** number of characters to match a pattern (or -1 if variable) 237** number of characters to match a pattern (or -1 if variable)
214** ('count' avoids infinite loops for grammars)
215*/ 238*/
216int fixedlenx (TTree *tree, int count, int len) { 239int fixedlen (TTree *tree) {
240 int len = 0; /* to accumulate in tail calls */
217 tailcall: 241 tailcall:
218 switch (tree->tag) { 242 switch (tree->tag) {
219 case TChar: case TSet: case TAny: 243 case TChar: case TSet: case TAny:
220 return len + 1; 244 return len + 1;
221 case TFalse: case TTrue: case TNot: case TAnd: case TBehind: 245 case TFalse: case TTrue: case TNot: case TAnd: case TBehind:
222 return len; 246 return len;
223 case TRep: case TRunTime: case TOpenCall: 247 case TRep: case TRunTime: case TOpenCall:
224 case TThrow: /* labeled failure */ 248 case TThrow: /* labeled failure */
225 return -1; 249 return -1;
226 case TCapture: case TRule: case TGrammar: 250 case TCapture: case TRule: case TGrammar:
227 /* return fixedlenx(sib1(tree), count); */ 251 /* return fixedlen(sib1(tree)); */
228 tree = sib1(tree); goto tailcall; 252 tree = sib1(tree); goto tailcall;
229 case TCall: 253 case TCall: {
230 if (count++ >= MAXRULES) 254 int n1 = callrecursive(tree, fixedlen, -1);
231 return -1; /* may be a loop */ 255 if (n1 < 0)
232 /* else return fixedlenx(sib2(tree), count); */ 256 return -1;
233 tree = sib2(tree); goto tailcall; 257 else
258 return len + n1;
259 }
234 case TSeq: case TRecov: { /* labeled failure */ 260 case TSeq: case TRecov: { /* labeled failure */
235 len = fixedlenx(sib1(tree), count, len); 261 int n1 = fixedlen(sib1(tree));
236 if (len < 0) return -1; 262 if (n1 < 0)
237 /* else return fixedlenx(sib2(tree), count, len); */ 263 return -1;
238 tree = sib2(tree); goto tailcall; 264 /* else return fixedlen(sib2(tree)) + len; */
265 len += n1; tree = sib2(tree); goto tailcall;
239 } 266 }
240 case TChoice: { 267 case TChoice: {
241 int n1, n2; 268 int n1 = fixedlen(sib1(tree));
242 n1 = fixedlenx(sib1(tree), count, len); 269 int n2 = fixedlen(sib2(tree));
243 if (n1 < 0) return -1; 270 if (n1 != n2 || n1 < 0)
244 n2 = fixedlenx(sib2(tree), count, len); 271 return -1;
245 if (n1 == n2) return n1; 272 else
246 else return -1; 273 return len + n1;
247 } 274 }
248 default: assert(0); return 0; 275 default: assert(0); return 0;
249 }; 276 };
@@ -287,7 +314,7 @@ static int getfirst (TTree *tree, const Charset *follow, Charset *firstset) {
287 loopset(i, firstset->cs[i] = follow->cs[i]); /* follow = fullset(?) */ 314 loopset(i, firstset->cs[i] = follow->cs[i]); /* follow = fullset(?) */
288 return 1; 315 return 1;
289 } 316 }
290 case TChoice: { 317 case TChoice: {
291 Charset csaux; 318 Charset csaux;
292 int e1 = getfirst(sib1(tree), follow, firstset); 319 int e1 = getfirst(sib1(tree), follow, firstset);
293 int e2 = getfirst(sib2(tree), follow, &csaux); 320 int e2 = getfirst(sib2(tree), follow, &csaux);
@@ -378,7 +405,7 @@ static int headfail (TTree *tree) {
378 if (!nofail(sib2(tree))) return 0; 405 if (!nofail(sib2(tree))) return 0;
379 /* else return headfail(sib1(tree)); */ 406 /* else return headfail(sib1(tree)); */
380 tree = sib1(tree); goto tailcall; 407 tree = sib1(tree); goto tailcall;
381 case TChoice: case TRecov: /* labeled failure */ 408 case TChoice: case TRecov: /* labeled failure */
382 if (!headfail(sib1(tree))) return 0; 409 if (!headfail(sib1(tree))) return 0;
383 /* else return headfail(sib2(tree)); */ 410 /* else return headfail(sib2(tree)); */
384 tree = sib2(tree); goto tailcall; 411 tree = sib2(tree); goto tailcall;
@@ -433,8 +460,9 @@ int sizei (const Instruction *i) {
433 return 2; 460 return 2;
434 case IThrow: /* labeled failure */ 461 case IThrow: /* labeled failure */
435 return 1; 462 return 1;
436 case IRecov: 463 case IRecov:
437 return (CHARSETINSTSIZE - 1) + 2; /* labeled failure */ 464 return (CHARSETINSTSIZE - 1) + 2; /* labeled failure */
465
438 default: return 1; 466 default: return 1;
439 } 467 }
440} 468}
@@ -750,9 +778,10 @@ static void codeand (CompileState *compst, TTree *tree, int tt) {
750 778
751 779
752/* 780/*
753** Captures: if pattern has fixed (and not too big) length, use 781** Captures: if pattern has fixed (and not too big) length, and it
754** a single IFullCapture instruction after the match; otherwise, 782** has no nested captures, use a single IFullCapture instruction
755** enclose the pattern with OpenCapture - CloseCapture. 783** after the match; otherwise, enclose the pattern with OpenCapture -
784** CloseCapture.
756*/ 785*/
757static void codecapture (CompileState *compst, TTree *tree, int tt, 786static void codecapture (CompileState *compst, TTree *tree, int tt,
758 const Charset *fl) { 787 const Charset *fl) {