Today I added two more rules in the default grammar, in addition to <p6rule>:
rule p6namedrule
{ rule \s+ ([\w|<'::'>]+) \s* \{ <p6rule> \} ;? \s* }
rule p6grammar
{ ^ grammar \s+ ([\w|<'::'>]+); \s* <p6namedrule>* $ }
With this, the PILN grammar is now successfully parsed with its Syntax.grammar file. To support that, tewk and I have implement various contructs:
- Enumerated character classes: <[abc]>
- Complemented character classes: <-[abc]>
- Literals: <'abc'>
- Begin/End anchors: ^ $ ^^ $$
- Partial parse of <p6rule> so it stops at the closing brace when used as part of <p6grammar>.
In addition to that, I've written a simple tree trasforming function for <p6grammar>, which takes a Match object and turns it into compiled rule expressions. Instead of using TGE-style separate set of attribute grammars as decribed in the Parrot compiler tools plan, I'm associating each rules with consumers, using e.g. SYB Generics to handle post-subrule-parsing production.
However, that scheme means we needed to perform multiple redundant traversals. I'd much rather something like this, with a conjectural :{} rule trait:
rule p6namedrule
:{ ($0 => $<p6rule>) }
{ rule \s+ ([\w|<'::'>]+) \s* \{ <p6rule> \} ;? \s* }
rule p6grammar
:{ Grammar.new(name => $0, rules => hash(@<p6namedrule>) }
{ ^ grammar \s+ ([\w|<'::'>]+); \s* <p6namedrule>* $ }
Some discussion on #perl6 ensued; luqui and I bounced some ideas about embedding attribute grammars into the rule declarations, and promptly went into tangents such as the evilness of keeping $! as global -- $!, $/ and $_ really should all be environmental -- expect some p6l threads about them in the near future...
Comments