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 Dirk Laurie once stated:
> I define a function to be used with LPEG that simply returns the first
> character. It _cannot_ match the empty string:
> 
> function fct(str)
>   if #str==0 then return false
>   else return 2,str:sub(1,1)
>   end
> end

The manual states:

	lpeg.P (value)

		...

		If the argument is a function, returns a pattern equivalent
		to a match-time capture over the empty string.

And for the match-time capture:

	lpeg.Cmt(patt, function)

		Creates a match-time capture. Unlike all other captures,
		this one is evaluated immediately when a match occurs. It
		forces the immediate evaluation of all its nested captures
		and then calls function.

		The given function gets as arguments the entire subject, the
		current position (after the match of patt), plus any capture
		values produced by patt.

So the function should be:

	function fct(subject,position,capture)
	  if #subject == 0 then
	    return false
	  else
	    return position,subject:sub(position-1,position-1)
	  end
	end

> I turn it into an LPEG pattern:
> 
> lpeg.version() --> 1.0.0
> patt=lpeg.P(fct)

  You aren't giving it any pattern to match, so I suspect it's the same as
if you did:

	patt = lpeg.Cmt(lpeg.P"" * fct)

> "patt" is supposed to do exactly the same as lepg.C(1). It works OK on its own:
>   patt:match""  --> nil
>   patt:match"abc" --> a
> 
> But I can't make it match twice:
>   (patt*patt):match"abc" --> a a [expected: a b]

  Because the pattern, the empty string, is being matched twice by the two
calls.  If you change it to:

	patt = lpeg.P(lpeg.P(1) * fct)

it will work.

> This seems to contradict the manual's statement that: "If the call
> returns a number, the match succeeds and the returned number becomes
> the new current position."

  Also, your original code is always returning the first character,
regardless of where the match happens.

  -spc