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 %{$thisparser->{_lines}} ) { $text = $thisparser->{_lines}->{$_} . $text; } } | 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 = ; $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