[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Any LPEG tutorial for laymen ?
- From: Andrew Starks <andrew.starks@...>
- Date: Tue, 24 Sep 2013 13:18:36 -0500
On Tue, Sep 24, 2013 at 9:50 AM, Jayanth Acharya <email@example.com> wrote:
> If someone can share 2 small illustrative examples of when to use which one,
> or why -- it'd be excellent. I know that I am perhaps asking for too much.
You're not asking too much, however 're' is a alternate dialect of the
same root library. IMHO, it appears to have been written to answer
expected critics of LPEG's more verbose style.
I use LPEG for effectively everything, using Lua's string matching
functions for only the most trivial purposes.
As you may be able to tell from searching for my previous posts to
this list, I'm not the most experienced developer in the world. :)
However, I was able to pick up LPEG to a point where I can now read
and use it very effectively. I got there by reading and referencing
its documentation. I've never been able to add to my understanding of
it through any other means, however, that might just be me.
What was especially helpful was to go through each example, writing it
for myself and not moving forward until I forced myself to understand
what was going on. Often, I had to go and poke around other written
papers, because I was unfamiliar with basic CSCI concepts (folding
grammars, for example). Once I had that context, Cg and Cf made more
Things that helped me understand it better were:
There are no magic characters (except for \n \t etc). It's easy to
read that in the documentation, but it's hard to grasp how profound
I'm most successful when I start with the tiniest patterns that I can
imagine, testing each one as I go, and then building up a solution
using all of those little blocks. When I started, that would mean
building up patterns from the most obvious elements. To illustrate,
here is a complete working example of a number and "formatted number"
local lpeg = require'lpeg'
local P, R, C = lpeg.P, lpeg.R, lpeg.C
local digit = R("09")
--without C (capture) the return values are the position after the last
--character in the match
print(digit:match("3"), digit:match("A")) --second one shouldn't match
local digits = digit^1
print(digits:match("1234"), digits:match("123 3"))
local unary_minus = P"-"
local space = P" "
local decimal_sep = P"."
print(unary_minus:match("-"), space:match(" "), decimal_sep:match("."))
--2 2 2
local integer = unary_minus^-1 * space^0 * digits
local mantissa = decimal_sep * digits
print(mantissa:match(".234"), mantissa:match(".")) --second one shouldn't match
local number = C(integer * mantissa^-1) * -1
--123 - 1.232
local seperator = P","
local formatted_integer = unary_minus^-1 *space^0 * digit^-3 *
(seperator * digit * digit * digit)^0
formatted_integer:match("1222,000")) --last two match until the format
--4 6 6 4
local formatted_number = C(formatted_integer * mantissa^-1 ) * -1
--the -1 will make the capture fail on invalid numbers
formatted_number:match("- 123,456.1234"), formatted_number:match("1,000."),
formatted_number:match("1234,000.0") -- last two fail
--10,000.3224 1,000.0 - 123,456.1234 nil nil
All of the examples in the documentation were gold to me. It might be
helpful for you if I rearrange their order in "hard - easy", the way I
1. Using a pattern
2. Searching for a pattern
3. Splitting a string
4. Global substitution
3. Balanced Parentheses
4. Comma-Separated Values (really, really helpful and once I got this,
I was able to be productive in LPEG)
5. Name-value lists (very difficult to grasp, for me)
6. Lua's long strings
7. Arithmetic expressions
(i didn't go through the UTF-8 examples, so I'm not sure where I would put them)
The Arithmetic expressions example is special, in that it's the only
one the details an actual grammar (Balanced Parentheses and the brief
example in Searching for a Pattern are too small to for me to say that
they "covered" it for me).
That's the best advice I can give, other than to say that the time I
spent learning LPEG was well worth it.