use v6-alpha; # Pure-Perl6 implementation of the 'Rule' syntax # author: Flavio S. Glock - fglock@gmail.com # This is for demonstation only, it currently can't be run by # Pugs::Compiler::Rule runtime grammar Pugs::Grammar::Rule; our %rule_terms; our %variables; token pod_begin { | \n =end \N* | . \N* } token pod_other { | \n =cut \N* | . \N* } token ws { [ | \# \N* | \n [ = [ | begin END \N* .* | begin | kwid | pod | for | head1 ]? ]? | \s ]+ } # regex ident can start with a number token ident { [ | _ | <'::'> ]+ } token literal { [ | \\ . | <-[ \' ]> ]* } token metasyntax { [ | \\ . | \' \' | \{ \} | \< \> | <-[ \> ]> ]+ { return { metasyntax => $$/ ,} } } token string_code { # bootstrap "code" [ | \\ . | \' \' | \{ \} | <-[ \} ]> ]+ } token parsed_code { # this subrule is overridden inside the perl6 compiler { return '{' ~ $/ ~ '}' } } token named_capture_body { | \( \) { return { capturing_group => $$ ,} } | \[ \] { return $$ } | \< \> { return $$ } | { die "invalid alias syntax" } } %variables = ( '$<' => token { \> { return { match_variable => '$' ~ $/ ,} } }, '$' => token { + { return { match_variable => '$' ~ $/ ,} } | \^? [ | _ | \: \: ]+ { return { variable => '$' ~ $/ ,} } }, '@' => token { + { return { match_variable => '@' ~ $/ ,} } | \^? [ | _ | \: \: ]+ { return { variable => '@' ~ $/ ,} } }, '%' => token { + { return { match_variable => '%' ~ $/ ,} } | \^? [ | _ | \: \: ]+ { return { variable => '%' ~ $/ ,} } }, ); # /%variables %rule_terms = ( '(' => token { \) { return { capturing_group => $$ ,} } }, '<(' => token { <')>'> { return { capture_as_result => $$ ,} } }, ' token { \> { return { after => :$$, } } }, ' token { \> { return { before => :$$, } } }, ' token { \> { return { not_before => :$$, } } }, ' token { \> { return { negate => :$$, } } }, '<' => token { \> { return $$ } }, '{' => token { \} { return { closure => $$ ,} } }, '\\' => token { . { return { special_char => '\\' ~ $/ , } } }, '.' => token { { return { 'dot' => 1 ,} } }, '[' => token { \] { return $$ } }, ':::' => token { { return { colon => ':::' ,} } }, ':?' => token { { return { colon => ':?' ,} } }, ':+' => token { { return { colon => ':+' ,} } }, '::' => token { { return { colon => '::' ,} } }, ':' => token { { return { colon => ':' ,} } }, '$$' => token { { return { colon => '$$' ,} } }, '$' => token { { return { colon => '$' ,} } }, '^^' => token { { return { colon => '^^' ,} } }, '^' => token { { return { colon => '^' ,} } }, ':i' => token { { return { modifier => 'ignorecase' ,} } }, ':ignorecase' => token { { return { modifier => 'ignorecase' ,} } }, ':s' => token { { return { modifier => 'sigspace' ,} } }, ':sigspace' => token { { return { modifier => 'sigspace' ,} } }, ':P5' => token { { return { modifier => 'Perl5' ,} } }, ':Perl5' => token { { return { modifier => 'Perl5' ,} } }, ':bytes' => token { { return { modifier => 'bytes' ,} } }, ':codes' => token { { return { modifier => 'codes' ,} } }, ':graphs' => token { { return { modifier => 'graphs' ,} } }, ':langs' => token { { return { modifier => 'langs' ,} } }, ); # /%rule_terms token term { | <%Pugs::Grammar::Rule::variables> [ ? <':='> ? { return { named_capture => { rule => $$, ident => $$, }, }; } | { return $$ } ] | <%Pugs::Grammar::Rule::rule_terms> { #print "term: ", Dumper( $_[0]->data ); return $$ } | <-[ \] \} \) \> \: \? \+ \* \| \& ]> { #print "constant: ", Dumper( $_[0]->data ); return { 'constant' => $$/ ,} } } token quant { | <'**'> ? \{ \} { return { closure => $$ ,} } | <[ \? \* \+ ]>? } token quantifier { $ := (?) ]> > $ := (?) $ := (<[ \? \+ ]>?) $ := (?) { return { quant => { term => $$/{'term'}, quant => $$/{'quant'}, greedy => $$/{'greedy'}, ws1 => $$/{'ws1'}, ws2 => $$/{'ws2'}, ws3 => $$/{'ws3'}, } } } } token concat { + { my $a = $.map( { $$_ } ); return { concat => $a ,} if $a.elems > 1; return $a[0]; } } token rule { [ ? \| ]? [ \| ]* { my $a = $.map( { $$_ } ); return { alt => $a ,} if $a.elems > 1; return $a[0]; } }