Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with lpeg 0.12 #5

Closed
catwell opened this issue Jul 2, 2013 · 2 comments · Fixed by #6
Closed

Problem with lpeg 0.12 #5

catwell opened this issue Jul 2, 2013 · 2 comments · Fixed by #6

Comments

@catwell
Copy link
Contributor

catwell commented Jul 2, 2013

Cosmo is broken with lpeg 0.12. This stacktrace use LuaJIT but the problem also happens with PUC Lua.

loop body may accept empty string
stack traceback:
    [C]: at 0x7fa6d89eca20
    [C]: in function 'match'
    /usr/local/share/lua/5.1/re.lua:208: in function 'new'
    /usr/local/share/lua/5.1/cosmo/grammar.lua:166: in main chunk
    [C]: in function 'require'
    /usr/local/share/lua/5.1/cosmo.lua:3: in main chunk
    [C]: in function 'require'
    stdin:1: in main chunk
    [C]: at 0x00405010
@h4rm
Copy link

h4rm commented Aug 13, 2013

I got the same issue here. Looked into the re.lua and it is something with this piece of code, starting at line 170 - 183 in re.lua:

Suffix = m.Cf(m.V"Primary" * S *
          ( ( m.P"+" * m.Cc(1, mt.__pow)
            + m.P"*" * m.Cc(0, mt.__pow)
            + m.P"?" * m.Cc(-1, mt.__pow)
            + "^" * ( m.Cg(num * m.Cc(mult))
                    + m.Cg(m.C(m.S"+-" * m.R"09"^1) * m.Cc(mt.__pow))
                    )
            + "->" * S * ( m.Cg((String + num) * m.Cc(mt.__div))
                         + m.P"{}" * m.Cc(nil, m.Ct)
                         + m.Cg(Def / getdef * m.Cc(mt.__div))
                         )
            + "=>" * S * m.Cg(Def / getdef * m.Cc(m.Cmt))
            ) * S
          )^0

@catwell
Copy link
Contributor Author

catwell commented Sep 19, 2013

I asked about this on the Lua mailing list. Here's what Tom Harris answered:

The problem is the construction

local longstring = #("[" * lpeg.S"[=") * (longstring1 + longstring2)

longstring1 is fine, but longstring2 is a match-time-capture that consumes an
unknown amount of input. Although the function will match a long string or
fail, the compiler doesn't know that and assumes it will match with no input.

I changed Cosmo's longstring pattern to this from the LPEG manual

local ls_equals = lpeg.P'='^0
local ls_open = '[' * lpeg.Cg(ls_equals, "init") * '['
local ls_close = ']' * lpeg.C(ls_equals) * ']'
local ls_closeeq = lpeg.Cmt(ls_close * lpeg.Cb("init"),
      function (s, i, a, b)
        return a == b
      end)
longstring = ls_open * (lpeg.P(1) - ls_closeeq)^0 * ls_close / 1

And deleted the old longstring, longstring1, longstring2, start_ls, and start.
It compiles without error, though I haven't tested if it still matches
correctly.

Then Roberto Ierusalimschy wrote:

A less intrusive change is to change only longstring2 itself:

local longstring2 = lpeg.Cmt(start, function (s, i, start)
  local p = string.gsub(start, "%[", "]")
  local _, e = string.find(s, p, i)
  return (e and e + 1)
end)

(Many thanks to Tom for doing the hard part.)

I will test his solution and submit a pull request asap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants