へんてこへんすう

Parse::RecDescentを継承したパーサーで$::RD_AUTOACTIONとかつかうとgdgdになるので、
サランラップする必要がある。使いづらいので、ベストプラクティスな実装にしてほしい。

package OreOre::Parse;

use base qw/Parse::RecDescent/;

sub _nextnamespace()
{
    return "Parse::RecDescent::" . $nextnamespace++;
}

sub new ($$$$)
{
    my $class = ref($_[0]) || $_[0];
        local $Parse::RecDescent::compiling = $_[2];
        my $name_space_name = defined $_[3]
        ? "Parse::RecDescent::".$_[3]
        : _nextnamespace();
    my $self =
    {
        "rules"     => {},
        "namespace" => $name_space_name,
        "startcode" => '',
        "localvars" => '',
        "_AUTOACTION" => undef,
        "_AUTOTREE"   => undef,
    };
    if ($_[4])
    {
        my $sourcecode = $_[4];
        $sourcecode = "{ $sourcecode }"
            unless $sourcecode =~ /\A\s*\{.*\}\s*\Z/;
        $self->{_check}{itempos} =
            $sourcecode =~ /\@itempos\b|\$itempos\s*\[/;
        $self->{_AUTOACTION}
            = new Parse::RecDescent::Action($sourcecode,0,-1)
    }

    bless $self, $class;
    shift;
    return $self->Replace(@_)
}

1;