Let's say you want to write a yacc grammar to parse Perl 6, or
Parse::RecDescent, or whatever you're going to use.  Yes, that will be
hard in Perl 6.  Certainly harder than it was in Perl 5.

In the end, I concluded there was _no_ way to write even a Perl 5 parser using any sort of pre-rolled grammar system, as the language does not have that sort of structure.


PPI was done "the hard way". Manually stepping through line by line and using a variety of cruft (some stolen from the perl source, some my own) to make it "just work".

I would envisage that the same would be true of writing a PPI6, except with a hell of a lot more operators :)

However, Perl 6 comes packaged with its own grammar, in Perl's own rule
format.  So now the quote "only perl can parse Perl" may become "only
Perl can parse Perl"  (And even "only Perl can parse perl", since it's
written in itself :-).

Perl's contextual sensitivity is part of the language.  So the best you
can do is to track everything like you mentioned.  It's going to be
impossible to parse Perl without having perl around to do it for you.
>
But using the built-in grammar, you can read in a program, macros and
all, and get an annotated source tree back, that you could rebuild the
source out of.

Again, this is of very little use, effectively destroying the source code and replacing it with different source that is a serialised version of the tree.


For a current notional example, it would be like loading a simple...

try {
  $object->$do_something;
} catch (Exception $problem) {
  handle($problem);
}

... changing ->$do_something to ->$do_something() to make it back-portable, and then ending up with...

Module::Exceptions::initialize('line 98');
my $exceptionhandler = Module::Exceptions::prepare();
eval {
  $exceptionhandler->update_status('in try');
  $object->do_something();
};
if ( $@ ) {
  if ( ref $exceptionhandler ) {
    require Scalar::Util ();
    if ( Scalar::Util::blessed $exceptionhandler eq 'Exception' ) {
      do {
        my $problem = $exceptionhandler->fetch_exception_as('$problem');

        # handler starts here
        handler($problem);

        $problem->clean_up;
      };
    }
  } else {
    # Just die as normal
    die $@;
  }
}

While technically they may be identical once they get through the parser and into tree form, trying to changing ->$do_something to ->$do_something() and getting back some huge monster chunk of code you didn't expect is definitely not what the intent of parsing it in the first place was.

This is what I am talking about when I refer to the "Frontpage" effect, the habit Micrsoft's HTML editor (especially the early versions) had of reuilding you HTML document from scratch, deleting all your template variables and PHP code and generally making it impossible to write HTML by hand. For HTML where you arn't MEANT to be writing stuff by hand under normal circumstances that wasn't always a problem, but perl _isi_ meant to be written by hand.

> You could even grab the comments and do something sick
with them (see Damian :-).  Or better yet, do something that PPI
doesn't, and add some sub call around all statements, or determine the
meaning of brackets in a particular context.

The question of whether to execute BEGIN blocks is a tricky one.
Sometimes they change the parse of the program. Sometimes they do other
stuff.  All you can hope for is that people understand the difference
between BEGIN (change parsing) and INIT (do before the program starts).

Frankly that is a gaping security hole... not only do I have to still deal with the problem of loading every single dependency or having no parsing ability otherwise, but I am required to "trust" every perl programmer on the planet :(


I love PPI, by the way :-)

Thank you, I do to :)

But I'd like to still have something like it in perl6 :(

Adam

Reply via email to