lua-users home
lua-l archive

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


Bravo, Roberto.

Lpeg is an useful and undeniably elegant addition to lua.
That said, I've got a few comments:

1) This pattern causes an infinite loop.  And while I understand
   why it does, it might be useful to either detect infinite loops
   or to disallow exponentiation on lookahead patterns:

   m.match( "asdf", (-m.P("x"))^0)

2) Documentation suggestion #0

   How about a table summarizing the operators as follows:

   Operator    Precedence      Description
   --------    ----------      -----------
   e^n         4               repetition
                                n>=0: n or more
                                n<0:  n at most
   #e          3               Positive lookahead (never consumes characters)
   -e          3               Negative lookahead (never consumes characters)
   e1 * e2     2               Sequence
   e1 + e2     1               Prioritized Choice

3) Documentation suggestion #1

   function anywhere (p)
     return (1 - lpeg.P(p))^0 * lpeg.I() * p * lpeg.I()
   end

   should perhaps instead be:

   function anywhere (p)
     local I = lpeg.I()
     return (1 - p)^0 * I * p * I
   end

4) Documentation suggestion #2

   Consider this example:

     assert( m.match("foo123", m.R("a","z")^0) == 4 )
     assert( string.sub("foo123", 4 ) == "123" )

   The return value is the index in the string _after_ the match.
   So perhaps this sentence:

   "If the match succeeds, returns the index in the subject where
    the match finished."

   should perhaps instead be:

   "If the match succeeds, returns the index in the subject of the
    first character after match."

5) Documentation suggestion #3

  The following note in the documentation is misleading:

  "(Maybe the # should be used for optional pattern; it seems to be
   more useful, and it has no symbol for it right now. We must write
   patt + "".)"

   But optional patterns _can_ be elegantly specified (with p^-1).

   If anything, #patt can be replaced with -(-patt), which currently
   works just fine.

   Alternatively, it might be worth adding lpeg.pos(patt) and lpeg.neg(patt)

6) Documentation suggestion #4

   Typo in "where the math occurs"

7) The "green" library re.lua has a bug in the following:

   re.match("parens don't work", "(.)")

   This can be fixed by changing the definition of expression() from

        local function expression (t) ... end
   to
        expression = function(t) ... end

   since it is already declared local.

8) A suggestion for test.lua:

   Negative numbers can be trivially handled in the evaluator:

        local Number = lpeg.C(lpeg.S("-")^-1 * lpeg.R("0", "9")^1) * Space


9) An implementation question/suggestion

   Since strings are hashed in lua, I don't understand why
   the optional capture name must be copied (670).  Seems to me
   that it would be more useful to allow any lua type
   (stored simply as a pointer).


That's it for now.  Thanks for a really interesting library
(and a great language as well!).

- Eric