Today I started the process of making Parsec a valid Rules engine, due the the whitespace boundary (<ws>) handling required to distinguish these two forms:
if %ENV{'PATH'} { 'foo' } # one "if" statement
if %ENV {'PATH'} { 'foo' } # two statements: "if" and bare-block 'foo'
This is because whitespace is never allowed before postfix operators in Perl 6, and we rely on this property to avoid infinite lookaheads for cases like "$x < 3" versus "$x<3>".
I went for the most convenient approach, namely keeping a UserState of the character class of the previous Char -- \s, \w, or others. It works as expected, but makes parsing 30% slower again, completely offsetting the gain of conversion to predictive parsing. I'll run some profiles and see if I can optimize it back to speed. I also added a UserState for offset, for .from/.to support. (Previously it only maintains lines and column numbers.)
The next step would be add UserState of the current named/positional captures, and then change the result type to from "a" to "Match a", then voila -- we'll have a Rules engine. scw (recently resurfaced on #perl6) offered to write a MiniPerl6-to-Haskell compiler, so we can have a shared Perl 6 grammar and the AST production rules for Perl 6, and translate them into Perl5/Parrot/Haskell as needed.
I also pointed spinclad to the optable.c skeleton, in the hope that the three implementations -- each have an operator precendence parser, none of which particularly fast -- can share a stable, C-based implementation. My C-fu is weak, so I'm glad to see interest on that front. :-)
In other news, particle has been populating the Parrot/Perl6 tree with symbolic and named builtin prototypes, imported from Pugs's primitives table, so unary and nullary functions can start to parse properly. Yay!
Comments
You can follow this conversation by subscribing to the comment feed for this post.