lua-users home
lua-l archive

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


You can use pretty much the same technique as the Lua long string
example on the LPEG webpage:
http://www.inf.puc-rio.br/~roberto/lpeg/

To quote:

Lua's long strings

A long string in Lua starts with the pattern [=*[ and ends at the
first occurrence of ]=*] with exactly the same number of equal signs.
If the opening brackets are followed by a newline, this newline is
discharged (that is, it is not part of the string).

To match a long string in Lua, the pattern must capture the first
repetition of equal signs and then, whenever it finds a candidate for
closing the string, check whether it has the same number of equal
signs.

equals = lpeg.P"="^0
open = "[" * lpeg.Cg(equals, "init") * "[" * lpeg.P"\n"^-1
close = "]" * lpeg.C(equals) * "]"
closeeq = lpeg.Cmt(close * lpeg.Cb("init"), function (s, i, a, b)
return a == b end)
string = open * lpeg.C((lpeg.P(1) - closeeq)^0) * close /
  function (s, o) return s end

The open pattern matches [=*[, capturing the repetitions of equal
signs in a group named init; it also discharges an optional newline,
if present. The close pattern matches ]=*], also capturing the
repetitions of equal signs. The closeeq pattern first matches close;
then it uses a back capture to recover the capture made by the
previous open, which is named init; finally it uses a match-time
capture to check whether both captures are equal. The string pattern
starts with an open, then it goes as far as possible until matching
closeeq, and then matches the final close. The final function capture
simply discards the capture made by close.

On Thu, Dec 6, 2012 at 5:49 AM, Benjamin Kober <kober@optisense.com> wrote:
> Hello list,
>
> I want to implement an asciidoc parser with lpeg. Now I got stuck with
> the `ifdef`-macro. It is defined
>
> ifdef::<attribute>[]
> ...
> endif::<attribute>[]
>
> in the asciidoc documentation. Now I've got
>
> start = lpeg.P"ifdef::" * attribute * "[]"
> stop  = lpeg.P"endif::" * attribute * "[]"
>
> patt = start * (any-stop)^0 * stop
>
> but to support nested `ifdef` I need to make sure that `attribute` is
> exactly the same and does not just match the same pattern.
>
> Can I use something like
>
> att2 = attribute / lepeg.P
> stop = lpeg.P"endif::" * att2 * "[]"
>
> Any ideas?
>
> Thx, Benjamin
>