Parse Trees

#!/opt/perl/bin/perl -w

use strict;

use Parse::RecDescent;

sub start::roll {
    my $self = shift;
    $self -> {die} -> roll;
}

sub die::roll {
    my $self = shift;
    my $sum  = 0;

    if ($self -> {count}) {
        foreach (1 .. $self -> {count} -> amount) {
            $sum += $self -> {faces} -> roll;
        }
    }
    else {
        $sum = $self -> {faces} -> roll;
    }

    $sum;
}

sub number::value {
    my $self = shift;
    $self -> {__VALUE__}
}

sub count::amount {
    my $self = shift;
    $self -> {number} -> value;
}

sub faces::roll {
    my $self = shift;
    1 + int rand $self -> {number} -> value;
}


my $grammar = <<'EOG';
<autotree>
start:        die  /^\Z/

die:          'd' faces
            | count 'd' faces

count:        number
faces:        number
number:       /\d+/
EOG

my $parser = Parse::RecDescent -> new ($grammar) or die "Failed to parse.\n";

while (<>) {
    chomp;
    my $val = $parser -> start ($_);
    next unless $val;
    foreach (1 .. 8) {
        print "$_: ", $val -> roll, "\n";
    }
}

__END__

3d4
1: 6
2: 6
3: 5
4: 8
5: 7
6: 8
7: 7
8: 10
d8
1: 3
2: 4
3: 4
4: 1
5: 2
6: 5
7: 4
8: 4

[Prev] [Next] [Index]