in reply to Re: Goto with Parse::RecDescent
in thread Goto with Parse::RecDescent
use Parse::RecDescent; use vars qw(@lines $curline %stash); use strict; $RD_HINT++; $RD_WARN++; #$RD_TRACE++; sub do_print { my $a=shift; print "$a\n"; } sub do_goto { $curline = int(shift)-1; } my $grammar = q{ Start: Expression(s) /\Z/ Expression: LineNum Print { $::lines[int($item{LineNum})]= ["print", [$item{Print}]]; } | LineNum Goto { $::lines[int($item{LineNum})]= ["goto", [$item[2]]]; } | LineNum Ass | <error> Ass: StringAss | NumAss StringAss: Identifier /\$/ /=/ /\"/ String /\"/ { $::stash{$item{Identifier}}{type}="String"; $::stash{$item{Identifier}}{value}=$item{String}; } NumAss: Identifier /=/ Number { $::stash{$item{Identifier}}{type}="Number"; $::stash{$item{Identifier}}{value}=$item{Number}; } Goto: /goto/i LineNum Print: /print/i /\"/ String /\"/ { $item{String}; } | /print/i Identifier /\$/ { if(defined($::stash{$item{Identifier}}{value})) { $::stash{$item{Identifier}}{value}; } else {die "A nasty and horrible death... Bad string identifier.\n" +;} } | /print/i Identifier { if(defined($::stash{$item{Identifier}}{value})) { $::stash{$item{Identifier}}{value}; } else {die "A nasty and horrible death... Bad number identifier.\n" +;} } String: /[\w\s]+/ LineNum: /\d+/ Identifier: /[a-zA-Z][a-zA-Z0-9]*/ Number: /[+-]?\d+(\.\d+)?/ }; my $parser = new Parse::RecDescent($grammar); undef $/; my $text = <>; $parser->Start($text); $curline=0; while(1) { if($lines[$curline]) { my $todo = "do_".${$lines[$curline]}[0]."(\""; my $args = join(', ', @{${$lines[$curline]}[1]}); $todo = $todo.$args."\")"; eval $todo; } last if $curline>$#lines; $curline++; }
5 print "This " 10 print "is " 15 print "a " 20 print "test" 25 goto 5
5 a$ = "This is a string" 10 print a$ 15 b = 35 20 print b
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Re: Goto with Parse::RecDescent
by merlyn (Sage) on Jan 12, 2001 at 10:36 UTC |