package Pugs::Runtime::Grammar; use strict; use warnings; use metaclass; use Pugs::Compiler::Rule; #our $VERSION ='0.01'; # stash the metaclass for the package # that we store the grammer in __PACKAGE__->meta->add_attribute('$:pkg_meta' => ( reader => '_pkg_meta', init_arg => 'pkg_meta' )); # keep the rules handy in a local hash __PACKAGE__->meta->add_attribute('%:rules' => ( reader => 'rules', default => sub { {} }, )); sub new { my ($class, $name, $version) = @_; # create the package to hold the my $meta = Class::MOP::Class->create($name, $version); my $self = $class->meta->new_object(pkg_meta => $meta); $meta->add_method('grammar' => sub { $self }); return $self; } sub add_rule { my ($self, $rule_name, $rule) = @_; # try to compile the rule first ... my $compiled_rule = eval { Pugs::Compiler::Rule->compile( $rule ) }; die "Could not compile rule ($rule_name) because : $@" if $@; # add the compiled rule to our local stash $self->rules->{$rule_name} = $compiled_rule; # but put the .code version of it into the package $self->_pkg_meta->add_method($rule_name, sub { $compiled_rule }); } 1; __END__ =pod =head1 NAME Pugs::Runtime::Grammar =head1 SYNOPSIS my $grammar = Pugs::Runtime::Grammar->new('Foo'); $grammar->add_rule(bar => '((.).).'); # or Foo->grammar->add_rule(bar => '((.).).'); my $match = Foo->bar->match( 'abc' ); if ($match) { # true print $match; # "abc" print $match->from; # 0 print $match->to; # 3 print $match->[0]; # "ab" print $match->[0][0]; # "a" } =head1 DESCRIPTION =head1 AUTHORS The Pugs Team Eperl6-compiler@perl.orgE. =head1 SEE ALSO The Perl 6 Rules Spec: L =head1 COPYRIGHT Copyright 2006 by Stevan Little and others. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L =cut