lua-users home
lua-l archive

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


It was thus said that the Great Jonathan Goble once stated:
> 
> While I have no objection to including LPeg with the standard Lua
> distribution, I would strongly object to having it replace the current
> patterns. The beauty of the current patterns is their simplicity and easy
> learning curve. I find neither to be true about LPeg. I've tried to use
> LPeg a few times, and I find it to be confusing and not at all intuitive.
> In part, the use of single letters for function names leaves me scratching
> my head, and I can never remember what operators mean what. 

  The more you work with it, the easier it becomes.  I've found mnemonic
value in the function names (lpeg.S() defines a SET, lpeg.C() defines a
CAPURE) but yes, some of the functions can be a bit confusing (lpeg.Cf()
does a folding capture, and if you aren't familiar with folding in general,
then yes, it's confusing).

> LPeg is
> powerful, yes, so I can see how it is useful. But if added to the stock Lua
> distribution, it should be its own standard library module (preferably with
> longer and more descriptive function names), without replacing patterns.
> 
> Also, unless I misunderstood something or something has changed since I
> last looked at it, LPeg cannot do anything requiring backtracking, so there
> are things matchable by patterns but unmatchable by LPeg. Possible example
> being "capture the three characters between a question mark and a dollar
> sign, immediately before the dollar sign", for which the (untested) pattern
> "%?.-([^$][^$][^$])%$" should match easily, but AFAICT, there is no
> equivalent LPeg pattern since the only way is to match up to the $ and then
> back up three characters.

  Yes it can:

	qd = lpeg.P"?"    -- match the question mark
	   * lpeg.P(1)^3  -- at least three characters, could be more
	   * lpeg.Cmt(	  -- at match time
                  lpeg,P"$", -- when we hit the dollar sign, call this
                  function(subject,position)
	            -- position is one past the dollar sign,
	            -- so we return the three characters prior to the 
	            -- dollar sign (position-4 to position-2 of subject)
 	            return position,subject:sub(position-4,position-2)
	          end
	     )

does it quite nicely.  LPeg functions used:

	lpeg.P"string"	- match literal string
	lpeg.P(n)	- match n arbitrary characters
	lpeg.Cmt(patt,func)
			- when matched given pattern, call the function
			  given with the entire input string, the position
			  past the match.  The first return determines how
			  LPeg continues, and in this case, we return the
			  current position to continue parsing (position
			  unchanged)---additional values are returned as the
			  capture.
	patt^n		- match pattern at least n times
	patt1 * patt2	- match pattern1 AND pattern 2

  -spc (It only looks longer because of the comments)