diff options
author | Sergio Queiroz <sqmedeiros@gmail.com> | 2019-01-10 10:06:33 -0300 |
---|---|---|
committer | Sergio Queiroz <sqmedeiros@gmail.com> | 2019-01-10 10:06:33 -0300 |
commit | 4fb816d55f47c48c34cc4478e584b1567a75863b (patch) | |
tree | 54ec6965c9d3983b193cf000a521a06cb3d73b8a /lpcode.c | |
parent | 9be59fb8f4b176a16643e707c74051b243202296 (diff) | |
download | lpeglabel-lpeg-1.0.0.tar.gz lpeglabel-lpeg-1.0.0.tar.bz2 lpeglabel-lpeg-1.0.0.zip |
Adapting lpeglabel-1.5 to the codebase of lpeg-1.0.0lpeg-1.0.0
Diffstat (limited to 'lpcode.c')
-rw-r--r-- | lpcode.c | 84 |
1 files changed, 28 insertions, 56 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lpcode.c,v 1.24 2016/09/15 17:46:13 roberto Exp $ | 2 | ** $Id: lpcode.c,v 1.23 2015/06/12 18:36:47 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,27 +126,6 @@ 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 | */ | ||
133 | static 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 | /* | ||
150 | ** Check whether a pattern tree has captures | 129 | ** Check whether a pattern tree has captures |
151 | */ | 130 | */ |
152 | int hascaptures (TTree *tree) { | 131 | int hascaptures (TTree *tree) { |
@@ -155,17 +134,14 @@ int hascaptures (TTree *tree) { | |||
155 | case TCapture: case TRunTime: | 134 | case TCapture: case TRunTime: |
156 | return 1; | 135 | return 1; |
157 | case TCall: | 136 | case TCall: |
158 | return callrecursive(tree, hascaptures, 0); | 137 | tree = sib2(tree); goto tailcall; /* return hascaptures(sib2(tree)); */ |
159 | case TRule: /* do not follow siblings */ | ||
160 | tree = sib1(tree); goto tailcall; | ||
161 | case TOpenCall: assert(0); | 138 | case TOpenCall: assert(0); |
162 | default: { | 139 | default: { |
163 | switch (numsiblings[tree->tag]) { | 140 | switch (numsiblings[tree->tag]) { |
164 | case 1: /* return hascaptures(sib1(tree)); */ | 141 | case 1: /* return hascaptures(sib1(tree)); */ |
165 | tree = sib1(tree); goto tailcall; | 142 | tree = sib1(tree); goto tailcall; |
166 | case 2: | 143 | case 2: |
167 | if (hascaptures(sib1(tree))) | 144 | if (hascaptures(sib1(tree))) return 1; |
168 | return 1; | ||
169 | /* else return hascaptures(sib2(tree)); */ | 145 | /* else return hascaptures(sib2(tree)); */ |
170 | tree = sib2(tree); goto tailcall; | 146 | tree = sib2(tree); goto tailcall; |
171 | default: assert(numsiblings[tree->tag] == 0); return 0; | 147 | default: assert(numsiblings[tree->tag] == 0); return 0; |
@@ -232,9 +208,9 @@ int checkaux (TTree *tree, int pred) { | |||
232 | 208 | ||
233 | /* | 209 | /* |
234 | ** number of characters to match a pattern (or -1 if variable) | 210 | ** number of characters to match a pattern (or -1 if variable) |
211 | ** ('count' avoids infinite loops for grammars) | ||
235 | */ | 212 | */ |
236 | int fixedlen (TTree *tree) { | 213 | int fixedlenx (TTree *tree, int count, int len) { |
237 | int len = 0; /* to accumulate in tail calls */ | ||
238 | tailcall: | 214 | tailcall: |
239 | switch (tree->tag) { | 215 | switch (tree->tag) { |
240 | case TChar: case TSet: case TAny: | 216 | case TChar: case TSet: case TAny: |
@@ -245,29 +221,26 @@ int fixedlen (TTree *tree) { | |||
245 | case TThrow: /* labeled failure */ | 221 | case TThrow: /* labeled failure */ |
246 | return -1; | 222 | return -1; |
247 | case TCapture: case TRule: case TGrammar: | 223 | case TCapture: case TRule: case TGrammar: |
248 | /* return fixedlen(sib1(tree)); */ | 224 | /* return fixedlenx(sib1(tree), count); */ |
249 | tree = sib1(tree); goto tailcall; | 225 | tree = sib1(tree); goto tailcall; |
250 | case TCall: { | 226 | case TCall: |
251 | int n1 = callrecursive(tree, fixedlen, -1); | 227 | if (count++ >= MAXRULES) |
252 | if (n1 < 0) | 228 | return -1; /* may be a loop */ |
253 | return -1; | 229 | /* else return fixedlenx(sib2(tree), count); */ |
254 | else | 230 | tree = sib2(tree); goto tailcall; |
255 | return len + n1; | 231 | case TSeq: { |
256 | } | 232 | len = fixedlenx(sib1(tree), count, len); |
257 | case TSeq: { | 233 | if (len < 0) return -1; |
258 | int n1 = fixedlen(sib1(tree)); | 234 | /* else return fixedlenx(sib2(tree), count, len); */ |
259 | if (n1 < 0) | 235 | tree = sib2(tree); goto tailcall; |
260 | return -1; | ||
261 | /* else return fixedlen(sib2(tree)) + len; */ | ||
262 | len += n1; tree = sib2(tree); goto tailcall; | ||
263 | } | 236 | } |
264 | case TChoice: { | 237 | case TChoice: { |
265 | int n1 = fixedlen(sib1(tree)); | 238 | int n1, n2; |
266 | int n2 = fixedlen(sib2(tree)); | 239 | n1 = fixedlenx(sib1(tree), count, len); |
267 | if (n1 != n2 || n1 < 0) | 240 | if (n1 < 0) return -1; |
268 | return -1; | 241 | n2 = fixedlenx(sib2(tree), count, len); |
269 | else | 242 | if (n1 == n2) return n1; |
270 | return len + n1; | 243 | else return -1; |
271 | } | 244 | } |
272 | default: assert(0); return 0; | 245 | default: assert(0); return 0; |
273 | }; | 246 | }; |
@@ -311,7 +284,7 @@ static int getfirst (TTree *tree, const Charset *follow, Charset *firstset) { | |||
311 | loopset(i, firstset->cs[i] = fullset->cs[i]); | 284 | loopset(i, firstset->cs[i] = fullset->cs[i]); |
312 | return 1; | 285 | return 1; |
313 | } | 286 | } |
314 | case TChoice: { | 287 | case TChoice: { |
315 | Charset csaux; | 288 | Charset csaux; |
316 | int e1 = getfirst(sib1(tree), follow, firstset); | 289 | int e1 = getfirst(sib1(tree), follow, firstset); |
317 | int e2 = getfirst(sib2(tree), follow, &csaux); | 290 | int e2 = getfirst(sib2(tree), follow, &csaux); |
@@ -396,7 +369,7 @@ static int headfail (TTree *tree) { | |||
396 | if (!nofail(sib2(tree))) return 0; | 369 | if (!nofail(sib2(tree))) return 0; |
397 | /* else return headfail(sib1(tree)); */ | 370 | /* else return headfail(sib1(tree)); */ |
398 | tree = sib1(tree); goto tailcall; | 371 | tree = sib1(tree); goto tailcall; |
399 | case TChoice: | 372 | case TChoice: |
400 | if (!headfail(sib1(tree))) return 0; | 373 | if (!headfail(sib1(tree))) return 0; |
401 | /* else return headfail(sib2(tree)); */ | 374 | /* else return headfail(sib2(tree)); */ |
402 | tree = sib2(tree); goto tailcall; | 375 | tree = sib2(tree); goto tailcall; |
@@ -769,10 +742,9 @@ static void codeand (CompileState *compst, TTree *tree, int tt) { | |||
769 | 742 | ||
770 | 743 | ||
771 | /* | 744 | /* |
772 | ** Captures: if pattern has fixed (and not too big) length, and it | 745 | ** Captures: if pattern has fixed (and not too big) length, use |
773 | ** has no nested captures, use a single IFullCapture instruction | 746 | ** a single IFullCapture instruction after the match; otherwise, |
774 | ** after the match; otherwise, enclose the pattern with OpenCapture - | 747 | ** enclose the pattern with OpenCapture - CloseCapture. |
775 | ** CloseCapture. | ||
776 | */ | 748 | */ |
777 | static void codecapture (CompileState *compst, TTree *tree, int tt, | 749 | static void codecapture (CompileState *compst, TTree *tree, int tt, |
778 | const Charset *fl) { | 750 | const Charset *fl) { |