Re: Autotrees !!

[email protected] (Damian Conway)
Newsgroups perl.recdescent
Message-ID <[email protected]>
Jeffrey asked:

        > Is there an example of an OO processor that handles the parse
        > tree that autotree produces?

I have a few, two of which I've appended below. I'll add them into the next
distribution too.

Damian

-----------cut-----------cut-----------cut-----------cut-----------cut----------

#! /usr/local/bin/perl -sw

# PARSE AND EVALUATE LOGICAL EXPRESSIONS WITH A AUTOGENERATED OO PARSE TREE

use Parse::RecDescent;
use Data::Dumper;

my $parse = Parse::RecDescent->new(<<'EOG');

<autotree>
        expr    :       set | clear | disj
        set     :       'set' atom
        clear   :       'clear' atom
        disj    :       <leftop: conj 'or' conj>
                                { bless $item[-1], $item[0] }
        conj    :       <leftop: unary 'and' unary>
                                { bless $item[-1], $item[0] }
        unary   :       neg | bracket | atom
        bracket :       '(' expr ')'
        neg     :       'not' unary
        atom    :       /[a-z]+/i
EOG

while (<>)
{
        my $tree = $parse->expr($_);
        print Data::Dumper->Dump([$tree]);
        print $tree->eval(), "\n" if $tree;
}

BEGIN {@var{qw(a c e)} = (1,1,1);}

sub returning
{
         # local $^W;
         # print +(caller(1))[3], " returning ($_[0])\n";
        $_[0];
}

sub expr::eval     { my $type = $_[0]->{set}||$_[0]->{clear}||$_[0]->{disj};
                     returning $type->eval() }
sub disj::eval     { returning join '', map {$_->eval()} @{$_[0]} }
sub conj::eval     { returning ! join '', map {! $_->eval()} @{$_[0]} }
sub unary::eval    { my $type = $_[0]->{neg}||$_[0]->{bracket}||$_[0]->{atom};
                     returning $type->eval() }
sub bracket::eval  { returning $_[0]->{expr}->eval() }
sub neg::eval      { returning ! $_[0]->{unary}->eval() }
sub set::eval      { returning $::var{$_[0]->{atom}->name()} = 1 }
sub clear::eval    { returning $::var{$_[0]->{atom}->name()} = 0 }
sub atom::eval     { returning $::var{$_[0]->{__VALUE__}} }
sub atom::name     { returning $_[0]->{__VALUE__} }

-----------cut-----------cut-----------cut-----------cut-----------cut----------

#! /usr/local/bin/perl -w

use Parse::RecDescent;

# $RD_TRACE = 1;

my $parser = Parse::RecDescent->new(<<'EOGRAMMAR');

<autotree>

        file:           element(s)

        element:        command | literal

        command:        '\\' literal options(?) args(?)

        options:        '[' option(s? /,/) ']'
        
        args:           '{' element(s?) '}'

        option:         /[^][\\$&%#_{}~^ \t\n,]+/

        literal:        /[^][\\$&%#_{}~^ \t\n]+/


EOGRAMMAR


local $/;
my $tree = $parser->file(<DATA>);

use AutoDump;
#show $tree;

$tree->explain(0);

sub file::explain
{
        my ($self, $level) = @_;
        for (@{$self->{element}})
        {
                $_->explain($level);
                print "\n";
        }
}

sub element::explain
{
        my ($self, $level) = @_;
        ($self->{command}||$self->{literal})->explain($level)
}

sub command::explain
{
        my ($self, $level) = @_;
        print "\t"x$level, "Command: $self->{literal}{__VALUE__}\n";
        print "\t"x$level, "\tOptions:\n";
        $self->{options}[0]->explain($level+2) if @{$self->{options}};
        print "\t"x$level, "\tArgs:\n";
        $self->{args}[0]->explain($level+2) if @{$self->{args}};
}

sub options::explain
{
        my ($self, $level) = @_;
        $_->explain($level) foreach @{$self->{__DIRECTIVE1__}};
}

sub args::explain
{
        my ($self, $level) = @_;
        $_->explain($level) foreach @{$self->{element}};
}


sub option::explain
{
        my ($self, $level) = @_;
        print "\t"x$level, "Option: $self->{__VALUE__}\n";
}

sub literal::explain
{
        my ($self, $level) = @_;
        print "\t"x$level, "Literal: $self->{__VALUE__}\n";
}


__DATA__

\documentclass[a4paper,11pt]{article}
\usepackage{latexsym}
\author{D. Conway}
\title{Parsing \LaTeX{}}
\begin{document}
\maketitle
\tableofcontents
\section{Description}
...is easy \footnote{But not \emph{necessarily} simple}.
\end{document}

-----------cut-----------cut-----------cut-----------cut-----------cut----------
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.