# Usage: perl compile_p6grammar.pl GrammarFile.pm > GrammarFile.pmc # The .pm file is in Perl 6 syntax # The .pmc file is in Perl 5 Pugs::Compiler::Rule syntax # TODO - in order to Grammar.pm to self-compile: # unshift @rule_terms, 'dot'; package Pugs::Compiler::Grammar; use Pugs::Compiler::Rule; use Pugs::Compiler::Token; use Pugs::Compiler::Regex; use base 'Pugs::Grammar::Base'; *pod = Pugs::Compiler::Token->compile(q( \= <'cut'> \N* [\n|$] | \N* [ $ | \n ] ))->code; # space, comments or pod *ws = Pugs::Compiler::Token->compile(q( [ \# \N* [\n|$] | [^|\n] \= \N* [\n|$] | \s ]* ))->code; *grammar_name = Pugs::Compiler::Token->compile(q( [ \w | \d | \: ]+ ))->code; *rule_name = Pugs::Compiler::Token->compile(q( \w+ ))->code; *block = Pugs::Compiler::Token->compile(q( \{ [ | <-[}]> | \\\\\} ]* \} ))->code; *mod = Pugs::Compiler::Token->compile(q( \: { return $ . " => 1" } ))->code; *rule = Pugs::Compiler::Rule->compile(q(<'rule'> * { my $body = substr($, 1, -1); my $mod = $[0] ? ", { " . join(", ", @{$}) . " }" : ""; $body =~ s/\\\\/\\\\\\\\/g; # duplicate every single backslashes return "*" . $ . " = Pugs::Compiler::Rule->compile(q(" . $body . ")$mod)->code;" } ))->code; *token = Pugs::Compiler::Rule->compile(q(<'token'> * { my $body = substr($, 1, -1); my $mod = $[0] ? ", { " . join(", ", @{$}) . " }" : ""; $body =~ s/\\\\/\\\\\\\\/g; # duplicate every single backslashes return "*" . $ . " = Pugs::Compiler::Token->compile(q(" . $body . ")$mod)->code;" } ))->code; *regex = Pugs::Compiler::Rule->compile(q(<'regex'> * { my $body = substr($, 1, -1); my $mod = $[0] ? ", { " . join(", ", @{$}) . " }" : ""; $body =~ s/\\\\/\\\\\\\\/g; # duplicate every single backslashes return "*" . $ . " = Pugs::Compiler::Regex->compile(q(" . $body . ")$mod)->code;" } ))->code; *grammar = Pugs::Compiler::Rule->compile(q( <'grammar'> \;[ [||]]* { return "package $\n" . "use Pugs::Compiler::Rule;\n" . "use Pugs::Compiler::Token;\n" . "use Pugs::Compiler::Regex;\n" . "use base 'Pugs::Grammar::Base';\n" . "use Pugs::Runtime::Match::Ratchet; # overload doesn't work without this ???\n\n" . join("\n", ( map { "$_" } @{$}, map { "$_" } @{$}, map { "$_" } @{$}, )) . "\n" }))->code; package main; use IO::File; use Pugs::Runtime::Match::Ratchet; my $source_file = shift(@ARGV); my $source = slurp($source_file); my $match = Pugs::Compiler::Grammar->grammar($source); print "$match"; sub slurp { my $fh = IO::File->new(shift) || return; return join('', $fh->getlines); } __END__ =head1 NAME compile_p6grammar.pl - Compile Perl6 Grammars to Perl5 Modules =head1 SYNOPSIS # The .pm file is in Perl 6 syntax # The .pmc file is in Perl 5 Pugs::Compiler::Rule syntax perl compile_p6grammar.pl GrammarFile.pm > GrammarFile.pmc =head1 DESCRIPTION Used to convert grammars in Perl 6 syntax into Perl 5 modules. =head1 AUTHORS The Pugs Team Eperl6-compiler@perl.orgE. =head1 SEE ALSO The Perl 6 Rules Spec: L =head1 COPYRIGHT Copyright 2006 by Nathan Gray. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L =cut