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", ""}) |
