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