Page 1 of 2

Requesting LPEG

Posted: Mon May 10, 2010 8:37 pm
by WillFa
Lua Pattern Expression Grammars is another pattern system that lends itself really well to mudding.

Here's an introduction to LPEG by Roberto Ierusalimschy (the head Lua guy) which includes PCRE benchmarking (LPEG is generally faster in most mudding applications)

As for a more mud-centric information:

LPEG gives you much more control on data return than PCRE. Here's a comparison of using PCRE and Lua to disect my HP Bar.

Given Mudlet's Lua Function trigger pattern type. myLPEGpatt:match(line) is a natural application for such a feature.

Mudlet doesn't have a native speedwalker. Here's a single function I have written that mimics MushClient's speedwalking syntax. It'd be trivial to make a quick wrapper to do a SendAll(unpack(SplitSpeedwalk(mypath)) (minor caveat, you'd need to split (forward/back) special directions but thats' an easy change)

Re: Requesting LPEG

Posted: Mon May 10, 2010 11:22 pm
by Vadi
Mudlet does have a speedwalking function (don't think I documented it yet unfortunately, but you can find it on these forums)

As for your example, I'm not against LPEG, but you do know about Mudlets gates, filters and etc features? besides lua functions, it's a quite powerful tool and I'm sure you could just craft a trigger for that complicated prompt without making up one rather big pattern.

Re: Requesting LPEG

Posted: Mon May 10, 2010 11:39 pm
by robg
I find LPEG to be much more elegant than gates/chains etc.

I would support seeing it incorporated. People tend to fear it initially, but quickly come to realize many, many things are easily done using LPEG that would otherwise be unwieldly and annoying to maintain.

Re: Requesting LPEG

Posted: Tue May 11, 2010 12:23 am
by WillFa
Another example... In my finished Mushclient plugin, the lpeg behaves a bit more abstractly. The plugin checks the mud and gets the custom_hp variable in my guild which returns:

You have custom_hp set to: HP: &$HP2$& K: &$K2$& SP: &$SP2$& V:
@himagenta:&$V$&@%&$AS$& @hicyan:&$P$&@ @himagenta:&$C$&@ |
@yellow:&$G2S$&@@brown:/&$G2N$& (&$G2N%$&%)@

The lpeg grammar then parses that line with the knowledge of what each of those tokens are, and builds the grammar that will parse the actual combat output. I can then change what the mud sends me, and the client figures out what it's getting.

To my understanding, PCRE can't handle that because of too many forks, order is indeterminate, and so on.

Filters and gates won't work, because of indeterminate placement and optional information (like the @ansi:coloring@) and repeated information (again in coloring tokens.)

As someone that likes making plugins/packages for friends of varying skill levels, LPEG gives an exceptionally powerful tool that lets me make systems that self-configure. I can't imagine asking certain friends of mine to download, for example, a 3gb xcode package that takes up 5.3 gigs installed so they can figure out how to make a 38k .so for their OSX installation.

Re: Requesting LPEG

Posted: Tue May 11, 2010 12:45 am
by tsuujin
In fairness, I've used basic PCRE to parse complex, indeterminate strings by simply tokenizing and handling it outside of the regex.

I don't particularly feel the need to have EVERYTHING done INSIDE my pattern, which (from what I can tell) is what LPEG is trying to do.

Re: Requesting LPEG

Posted: Tue May 11, 2010 12:49 am
by Vadi
That's been the case with me as well, frankly. Some of the the more advanced processing I simply code in...

Can't think of reasons to ignore it though, so we'll think on it

Re: Requesting LPEG

Posted: Tue May 11, 2010 3:09 pm
by Denarii
Your real challenge is convincing Heiko that it's worth including. It took me a while to win him over to including PCRE. :p

Though if we did include it we might want to create a wrapper for it, the module's functions names are just awful.

It took me about 5 mins to build it for Windows, it shouldn't be hard to find someone willing to build it for OSX. I haven't used OSX for development, does it not come with gcc?

Re: Requesting LPEG

Posted: Tue May 11, 2010 5:04 pm
by Vadi
I'm sure ixokai could build it fine if we decide on it.

It doesn't come with gcc, the only way to get it is - as described - to get the rather heavy whole suite from apple.

Re: Requesting LPEG

Posted: Tue May 11, 2010 10:22 pm
by Heiko
I'm fine with including it - in fact I've thought about doing this for quite some time.

Re: Requesting LPEG

Posted: Wed May 12, 2010 5:38 am
by WillFa
Thank you, Heiko! :)

I'd like to chime in on the comments about making "the pattern do everything". LPEG is slightly different from what PCRE experts are used to dealing with...

With each line of text the mud sends you, you want to do three things to it:

1. Identify it.
2. Extract data from it.
3. Manipulate that data.

PCRE is perfect for identifying it, and does a competant job of extracting data. With PCRE, we're used to doing all of phase 1, identifying, with a pattern, and doing half of phase 2, extracting data because of captures. With LPEG, all of phase 1 and 2 is handled in the engine. How much more readable and maintainable do scripts and functions become when the first half of the function no longer is the cluttered busy work of pulling data from the matches table/collection and is just the pure logic of representing, determining state, or sending commands? Logically, there's not a lot of difference between a trigger chain matching " HP: ..." and a sub-trigger/leaf/node for the "[[ ]]" portion of the line. The main difference, for me, is that I can control an LPEG grammar with one keyboard, versus umpteen mouse clicks while traversing a chain in the GUI.

With LPEG, you wouldn't necessarily consume " HP: 50/100" and send whether or not to drink your healing potion, but you would make sure that the information is extracted, converted to the variable type you want (tonumber()), presented in a manner you want (myStats.HP.current) so that the logic in your functions reads much more cleanly. It shifts the code writing from the Trigger doing all of Phase 1 and half of Phase 2, and the Script action doing the other half of Phase 2 and all of Phase 3; to doing phases 1 and 2 completely. Since working with the data is typically more important than how we got it, Pattern Expression Grammars (pypeg, rubypeg, as well as lpeg) are great for dividing the work into more maintainable segments.