# Perl6 implementation of the 'Term' syntax category # author: Flavio S. Glock - fglock@gmail.com use v6-alpha; grammar Pugs::Grammar::Perl6 does Pugs::Grammar::BaseCategory; use Pugs::Compiler::Rule; use Pugs::Runtime::Match; use Pugs::Grammar::StatementControl; use Pugs::Grammar::StatementModifier; use Pugs::Grammar::Expression; use Pugs::Grammar::Pod; use Pugs::Grammar::P6Rule; token perl6_expression_or_null { { return $/{'Pugs::Grammar::Expression.parse'}() } | { return { null => 1, } } } token block { \{ ? ? \} { #print "matched block\n", Dumper( $/{statements}->data ); return { bare_block => $/{statements}(), } } | \{ ? \} { return { bare_block => { statements => [] } } } | <'->'> [ ? ? \{ ? ? \} { return { pointy_block => $/{statements}(), signature => $/{signature_no_invocant}(), } } | ? \{ ? ? \} { return { pointy_block => $/{statements}(), signature => undef, } } ] } token attribute { (+) ( [|_|\\:\\:]+) [ { return [ [ { bareword => $/[0]() }, { bareword => $/[1]() } ], @{$()}, ] } | { return [[ { bareword => $/[0]() }, { bareword => $/[1]() } ]] } ] | (\\:+) [ ? { return [ [ { bareword => $/[0]() }, { num => 1 } ], @{$()}, ] } | { return [[ { bareword => $/[0]() }, { num => 1 } ]] } ] | { return [] } } # Str|Num token signature_term_type { [ ? \| ? { return { op1 => '|', exp1 => $/{'Pugs::Grammar::Term.bare_ident'}(), exp2 => $(), } } | { return $/{'Pugs::Grammar::Term.bare_ident'}() } ] | { return undef } } token signature_term_ident { # XXX t/subroutines/multidimensional_arglists.t \\@ ; { return { die => "not implemented" } } | ( ( <'$'>|<'%'>|<'@'>|<'&'> ) ) { return $/[0]() } } token signature_term { : ? (<':'>?) (<'*'>?) (<'?'>?) (? <'='> )? ? { return { default => $/[3] ? $/[3][0]{'Pugs::Grammar::Expression.parse'}() : undef, type => $/{signature_term_type}(), name => $/{signature_term_ident}(), attribute => $/{attribute}(), named_only => $/[0](), is_slurpy => $/[1](), optional => $/[2](), } } } token signature_no_invocant { [ ? <','> ? { return [ $/{signature_term}(), @{$/{signature_no_invocant}()}, ] } | { return [ $/{signature_term}() ] } ] | { return [] } } token signature { ? <':'> [ ? { return [ { %{$/{signature_term}()}, invocant => 1, }, @{$/{signature_no_invocant}()}, ] } | { return [ { %{$/{signature_term}()}, invocant => 1, }, ] } ] | { return $/{signature_no_invocant}() } } token category_name { [ <':'> [ <%Pugs::Grammar::Term::hash> { return { category => $/{'Pugs::Grammar::Term.bare_ident'}(), name => { 'exp1' => { 'hash' => '%::_V6_GRAMMAR::' . $/{'Pugs::Grammar::Term.bare_ident'}(), }, 'exp2' => $/{'Pugs::Grammar::Term::hash'} ()->{bare_block}, 'fixity' => 'postcircumfix', 'op1' => { 'op' => '{' }, 'op2' => { 'op' => '}' }, } } } | # <%Pugs::Grammar::Quote::hash> { return { category => $/{'Pugs::Grammar::Term.bare_ident'}(), name => { 'exp1' => { 'hash' => '%::_V6_GRAMMAR::' . $/{'Pugs::Grammar::Term.bare_ident'}(), }, 'exp2' => $/{'Pugs::Grammar::Quote::hash'}(), 'fixity' => 'postcircumfix', 'op1' => { 'op' => '<' }, 'op2' => { 'op' => '>' }, } } } ] | { return { category => '', name => $/{'Pugs::Grammar::Term.bare_ident'}(), } } ] | { return { category => '', name => '', } } } token sub_signature { <'('> ? ? <')'> { #print "sig ", Dumper( $/{signature}() ); return $/{signature}() } | { return [] } } token sub_decl { [ ( multi | ) ? ( submethod | method | sub ) ? | ( multi ) ? ( ) ] ? ? ? { return { multi => $/[0](), term => $/[1]() || 'sub', category => $/{category_name}()->{category}, name => $/{category_name}()->{name}, attribute => $/{attribute}(), signature => $/{sub_signature}(), block => $/{block}(), } } } token rule_decl { ( multi | ) ? ( rule | regex | token ) ? ? ? ? <'{'> ? [ ? <'}'> { return { multi => $/[0](), term => $/[1](), category => $/{category_name}()->{category}, name => $/{category_name}()->{name}, attribute => $/{attribute}(), signature => $/{sub_signature}(), # pass the match tree to the emitter block => $/{'Pugs::Grammar::P6Rule.rule'}(), } } | # XXX better error messages { return { die "invalid rule syntax" } } ] } # class token class_decl_name { ( class | grammar | module | role | package ) ? ( | | ) { return { statement => $/[0](), name => $/[1](), } } } token class_decl { ? ? ? { #print "matched block\n", Dumper( $/{block}[0]->data ); return { term => $/{class_decl_name}()->{statement}, name => $/{class_decl_name}()->{name}, attribute => $/{attribute}(), block => defined $/{block}[0] ? $/{block}[0]() : undef , } } } # /class token statement { { return $/->{'Pugs::Grammar::StatementControl.parse'}(); } | { return $/{'Pugs::Grammar::Expression.parse'}(); } } token statements { [ ; ? ]* [ > { $::_V6_SUCCEED = 0 } | ? [ ; ? ]* [ > { $::_V6_SUCCEED = 0 } | { return { statements => [ $/{statement}(), @{ $/{statements}()->{statements} }, ] } } | { return { statements => [ $/{statement}() ], } } ] ] } token parse { ? ? { return $/{statements}() } }