  lua-l archive

• Subject: Re: LPEG > 0.10 regression: 'B' (pattern may not have fixed length)
• From: Roberto Ierusalimschy <roberto@...>
• Date: Fri, 15 Apr 2016 13:35:56 -0300

```> Consider this piece of code:
>
> ```
> local lpeg = require 'lpeg'
>
> local D = lpeg.R'09'
> local I = lpeg.R('AZ', 'az', '\127\255') + '_'
> local SOS = lpeg.P(function(s, i) return i == 1 end) -- start of string
> local EOS = -lpeg.P(1) -- end of string
> local B = -(I + D) -- word boundary
>
> -- Transform a string with keywords into an LPeg pattern that matches a keyword
> -- followed by a word boundary.
>
> local patt = lpeg.P("foo")+lpeg.P("bar")+lpeg.P("qux")
> local BB = lpeg.B(B) + SOS -- starting boundary
> local AB = B + EOS -- ending boundary
>
> patt = BB * patt * AB
>
> patt = lpeg.P{ patt + 1 * lpeg.V(1) }
>
> print(patt:match(" foo"))
> ```
>
> It works in lpeg 0.10. but not in lpeg 1.0
> To get it to work in lpeg 1.0 I applied this change:
>
> -local B = -(I + D) -- word boundary
> +local B = #lpeg.P(1) + -(I + D) -- word boundary

The "look behind" (lpeg.B) function changed from 0.10 to 0.11.

In 0.10, it received an explicit number to "go back" before the match,
and the default was one. In 0.11 and later versions, it uses the
"pattern length" as the length to go back.  For instance,
lpeg.B("123") will try to match "123" three positions
behind the current one,
and lpeg.B("1") will go back one position.
In your code, BB goes back the size of B, which is zero.
Probably what you want is this:

- BB = lpeg.B(-(I + D)) + SOS -- starting boundary
+ BB = -peg.B(I + D) + SOS -- starting boundary

-- Roberto

```

• References: