in reply to Re: Parse::RecDescent precompiled grammar != interp'd
in thread Parse::RecDescent precompiled grammar != interp'd
correct output from fully interpreted version:
incorrect output from same input when using precompiled grammar:1: // test cases. 2: 3: // repeat instruction 4: [0000] 000000f70000 5: repeat = 0x0001; 6: repeat = 0x0002; [0001] 000000f70001 7: repeat = 0xfade; [0002] 000000f7fadd
at a high level, here is the bare bones of the code. first is the interpreted version, later is as changed for use with the precompiled grammar as a .pm file:1: // test cases. 2: INVALID INSTRUCTION DETECTED. I got as far as finding ...i had just started! (going for anything i might recognise) my last success ended at LINE 1 COL 1. You might have a look at that last line, or at this line: 3: // repeat instruction skip 1 address, try to continue... 3: // repeat instruction 4: 5: repeat = 0x0001; 6: repeat = 0x0002; [0001] 000000f70001 7: repeat = 0xfade; [0002] 000000f7fadd
ok, that was the interpreted, now for the precompiled:#interp'd $mach_grammar = q { [...grammar_contents...] } main { my $mach_parser = new Parse::RecDescent ($mach_grammar); #[...] defined $ns85_parser->program_body($src_code) or die "bad grammar!"; }
in more detail, below is substantially more of the code. the changes are, as noted, very small and a lot harder to see in it all. first is the interpreted version, later is as changed for use with the precompiled grammar as a .pm file. the debug option has been set in each case, so that internal test data is used and the input file (spec'd on the command line) is ignored.#precompiled use mach_grammar; main { my $mach_parser = mach_grammar->new(); #[...] defined $mach_parser->program_body($src_code) or die "bad grammar!"; }
and the precompiled usage has the grammar all off in another file, precompiled to mach_grammar.pm and the main code then looks like:#interp'd require "/usr/lib/perl5/5.6.1/getopts.pl"; #[...] our @prog_src; our $src_code; our $opt_i; use vars qw($opt_l); # L is used in actions inside the grammar # the machine has 48 bit instruction words, which are built up # in two halves. use vars qw($Instruction_upper); use vars qw($Instruction_lower); use vars qw($Instruction_address); use vars qw($LastPrintedLine); use vars qw($LineToPrint); use vars qw($LastSuccess); use vars qw($LookingFor); #[...] $mach_grammar = q { program_body : instruction(s) program_body { $return = 1; } | instruction { $return = 1; } | end_of_input { print sprintf "\nend of source at LINE %d\n", $thisline; exit; } | bad_instr : { print sprintf "\nINVALID INSTRUCTION DETECTED."; print sprintf "\n\n%s %s\n (%s %s)\n", "I got as far as finding", $main::LastSuccess, "going for", $main::LookingFor; $main::Instruction_address += 1; print sprintf "\nmy last success ended at LINE %d COL %d." +, $thisline, $thiscolumn; print sprintf "\nYou might have a look at that"; print sprintf "\n last line, or at this line:"; print "\n\n "; print sprintf "%d: %s", $main::LastPrintedLine + 2, @main::prog_src[$main::LastPrintedLine+1]; print sprintf "\nskip 1 address, try to continue...\n"; } <resync:[^;]*[;]> #[....major snippage...] hexval : /0x[0-9A-F]+/i { $return = hex $item[1]; 1; } }; # end of grammar # # main program follows # { my $mach_parser = new Parse::RecDescent ($mach_grammar); #[...] # acquire @prog_src if ($debug == 1) { @prog_src = <DATA> or die "ERROR: cannot read input data."; } else { # open the input file open(INFILE, "$opt_i") || die "ERROR: Cannot open $opt_i"; @prog_src = <INFILE> or die "ERROR: cannot read input file."; close(INFILE); } # # mash all the source together and remove all the newlines. # foreach (0 .. scalar(@prog_src) - 1) { $prog_src[@_] =~ s/\\r/\$\//g ; } push @prog_src, "\n__EOF__"; $src_code = join " ", @prog_src; defined $mach_parser->program_body($src_code) or die "bad grammar!"; } # # ****************************************************************** # main program section has ended, debug data section follows. # ****************************************************************** # __DATA__ // test cases. // repeat instruction repeat = 0x0001; repeat = 0x0002; repeat = 0xfade; //[...rest of test cases removed...] /* that's all folks.... */ __EOF__
require "/usr/lib/perl5/5.6.1/getopts.pl"; #[...] use mach_grammar; our @prog_src; our $src_code; our $opt_i; use vars qw($opt_l); # L is used in actions inside the grammar # the machine has 48 bit instruction words, which are built up # in two halves. use vars qw($Instruction_upper); use vars qw($Instruction_lower); use vars qw($Instruction_address); use vars qw($LastPrintedLine); use vars qw($LineToPrint); use vars qw($LastSuccess); use vars qw($LookingFor); # # main program follows # { my $mach_parser = mach_grammar->new(); #[...] # acquire @prog_src if ($debug == 1) { @prog_src = <DATA> or die "ERROR: cannot read input data."; } else { # open the input file open(INFILE, "$opt_i") || die "ERROR: Cannot open $opt_i"; @prog_src = <INFILE> or die "ERROR: cannot read input file."; close(INFILE); } # # mash all the source together and remove all the newlines. # foreach (0 .. scalar(@prog_src) - 1) { $prog_src[@_] =~ s/\\r/\$\//g ; } push @prog_src, "\n__EOF__"; $src_code = join " ", @prog_src; defined $mach_parser->program_body($src_code) or die "bad grammar!"; } # # ****************************************************************** # main program section has ended, debug data section follows. # ****************************************************************** # __DATA__ // test cases. // repeat instruction repeat = 0x0001; repeat = 0x0002; repeat = 0xfade; //[...rest of test cases removed...] /* that's all folks.... */ __EOF__
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Parse::RecDescent precompiled grammar != interp'd
by bear_hwn (Acolyte) on Jun 04, 2003 at 16:20 UTC |