[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: yet another pattern-matching library for Lua
- From: Philippe Lhoste <PhiLho@...>
- Date: Thu, 04 Jan 2007 12:56:30 +0100
Philippe Lhoste wrote:
Thanks, I will try to compile this for Windows to be able to test it.
Done, that's my first module for Lua 5.1...
Now I can play with this library!
function rep (p, n, m)
[...]
end
As untested as your...
No longer... I preferred to manage parameters differently:
local m = require"lpeg"
-- emulates {n,m} syntax of REs:
-- {n} exactly n repeats (m omitted or equal to n)
-- {n,} n or more repeats (m nul (zero) or negative)
-- {n,m} at least n repeats, at most m (m must be greater than n)
function rep(p, n, m)
local r = lpeg.P""
for i = 1, n do r = r * p end -- at least n
if m == nil or m == n then return r -- {n,n} or {n}
elseif m <= 0 then m = 0 -- {n,}
else m = n - m -- m should be negative...
end
return r * p^m
end
digit = m.R('0', '9')
upper = m.R("A", "Z")
lower = m.R("a", "z")
letter = upper + lower
alpha = letter + digit
ansiDate = rep(digit, 4) * '-' * rep(digit, 2) * '-' * rep(digit, 2)
ansiDate2 = rep(digit, 4) * rep('-' * rep(digit, 2), 2)
d3 = rep(digit, 1, 3)
ipAddress = d3 * '.' * d3 * '.' * d3 * '.' * d3
ipAddress2 = d3 * rep('.' * d3, 3)
print(m.match("2007-01-04", ansiDate))
print(m.match("400-01-04", ansiDate))
print(m.match("2007-01-04", ansiDate2))
print(m.match("400-01-04", ansiDate2))
print(m.match("168.92.0.11", ipAddress))
print(m.match("168.2F.0.11", ipAddress))
print(m.match("127.0.0.1", ipAddress2))
print(m.match("1168.99.0.111", ipAddress2))
The remark of Mike is interesting.
It is annoying that Pegs cannot reference previous captures in the same
pattern.
I understand that's not obvious, because of the non-linear (recursive)
way of writing patterns. Perhaps with a way to push a capture in a
stack, then pulling this result and using it in the match. That suppose
some dynamic part in the parsed pattern.
For example, instead of the following (wrong) code:
comment = "[" * m.C(m.P("=")^0) * "[" *
(m.P(1) - "]" * m.P("=")^0 * "]")^0 *
"]" * m.P("=")^0 * "]"
we would have something like:
comment = "[" * m.PushC(m.P("=")^0) * "[" *
(m.P(1) - "]" * m.PushC(m.PullC()) * "]")^0 *
"]" * m.PullC() * "]"
but maybe using callbacks might be the way to go.
--
Philippe Lhoste
-- (near) Paris -- France
-- http://Phi.Lho.free.fr
-- -- -- -- -- -- -- -- -- -- -- -- -- --