aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-06-22 10:50:15 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-06-22 10:50:15 -0300
commit4eb4419163dd6c97665b9481e9581ff32496b392 (patch)
tree85bbac8be5fb03d340a6a901fd15599dd699d8da
parente3f612f58dc0201beb3a86e1a5d8df9cd9158698 (diff)
downloadlpeg-4eb4419163dd6c97665b9481e9581ff32496b392.tar.gz
lpeg-4eb4419163dd6c97665b9481e9581ff32496b392.tar.bz2
lpeg-4eb4419163dd6c97665b9481e9581ff32496b392.zip
Accumulator pattern added to the 're' module
-rw-r--r--re.lua16
-rwxr-xr-xtest.lua7
2 files changed, 15 insertions, 8 deletions
diff --git a/re.lua b/re.lua
index 8e306c2..5044e9e 100644
--- a/re.lua
+++ b/re.lua
@@ -141,7 +141,7 @@ local item = (defined + Range + m.C(any)) / m.P
141local Class = 141local Class =
142 "[" 142 "["
143 * (m.C(m.P"^"^-1)) -- optional complement symbol 143 * (m.C(m.P"^"^-1)) -- optional complement symbol
144 * m.Cf(item * (item - "]")^0, mt.__add) / 144 * (item * ((item % mt.__add) - "]")^0) /
145 function (c, p) return c == "^" and any - p or p end 145 function (c, p) return c == "^" and any - p or p end
146 * "]" 146 * "]"
147 147
@@ -167,13 +167,13 @@ end
167 167
168local exp = m.P{ "Exp", 168local exp = m.P{ "Exp",
169 Exp = S * ( m.V"Grammar" 169 Exp = S * ( m.V"Grammar"
170 + m.Cf(m.V"Seq" * ("/" * S * m.V"Seq")^0, mt.__add) ); 170 + m.V"Seq" * ("/" * S * m.V"Seq" % mt.__add)^0 );
171 Seq = m.Cf(m.Cc(m.P"") * m.V"Prefix"^0 , mt.__mul) 171 Seq = (m.Cc(m.P"") * (m.V"Prefix" % mt.__mul)^0)
172 * (#seq_follow + patt_error); 172 * (#seq_follow + patt_error);
173 Prefix = "&" * S * m.V"Prefix" / mt.__len 173 Prefix = "&" * S * m.V"Prefix" / mt.__len
174 + "!" * S * m.V"Prefix" / mt.__unm 174 + "!" * S * m.V"Prefix" / mt.__unm
175 + m.V"Suffix"; 175 + m.V"Suffix";
176 Suffix = m.Cf(m.V"Primary" * S * 176 Suffix = m.V"Primary" * S *
177 ( ( m.P"+" * m.Cc(1, mt.__pow) 177 ( ( m.P"+" * m.Cc(1, mt.__pow)
178 + m.P"*" * m.Cc(0, mt.__pow) 178 + m.P"*" * m.Cc(0, mt.__pow)
179 + m.P"?" * m.Cc(-1, mt.__pow) 179 + m.P"?" * m.Cc(-1, mt.__pow)
@@ -185,9 +185,10 @@ local exp = m.P{ "Exp",
185 + defwithfunc(mt.__div) 185 + defwithfunc(mt.__div)
186 ) 186 )
187 + "=>" * S * defwithfunc(mm.Cmt) 187 + "=>" * S * defwithfunc(mm.Cmt)
188 + ">>" * S * defwithfunc(mt.__mod)
188 + "~>" * S * defwithfunc(mm.Cf) 189 + "~>" * S * defwithfunc(mm.Cf)
189 ) * S 190 ) % function (a,b,f) return f(a,b) end * S
190 )^0, function (a,b,f) return f(a,b) end ); 191 )^0;
191 Primary = "(" * m.V"Exp" * ")" 192 Primary = "(" * m.V"Exp" * ")"
192 + String / mm.P 193 + String / mm.P
193 + Class 194 + Class
@@ -203,8 +204,7 @@ local exp = m.P{ "Exp",
203 + (name * -arrow + "<" * name * ">") * m.Cb("G") / NT; 204 + (name * -arrow + "<" * name * ">") * m.Cb("G") / NT;
204 Definition = name * arrow * m.V"Exp"; 205 Definition = name * arrow * m.V"Exp";
205 Grammar = m.Cg(m.Cc(true), "G") * 206 Grammar = m.Cg(m.Cc(true), "G") *
206 m.Cf(m.V"Definition" / firstdef * m.Cg(m.V"Definition")^0, 207 ((m.V"Definition" / firstdef) * (m.V"Definition" % adddef)^0) / mm.P
207 adddef) / mm.P
208} 208}
209 209
210local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error) 210local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error)
diff --git a/test.lua b/test.lua
index 7e61603..d0b82da 100755
--- a/test.lua
+++ b/test.lua
@@ -1517,6 +1517,13 @@ c = re.compile([[
1517]], {tonumber = tonumber, add = function (a,b) return a + b end}) 1517]], {tonumber = tonumber, add = function (a,b) return a + b end})
1518assert(c:match("3 401 50") == 3 + 401 + 50) 1518assert(c:match("3 401 50") == 3 + 401 + 50)
1519 1519
1520-- test for accumulator captures
1521c = re.compile([[
1522 S <- number (%s+ number >> add)*
1523 number <- %d+ -> tonumber
1524]], {tonumber = tonumber, add = function (a,b) return a + b end})
1525assert(c:match("3 401 50") == 3 + 401 + 50)
1526
1520-- tests for look-ahead captures 1527-- tests for look-ahead captures
1521x = {re.match("alo", "&(&{.}) !{'b'} {&(...)} &{..} {...} {!.}")} 1528x = {re.match("alo", "&(&{.}) !{'b'} {&(...)} &{..} {...} {!.}")}
1522checkeq(x, {"", "alo", ""}) 1529checkeq(x, {"", "alo", ""})