use v6-alpha; grammar MiniPerl6::Grammar { use MiniPerl6::Grammar::Regex; use MiniPerl6::Grammar::Mapping; use MiniPerl6::Grammar::Control; # XXX - move to v6.pm emitter #sub array($data) { use v5; @$data; use v6; } my $Class_name; # for diagnostic messages sub get_class_name { $Class_name } token ident_digit { [ [ | _ | ] | '' ] } token ident { [ | _ ] } token full_ident { [ <'::'> | '' ] } token to_line_end { | \N | '' } token pod_begin { | \n <'=end'> | . } token pod_other { | \n <'=cut'> | . } token ws { [ | <'#'> | \n [ | <'=begin'> | <'=kwid'> | <'=pod'> | <'=for'> | <'=head1'> | '' ] | \s ] [ | '' ] } token opt_ws { | '' } token opt_ws2 { | '' } token opt_ws3 { | '' } token parse { | [ | { return [ $$, @( $$ ) ] } | { return [ $$ ] } ] | { return [] } } token comp_unit { [\; | '' ] [ <'use'> <'v6-'> \; | '' ] [ <'class'> | <'grammar'> ] <'{'> { $Class_name := ~$ } <'}'> [\; | '' ] { return ::CompUnit( 'name' => $$, 'attributes' => { }, 'methods' => { }, 'body' => $$, ) } } token infix_op { <'+'> | <'-'> | <'*'> | <'/'> | eq | ne | <'=='> | <'!='> | <'&&'> | <'||'> | <'~~'> | <'~'> } token hyper_op { <'>>'> | '' } token prefix_op { [ <'$'> | <'@'> | <'%'> | <'?'> | <'!'> | <'++'> | <'--'> | <'+'> | <'-'> | <'~'> ] | <'$'> > } token declarator { <'my'> | <'state'> | <'has'> } token exp2 { { return $$ } } token exp_stmts2 { { return $$ } } } #---- split into compilation units in order to use less RAM... grammar MiniPerl6::Grammar { token exp { # { say 'exp: going to match at ', $/.to; } [ <'??'> [ <'!!'> { return ::Apply( 'code' => 'ternary:', 'arguments' => [ $$, $$, $$ ], ) } | { say '*** Syntax error in ternary operation' } ] | { return ::Apply( 'code' => 'infix:<' ~ $ ~ '>', 'arguments' => [ $$, $$ ], ) } | <':='> { return ::Bind( 'parameters' => $$, 'arguments' => $$) } | { return $$ } ] } token opt_ident { | { return $$ } | '' { return 'postcircumfix:<( )>' } } token term_meth { [ \. [ \( \) # { say 'found parameter list: ', $.perl } | \: | { return ::Call( 'invocant' => ::Proto( 'name' => ~$ ), 'method' => $$, 'arguments' => undef, 'hyper' => $$, ) } ] { return ::Call( 'invocant' => ::Proto( 'name' => ~$ ), 'method' => $$, 'arguments' => $$, 'hyper' => $$, ) } ] | [ \. # $obj.(42) [ \( # { say 'testing exp_seq at ', $/.to } \) # { say 'found parameter list: ', $.perl } | \: | { return ::Call( 'invocant' => $$, 'method' => $$, 'arguments' => undef, 'hyper' => $$, ) } ] { return ::Call( 'invocant' => $$, 'method' => $$, 'arguments' => $$, 'hyper' => $$, ) } | \[ \] { return ::Index( 'obj' => $$, 'index' => $$ ) } # $a[exp] | \{ \} { return ::Lookup( 'obj' => $$, 'index' => $$ ) } # $a{exp} | { return $$ } ] } token sub_or_method_name { [ \. | '' ] } token opt_type { | [ <'::'> | '' ] { return $$ } | '' { return '' } } token term { | { return $$ } # $variable | { return ::Apply( 'code' => 'prefix:<' ~ $ ~ '>', 'arguments' => [ $$ ], ) } | \( \) { return $$ } # ( exp ) | \{ \} { return ::Lit::Hash( 'hash' => $$ ) } # { exp => exp, ... } | \[ \] { return ::Lit::Array( 'array' => $$ ) } # [ exp, ... ] | \$ \< \> { return ::Lookup( 'obj' => ::Var( 'sigil' => '$', 'twigil' => '', 'name' => '/' ), 'index' => ::Val::Buf( 'buf' => $$ ) ) } # $ | do \{ \} { return ::Do( 'block' => $$ ) } # do { stmt; ... } | # my Int $variable { return ::Decl( 'decl' => $$, 'type' => $$, 'var' => $$ ) } | use [ - | '' ] { return ::Use( 'mod' => $$ ) } | { return $$ } # 'value' | { return $$ } # [literal construct] # | { return $$ } # $lhs := $rhs | { return $$ } # token { regex... } | { return $$ } # method { code... } | { return $$ } # sub { code... } | { return $$ } # Various control structures. Does _not_ appear in binding LHS # | # $obj[1, 2, 3] # | # $obj{'1', '2', '3'} | { return $$ } # self; print 1,2,3 } #token index { XXX } #token lookup { XXX } } #---- split into compilation units in order to use less RAM... grammar MiniPerl6::Grammar { token sigil { \$ |\% |\@ |\& } token twigil { [ \. | \! | \^ | \* ] | '' } token var_name { | <'/'> | } token var { { return ::Var( 'sigil' => ~$, 'twigil' => ~$, 'name' => ~$, ) } } token val { | { return $$ } # undef # | $ := # (not exposed to the outside) | { return $$ } # 123 | { return $$ } # True, False | { return $$ } # 123.456 | { return $$ } # 'moose' } token val_bit { | True { return ::Val::Bit( 'bit' => 1 ) } | False { return ::Val::Bit( 'bit' => 0 ) } } } #---- split into compilation units in order to use less RAM... grammar MiniPerl6::Grammar { token val_undef { undef { return ::Val::Undef( ) } } token val_num { XXX { return 'TODO: val_num' } } token double_quoted { | \\ . | . | '' } token single_quoted { | \\ . | . | '' } token digits { \d [ | '' ] } token val_buf { | \" \" { return ::Val::Buf( 'buf' => ~$ ) } | \' \' { return ::Val::Buf( 'buf' => ~$ ) } } token val_int { { return ::Val::Int( 'int' => ~$/ ) } } token exp_stmts { | [ | [ \; | '' ] [ \; | '' ] { return [ $$, @( $$ ) ] } | [ \; | '' ] { return [ $$ ] } ] | { return [] } } token exp_seq { | # { say 'exp_seq: matched ' } [ | \, [ \, | '' ] { return [ $$, @( $$ ) ] } | [ \, | '' ] { return [ $$ ] } ] | # { say 'exp_seq: end of match' } { return [] } } } #---- split into compilation units in order to use less RAM... grammar MiniPerl6::Grammar { token lit { #| { return $$ } # (a, b, c) #| { return $$ } # [a, b, c] #| { return $$ } # {a => x, b => y} #| { return $$ } # sub $x {...} | { return $$ } # ::Tree(a => x, b => y); } token lit_seq { XXX { return 'TODO: lit_seq' } } token lit_array { XXX { return 'TODO: lit_array' } } token lit_hash { XXX { return 'TODO: lit_hash' } } token lit_code { XXX { return 'TODO - Lit::Code' } } token lit_object { <'::'> \( [ \) { # say 'Parsing Lit::Object ', $$, ($$).perl; return ::Lit::Object( 'class' => $$, 'fields' => $$ ) } | { say '*** Syntax Error parsing Constructor'; die() } ] } token bind { <':='> { return ::Bind( 'parameters' => $$, 'arguments' => $$, ) } } token call { \. \( \) { return ::Call( 'invocant' => $$, 'method' => $$, 'arguments' => $$, ) } } token apply { [ [ \( \) | ] { return ::Apply( 'code' => $$, 'arguments' => $$, ) } | { return ::Apply( 'code' => $$, 'arguments' => [], ) } ] } token opt_name { | '' } token invocant { | \: { return $$ } | { return ::Var( 'sigil' => '$', 'twigil' => '', 'name' => 'self', ) } } token sig { # TODO - exp_seq / exp_mapping == positional / named { # say ' invocant: ', ($$).perl; # say ' positional: ', ($$).perl; return ::Sig( 'invocant' => $$, 'positional' => $$, 'named' => { } ); } } token method_sig { | \( \) { return $$ } | { return ::Sig( 'invocant' => ::Var( 'sigil' => '$', 'twigil' => '', 'name' => 'self' ), 'positional' => [ ], 'named' => { } ) } } token method { method \{ # { say ' parsing statement list ' } # { say ' got statement list ', ($$).perl } [ \} | { say '*** Syntax Error in method \'', get_class_name(), '.', $$, '\' near pos=', $/.to; die 'error in Block'; } ] { # say ' block: ', ($$).perl; return ::Method( 'name' => $$, 'sig' => $$, 'block' => $$ ); } } token sub { sub \{ [ \} | { say '*** Syntax Error in sub \'', $$, '\''; die 'error in Block'; } ] { return ::Sub( 'name' => $$, 'sig' => $$, 'block' => $$ ) } } } #---- split into compilation units in order to use less RAM... grammar MiniPerl6::Grammar { token token { # { say 'parsing Token' } token \{ \} { #say 'Token was compiled into: ', ($$).perl; my $source := 'method ' ~ $ ~ ' ( $grammar: $str, $pos ) { ' ~ 'my $MATCH; $MATCH := ::MiniPerl6::Perl5::Match( \'str\' => $str, \'from\' => $pos, \'to\' => $pos, \'bool\' => 1 ); ' ~ '$MATCH.bool( ' ~ ($$).emit ~ '); ' ~ 'return $MATCH }'; #say 'Intermediate code: ', $source; my $ast := MiniPerl6::Grammar.term( $source ); # say 'Intermediate ast: ', $$ast.emit; return $$ast; } } } =begin =head1 NAME MiniPerl6::Grammar - Grammar for MiniPerl6 =head1 SYNOPSIS my $match := $source.parse; ($$match).perl; # generated MiniPerl6 AST =head1 DESCRIPTION This module generates a syntax tree for the MiniPerl6 compiler. =head1 AUTHORS The Pugs Team Eperl6-compiler@perl.orgE. =head1 SEE ALSO The Perl 6 homepage at L. The Pugs homepage at L. =head1 COPYRIGHT Copyright 2006 by Flavio Soibelmann Glock, Audrey Tang and others. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L =end