On Jun 27, Luke Palmer said:
>Jeff 'japhy' Pinyan writes:
>> I am currently completing work on an extensible regex-specific parsing
>> module, Regexp::Parser. It should appear on CPAN by early July
>> (hopefully under my *new* CPAN ID "JAPHY").
>>
>> Once it is completed, I will be starting work on writing a subclass
>> that matches Perl 6 regexes, Regexp::Perl6 (or Perl6::Regexp, or
>> Perl6::Regexp::Parser).
>
>Or Regexp::Parser::Perl6 :-)
I wasn't sure where in the hierarchy of modules it should go.
>The grammar for Perl 6 is going to be specified with Perl 6 patterns.
>That presents us a little bootstrapping problem. So the original goal
>of Damian's Perl6::Rules was to transform this grammar back into Perl 5
>patterns so they can parse the simplified Perl 6 code for Perl 6 and
>compile a bootstrap.
>
>My personal, nondivine plan would be to use your module to create a
>driver-based parser. That could then be used for the bootstrap instead.
If you mean what I think you mean by driver-based, than my module is a
perfect fit. To subclass it, you do this:
package Regexp::NoCode;
use base 'Regexp::Parser';
sub init {
my $self = shift;
$self->SUPER::init();
$self->del_handler('(?{');
$self->del_handler('(??{');
$self->del_handler('(?p{');
}
1;
Now you have a parser that refuses to acknowledge (?{ ... }) and (??{ ...
}) assertions (resulting in an error).
Another example would be to support the '&' metacharacter, which is the
"AND" equivalent of '|':
package Regexp::AndBranch;
use base 'Regexp::Parser';
sub init {
my $self = shift;
$self->SUPER::init();
$self->add_handler('&' => sub {
my ($S) = @_;
return $S->object('and');
});
}
Then you create Regexp::AndBranch::and like so:
package Regexp::AndBranch::and;
@ISA = Regexp::Parser::or; # it behaves like an 'or' branch...
sub new {
my ($class, $rx, $lhs, $rhs) = @_;
my $self = bless {
rx => $rx,
flags => $rx->{flags}[-1],
class => 'branch',
type => 'and',
data => [$lhs, $rhs],
raw => '&',
}, $class;
return $self;
}
It'll inherit the other methods it needs from the 'or' class. Then, when
you want to convert it to an existing construct (specifically, /x&y&z/
would become /(?=x)(?=y)z/, like in vim).
>A driver-based parser has a couple of advantages over regexes and even
>Parse::RecDescent. First, the parsing algorithm can be easily
>customized, so we can play with hybrid models and see how the time
>complexity works out. Also, you can suspend the parsing in the middle
>of execution, go somewhere else, and continue, which the Perl 6 parser
>might just want to do (something like simulated coroutines).
Yeah, you can parse node-by-node:
my $p = Regexp::Parser->new($regex);
while (my $n = $p->next) {
# ...
}
When I finish writing it to work with the current set, I'll post it to
CPAN and alert the group.
--
Jeff "japhy" Pinyan [EMAIL PROTECTED] http://www.pobox.com/~japhy/
RPI Acacia brother #734 http://www.perlmonks.org/ http://www.cpan.org/
CPAN ID: PINYAN [Need a programmer? If you like my work, let me know.]
<stu> what does y/// stand for? <tenderpuss> why, yansliterate of course.