aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-04-30 18:23:40 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-04-30 18:23:40 -0300
commit1cc484a05cf9c7da8c859f3f52ea5a85009c4509 (patch)
tree68983c515343cb1759e6b94a14f911fa8405f0d7
parenteb8b906d5eb5113e7377f06afbfd641c1c5e6a1e (diff)
downloadlpeg-1cc484a05cf9c7da8c859f3f52ea5a85009c4509.tar.gz
lpeg-1cc484a05cf9c7da8c859f3f52ea5a85009c4509.tar.bz2
lpeg-1cc484a05cf9c7da8c859f3f52ea5a85009c4509.zip
'nullable' ('checkaux') uses tag from 'verifyrule'
When checking whether a rule is nullable, 'checkaux' reuses tag previously set by 'verifyrule'.
-rw-r--r--lpcode.c7
-rw-r--r--lpprint.c23
-rw-r--r--lptree.c7
-rw-r--r--lptree.h7
-rwxr-xr-xtest.lua44
5 files changed, 75 insertions, 13 deletions
diff --git a/lpcode.c b/lpcode.c
index f3b8ae3..2a4e642 100644
--- a/lpcode.c
+++ b/lpcode.c
@@ -139,7 +139,12 @@ int checkaux (TTree *tree, int pred) {
139 if (checkaux(sib2(tree), pred)) return 1; 139 if (checkaux(sib2(tree), pred)) return 1;
140 /* else return checkaux(sib1(tree), pred); */ 140 /* else return checkaux(sib1(tree), pred); */
141 tree = sib1(tree); goto tailcall; 141 tree = sib1(tree); goto tailcall;
142 case TCapture: case TGrammar: case TRule: case TXInfo: 142 case TRule:
143 assert(tree->cap == RLNULL || tree->cap == RLNONNULL);
144 if (pred == PEnullable)
145 return (tree->cap == RLNULL);
146 /* else */ /* FALLTHROUGH */
147 case TCapture: case TGrammar: case TXInfo:
143 /* return checkaux(sib1(tree), pred); */ 148 /* return checkaux(sib1(tree), pred); */
144 tree = sib1(tree); goto tailcall; 149 tree = sib1(tree); goto tailcall;
145 case TCall: /* return checkaux(sib2(tree), pred); */ 150 case TCall: /* return checkaux(sib2(tree), pred); */
diff --git a/lpprint.c b/lpprint.c
index 42824cc..0150750 100644
--- a/lpprint.c
+++ b/lpprint.c
@@ -278,10 +278,16 @@ static void printktable (lua_State *L, int idx) {
278/* }====================================================== */ 278/* }====================================================== */
279 279
280 280
281static int lp_printtree (lua_State *L) { 281static Pattern * getp (lua_State *L, int compile) {
282 Pattern *p = (Pattern *)luaL_checkudata(L, 1, PATTERN_T); 282 Pattern *p = (Pattern *)luaL_checkudata(L, 1, PATTERN_T);
283 if (lua_toboolean(L, 2)) 283 if (compile && p->code == NULL) /* not compiled yet? */
284 prepcompile(L, p, 1); 284 prepcompile(L, p, 1);
285 return p;
286}
287
288
289static int lp_printtree (lua_State *L) {
290 Pattern *p = getp(L, lua_toboolean(L, 2));
285 printktable(L, 1); 291 printktable(L, 1);
286 printtree(p->tree, 0); 292 printtree(p->tree, 0);
287 return 0; 293 return 0;
@@ -289,17 +295,24 @@ static int lp_printtree (lua_State *L) {
289 295
290 296
291static int lp_printcode (lua_State *L) { 297static int lp_printcode (lua_State *L) {
292 Pattern *p = (Pattern *)luaL_checkudata(L, 1, PATTERN_T); 298 Pattern *p = getp(L, 1);
293 printktable(L, 1); 299 printktable(L, 1);
294 if (p->code == NULL) /* not compiled yet? */
295 prepcompile(L, p, 1);
296 printpatt(p->code); 300 printpatt(p->code);
297 return 0; 301 return 0;
298} 302}
299 303
304
305static int lp_nullable (lua_State *L) {
306 Pattern *p = getp(L, 0);
307 lua_pushboolean(L, nullable(p->tree));
308 return 1;
309}
310
311
300static struct luaL_Reg debugreg[] = { 312static struct luaL_Reg debugreg[] = {
301 {"ptree", lp_printtree}, 313 {"ptree", lp_printtree},
302 {"pcode", lp_printcode}, 314 {"pcode", lp_printcode},
315 {"nullable", lp_nullable},
303 {NULL, NULL} 316 {NULL, NULL}
304}; 317};
305 318
diff --git a/lptree.c b/lptree.c
index 835595c..568b64f 100644
--- a/lptree.c
+++ b/lptree.c
@@ -1016,13 +1016,6 @@ static int collectrules (lua_State *L, int arg, int *totalsize) {
1016} 1016}
1017 1017
1018 1018
1019/* Status of a Rule */
1020#define RLNOTVISITED 0 /* rule not visited yet */
1021#define RLBEINGVISITED 1 /* rule is being visited */
1022#define RLNULL 2 /* rule was visited and is nullable */
1023#define RLNONNULL 3 /* rule was visited and is not nullable */
1024
1025
1026static void buildgrammar (lua_State *L, TTree *grammar, int frule, int n) { 1019static void buildgrammar (lua_State *L, TTree *grammar, int frule, int n) {
1027 int i; 1020 int i;
1028 TTree *nd = sib1(grammar); /* auxiliary pointer to traverse the tree */ 1021 TTree *nd = sib1(grammar); /* auxiliary pointer to traverse the tree */
diff --git a/lptree.h b/lptree.h
index 4c0951d..875ae4f 100644
--- a/lptree.h
+++ b/lptree.h
@@ -63,6 +63,13 @@ typedef struct TTree {
63} TTree; 63} TTree;
64 64
65 65
66/* Status of a Rule */
67#define RLNOTVISITED 0 /* rule not visited yet */
68#define RLBEINGVISITED 1 /* rule is being visited */
69#define RLNULL 2 /* rule was visited and is nullable */
70#define RLNONNULL 3 /* rule was visited and is not nullable */
71
72
66/* access to charset */ 73/* access to charset */
67#define treebuffer(t) ((t)->u.set.bitmap) 74#define treebuffer(t) ((t)->u.set.bitmap)
68 75
diff --git a/test.lua b/test.lua
index 3241408..a81c8b8 100755
--- a/test.lua
+++ b/test.lua
@@ -1662,6 +1662,50 @@ errmsg("x <- 'a' x <- 'b'", 'already defined')
1662errmsg("'a' -", "near '-'") 1662errmsg("'a' -", "near '-'")
1663 1663
1664 1664
1665if m.nullable then
1666 print "testing nullable predicate"
1667
1668
1669 local bg = re.compile[[
1670 A31 <- A30 A30
1671 A30 <- A29 A29
1672 A29 <- A28 A28
1673 A28 <- A27 A27
1674 A27 <- A26 A26
1675 A26 <- A25 A25
1676 A25 <- A24 A24
1677 A24 <- A23 A23
1678 A23 <- A22 A22
1679 A22 <- A21 A21
1680 A21 <- A20 A20
1681 A20 <- A19 A19
1682 A19 <- A18 A18
1683 A18 <- A17 A17
1684 A17 <- A16 A16
1685 A16 <- A15 A15
1686 A15 <- A14 A14
1687 A14 <- A13 A13
1688 A13 <- A12 A12
1689 A12 <- A11 A11
1690 A11 <- A10 A10
1691 A10 <- A9 A9
1692 A9 <- A8 A8
1693 A8 <- A7 A7
1694 A7 <- A6 A6
1695 A6 <- A5 A5
1696 A5 <- A4 A4
1697 A4 <- A3 A3
1698 A3 <- A2 A2
1699 A2 <- A1 A1
1700 A1 <- ""
1701 ]]
1702
1703 assert(bg:nullable())
1704 assert((bg * bg):nullable())
1705 assert(not (bg * bg * "a"):nullable())
1706 assert(m.P(-1):nullable())
1707end
1708
1665print"OK" 1709print"OK"
1666 1710
1667 1711