Oh lord, there must be an easier way to do this in Parse::RecDescent, so why can't I see it? I think Merlyn's right - it's better to compile the data into another form rather then try to screw around with it on-the-fly.
What this does is save every line seen, and, when a GOTO is encountered, it's all pasted it all back into to top of $text (which holds the unparsed text.) There is no error checking to make sure the line to go to actually exists.
use Parse::RecDescent; $RD_HINT++; $RD_WARN++; my $grammar = q{ Start: Expression(s) /\Z/ Expression: LineNum Print { $thisparser->{_lines}->{$item[1]} = $item[1].' PRINT "'.$item[2] +.'"'; } | LineNum Goto { $text = $item[1] . " GOTO " . $item[2] . $text; foreach ( sort { $b <=> $a } grep { $_ >= $item[2] } keys %{$thi +sparser->{_lines}} ) { $text = $thisparser->{_lines}->{$_} . $text; } } | <error> Print: /print/i /\"/ /[\s\w]+/ /\"/ { print "$item[3]\n"; $item[3]; } Goto: /goto/i LineNum { $item[2]; # print "Seen a goto line $item[2]\n"; # How do I seek back to line $item[2] of # the input? } LineNum: /\d+/ }; my $parser = new Parse::RecDescent($grammar); undef $/; my $text = <DATA>; $parser->Start($text); __END__ 10 print "hello" 20 print "this" 30 print "is" 40 print "a" 50 print "test" 60 print "goodbye" 70 goto 30
There's a general method or something that I'm missing or have skipped over or have forgotten ...
In reply to Re: Goto with Parse::RecDescent
by eg
in thread Goto with Parse::RecDescent
by bent
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |