diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-06-22 10:50:15 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-06-22 10:50:15 -0300 |
commit | 4eb4419163dd6c97665b9481e9581ff32496b392 (patch) | |
tree | 85bbac8be5fb03d340a6a901fd15599dd699d8da | |
parent | e3f612f58dc0201beb3a86e1a5d8df9cd9158698 (diff) | |
download | lpeg-4eb4419163dd6c97665b9481e9581ff32496b392.tar.gz lpeg-4eb4419163dd6c97665b9481e9581ff32496b392.tar.bz2 lpeg-4eb4419163dd6c97665b9481e9581ff32496b392.zip |
Accumulator pattern added to the 're' module
-rw-r--r-- | re.lua | 16 | ||||
-rwxr-xr-x | test.lua | 7 |
2 files changed, 15 insertions, 8 deletions
@@ -141,7 +141,7 @@ local item = (defined + Range + m.C(any)) / m.P | |||
141 | local Class = | 141 | local 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 | ||
168 | local exp = m.P{ "Exp", | 168 | local 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 | ||
210 | local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error) | 210 | local pattern = S * m.Cg(m.Cc(false), "G") * exp / mm.P * (-any + patt_error) |
@@ -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}) |
1518 | assert(c:match("3 401 50") == 3 + 401 + 50) | 1518 | assert(c:match("3 401 50") == 3 + 401 + 50) |
1519 | 1519 | ||
1520 | -- test for accumulator captures | ||
1521 | c = re.compile([[ | ||
1522 | S <- number (%s+ number >> add)* | ||
1523 | number <- %d+ -> tonumber | ||
1524 | ]], {tonumber = tonumber, add = function (a,b) return a + b end}) | ||
1525 | assert(c:match("3 401 50") == 3 + 401 + 50) | ||
1526 | |||
1520 | -- tests for look-ahead captures | 1527 | -- tests for look-ahead captures |
1521 | x = {re.match("alo", "&(&{.}) !{'b'} {&(...)} &{..} {...} {!.}")} | 1528 | x = {re.match("alo", "&(&{.}) !{'b'} {&(...)} &{..} {...} {!.}")} |
1522 | checkeq(x, {"", "alo", ""}) | 1529 | checkeq(x, {"", "alo", ""}) |