lua-users home
lua-l archive

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


On Wed, 16 Aug 2023 at 16:25, Roberto Ierusalimschy
<roberto@inf.puc-rio.br> wrote:
> "complete" is defined in the text you sent; "outermost" idem; "last"
> means "most recent" (also defined in the text); "group capture" is
> defined somewhere else. I really don't know what else we should
> explain.
>
> In your example:
>
>   (lpeg.C(1):Cg"c" * (lpeg.C(1):Cg"d" * lpeg.Cb"c")):match"ab"
>
> When it matches lpeg.Cb"c", the match with "lpeg.C(1):Cg"c" is complete.
> That group pattern is also not inside another complete capture that does
> not contain the back capture itself, so it is outermost. It is the last
> group capture with that given name ("c"). So, its value is used in the
> back capture.
>
> Counter-examples:
>
>   - lpeg.Cg(lpeg.Cb"c", "c")
>   When it matches lpeg.Cb"c", the group capture is not complete, so
>   it cannot be used.
>
>   - (lpeg.Cg(1, "c") / "x") * lpeg.Cb("c")
>   The group capture is inside another complete capture (the string
>   capture) that does not contain the back capture, so it is not
>   "outermost", and therefore cannot be used.
>
> (Actually, it seems that "that does not contain the back capture itself"
> is redundant. If the capture is complete, it cannot contain the back
> capture.)


Hi Roberto,

I gave a mini-presentation/mini-workshop about my diagrams to two
friends yesterday and they liked it very much - so now there are at
least two people besides me who think that they are useful, and that's
more than enough...

Anyway, in the code below the tests C1..C3 and D1..D4 are based in
your examples. In the block D1..D4 only D4 yields an error, and that
makes sense to me - but in the block C1..C3 the tests C1 and C3 yield
errors but C2 does not. Is this behavior of C1..C3 something that is
explained in the documentation? How? I admit that I'm still struggling
with some terms, sorry...

The code:

  require "lpeg"
  B,C,P,R,S,V = lpeg.B,lpeg.C,lpeg.P,lpeg.R,lpeg.S,lpeg.V
  Cb,Cc,Cf,Cg = lpeg.Cb,lpeg.Cc,lpeg.Cf,lpeg.Cg
  Cp,Cs,Ct    = lpeg.Cp,lpeg.Cs,lpeg.Ct
  Carg,Cmt    = lpeg.Carg,lpeg.Cmt
  lpeg.pm     = function (pat, str) PP(pat:match(str or "")) end

  pat1234     = Cc(10, 20) * Cc(30, 40):Cg"a"
  pat5678     = Cc(50, 60) * Cc(70, 80):Cg"a"

  (pat1234                            )     :pm()    -- A1
  (pat1234                            ):Ct():pm()    -- A2
  (pat1234          * pat5678         ):Ct():pm()    -- A3
  (pat1234 *  Cb"a" * pat5678  * Cb"a"):Ct():pm()    -- A4
  (pat1234 * (Cb"a" * pat5678) * Cb"a"):Ct():pm()    -- A5

  (pat1234              ):Ct():pm()         -- B1
  (pat1234:Cg"b"        ):Ct():pm()         -- B2
  (pat1234:Cg"b" * Cb"b"):Ct():pm()         -- B3

  (Cb"c"      )     :pm()                   -- C1
  (Cb"c":Cg"c")     :pm()                   -- C2
  (Cb"c":Cg"c"):Ct():pm()                   -- C3

     Cc"a"                         :pm()    -- D1
     Cc"a":Cg"c"                   :pm()    -- D2
   ((Cc"a":Cg"c") / "x")           :pm()    -- D3
  (((Cc"a":Cg"c") / "x") * Cb"c")  :pm()    -- D4

Its output in a REPL:

  >   require "lpeg"
  >   B,C,P,R,S,V = lpeg.B,lpeg.C,lpeg.P,lpeg.R,lpeg.S,lpeg.V
  >   Cb,Cc,Cf,Cg = lpeg.Cb,lpeg.Cc,lpeg.Cf,lpeg.Cg
  >   Cp,Cs,Ct    = lpeg.Cp,lpeg.Cs,lpeg.Ct
  >   Carg,Cmt    = lpeg.Carg,lpeg.Cmt
  >   lpeg.pm     = function (pat, str) PP(pat:match(str or "")) end
  >
  >   pat1234     = Cc(10, 20) * Cc(30, 40):Cg"a"
  >   pat5678     = Cc(50, 60) * Cc(70, 80):Cg"a"
  >
  >   (pat1234                            )     :pm()    -- A1
   10 20
  >   (pat1234                            ):Ct():pm()    -- A2
   {1=10, 2=20, "a"=30}
  >   (pat1234          * pat5678         ):Ct():pm()    -- A3
   {1=10, 2=20, 3=50, 4=60, "a"=70}
  >   (pat1234 *  Cb"a" * pat5678  * Cb"a"):Ct():pm()    -- A4
   {1=10, 2=20, 3=30, 4=40, 5=50, 6=60, 7=70, 8=80, "a"=70}
  >   (pat1234 * (Cb"a" * pat5678) * Cb"a"):Ct():pm()    -- A5
   {1=10, 2=20, 3=30, 4=40, 5=50, 6=60, 7=70, 8=80, "a"=70}
  >
  >   (pat1234              ):Ct():pm()         -- B1
   {1=10, 2=20, "a"=30}
  >   (pat1234:Cg"b"        ):Ct():pm()         -- B2
   {"b"=10}
  >   (pat1234:Cg"b" * Cb"b"):Ct():pm()         -- B3
   {1=10, 2=20, "b"=10}
  >
  >   (Cb"c"      )     :pm()                   -- C1
  stdin:1: back reference 'c' not found
  stack traceback:
  [C]: in function 'match'
  stdin:1: in function 'pm'
  stdin:1: in main chunk
  [C]: ?
  >   (Cb"c":Cg"c")     :pm()                   -- C2
   1
  >   (Cb"c":Cg"c"):Ct():pm()                   -- C3
  stdin:1: back reference 'c' not found
  stack traceback:
  [C]: in function 'match'
  stdin:1: in function 'pm'
  stdin:1: in main chunk
  [C]: ?
  >
  >      Cc"a"                         :pm()    -- D1
   "a"
  >      Cc"a":Cg"c"                   :pm()    -- D2
   1
  >    ((Cc"a":Cg"c") / "x")           :pm()    -- D3
   "x"
  >   (((Cc"a":Cg"c") / "x") * Cb"c")  :pm()    -- D4
  stdin:1: back reference 'c' not found
  stack traceback:
  [C]: in function 'match'
  stdin:1: in function 'pm'
  stdin:1: in main chunk
  [C]: ?
  >

Thanks in advance =/,
  Eduardo Ochs