[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: LPEG bug?
- From: Roberto Ierusalimschy <roberto@...>
- Date: Thu, 4 Jun 2015 11:15:39 -0300
> Today I was working on an lpeg pattern, and ran into this oddity,
> which I believe to be a bug.
> I've condensed it down as far as I could, if I remove any more the bug
> seems to disappear.
>
> The following script throws in the assert.
> If you uncomment either of the alternate `path_abempty` definitions, it works.
>
> local lpeg = require "lpeg"
> local P = lpeg.P
> local HEXDIG = lpeg.R("09","af", "AF")
> local pct_encoded = P"%" * lpeg.C ( HEXDIG * HEXDIG ) / function (hex_num)
> return string.char(tonumber(hex_num, 16))
> end
> local pchar = lpeg.R("az","AZ") + pct_encoded
> local path_abempty = ( P"/" * pchar^0 )^0
> -- local path_abempty = ( P"/" * pchar^0 )^0 * ( P"/" * pchar^0 )^0
> -- local path_abempty = ( P"/" * pchar^0 )^0 * function() return true end
> local path_rootless = pchar^1 * path_abempty
> local path_absolute = P"/" * path_rootless^-1
>
> assert(lpeg.Cs ( path_absolute ):match "/var/log/messages" ==
> "/var/log/messages")
The problem can be reduced to the following example:
local re = require're'
local p = re.compile[[ { ('ab' ('c' 'ef'?)*)? } ]]
s = "abcefccefc"
print(s, p:match(s)) --> abcefccefc abcefc
(An optional at the end of a repetition at the end of an
optional...) The bug is caused by a wrong optimization; the following
patch (in lpcode.c) should fix it:
@@ -759,7 +759,7 @@
/* L1: test (fail(p1)) -> L2; <p>; jmp L1; L2: */
int jmp;
int test = codetestset(compst, &st, 0);
- codegen(compst, tree, opt, test, fullset);
+ codegen(compst, tree, 0, test, fullset); /* ?????? */
jmp = addoffsetinst(compst, IJmp);
jumptohere(compst, test);
jumptothere(compst, jmp, test);
(I think there is a similar bug in repetitions, line 678, but I have to
recheck that.)
-- Roberto