lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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
--  --  --  --  --  --  --  --  --  --  --  --  --  --