On Monday, Jun 9, 2003 "h. w. neff" said: > ok, i now have a much pared down example that exhibits the > problem -- at least with attempts to use '<<' in an exe > block.
<blessedly snipped> Wow. If that was "pared down" I would hate to see "the whole script" :-) This one is kind of subtle, and reminds me of the quote "nothing can parse perl except perl". The problem is in Text::Balanced::_match_quotelike where it thinks the '<<' is a hereis operator instead of a shift and tries to process it like a quoting operator. Since nothing follows the '<<' that really corresponds to a label, it looks for "" instead. See Text::Balanced::_match_quotelike starting at line 714: if ($op eq '<<') { $ld1pos = pos($$textref); my $label; if ($$textref =~ m{\G([A-Za-z_]\w*)}gc) { $label = $1; } elsif ($$textref =~ m{ \G ' ([^'\\]* (?:\\.[^'\\]*)*) ' | \G " ([^"\\]* (?:\\.[^"\\]*)*) " | \G ` ([^`\\]* (?:\\.[^`\\]*)*) ` }gcx) { $label = $+; } else { $label = ""; } What happens is that $label is being set to null so the quote terminator is looking for a BLANK LINE. Here is a much simpler test case which fails. use Parse::RecDescent; use Data::Dumper; $::RD_ERRORS = 1; # Make sure the parser dies when it encounters an error $::RD_WARN = 1; # Enable warnings. This will warn on unused rules &c. $::RD_HINT = 1; # Give out hints to help fix problems. $::RD_TRACE=100; $mach_grammar = q { acu_config_cmd : ';' { $main::Instruction_lower = 0x000000 | (($item[16] & 0x000003)<<10) ; 1; } }; my $mach_parser = new Parse::RecDescent ($mach_grammar); Where it outputs the following: Parse::RecDescent: Treating "acu_config_cmd :" as a rule declaration Parse::RecDescent: Treating ";" as a literal terminal printing code (3612) to RD_TRACE But this works: use Parse::RecDescent; use Data::Dumper; $::RD_ERRORS = 1; # Make sure the parser dies when it encounters an error $::RD_WARN = 1; # Enable warnings. This will warn on unused rules &c. $::RD_HINT = 1; # Give out hints to help fix problems. $::RD_TRACE=100; $mach_grammar = q { acu_config_cmd : ';' { $main::Instruction_lower = 0x000000 | (($item[16] & 0x000003)<<10) ; 1; } }; my $mach_parser = new Parse::RecDescent ($mach_grammar); Now PAY ATTENTION: The only difference between the two cases is the *BLANK* line after the expression with the '<<' in it!!!! Yet this works and correctly picks up the action: Parse::RecDescent: Treating "acu_config_cmd :" as a rule declaration Parse::RecDescent: Treating ";" as a literal terminal Parse::RecDescent: Treating "{ $main::Instruction_lower = 0x000000 | (($item[16] & 0x000003)<<10) ; 1; }" as an action printing code (4229) to RD_TRACE The reason for the bug is that it consumes the entire input and the parser fails in a bizarre way that makes it think everything after the '<<' is part of that hereis literal. So to fake it out, give it what it wants, which is a blank line after every usage of the '<<' shift operator, but you have to do it INSIDE the action. The original code had the blank line after the action and the parser parser looses it mind. So with your original code, change it to this: acu_config_cmd : bus0_p_see_clause { $main::LastSuccess = "a bus0 'ptr see clause'"; $main::LookingFor = "a comma and a bus0 'update clause'"; } bus0_update_clause { $main::LastSuccess = "a bus0 'update clause'"; $main::LookingFor = "a comma'"; } ',' { $main::LastSuccess = "a comma"; $main::LookingFor = "a bus1 'ptr see clause'"; } bus1_p_see_clause <commit> { $main::LastSuccess = "a bus1 'ptr see clause'"; $main::LookingFor = "a comma and a bus1 'update clause'"; } bus1_update_clause { $main::LastSuccess = "a bus1 'update clause'"; $main::LookingFor = "a comma'"; } ',' { $main::LastSuccess = "a comma"; $main::LookingFor = "a bus2 'ptr see clause'"; } bus2_p_see_clause { $main::LastSuccess = "a bus2 'ptr see clause'"; $main::LookingFor = "a comma and a bus2 'update clause'"; } bus2_update_clause { $main::LastSuccess = "a bus2 'update clause'"; $main::LookingFor = "a comma'"; } ',' { $main::LastSuccess = "a comma"; $main::LookingFor = "a bus3 'ptr see clause'"; } bus3_p_see_clause { $main::LastSuccess = "a bus3 'ptr see clause'"; $main::LookingFor = "a comma and a bus3 'update clause'"; } bus3_update_clause { $main::LastSuccess = "a bus3 'update clause'"; $main::LookingFor = "a comma'"; } ',' { $main::LastSuccess = "a comma"; $main::LookingFor = "a sm_b0123 'see clause'"; } sm_b0123_see_clause { $main::LastSuccess = "a sm_b0123 'see clause'"; $main::LookingFor = "a semicolon"; } ';' { $main::Instruction_upper = 0x400000 | ($item[1] / 16) | ($item[7] / 2) | ($item[14] / 512) | ($item[20] / 64) | ($item[26] & 0x00000F) ; $main::Instruction_lower = 0x000000 | ($item[3] / 2048) | ($item[10] / 128) | (($item[16] & 0xC00000) / 16384) # | (($item[16] & 0x000003) * 1024) | (($item[16] & 0x000003) << 10) | (($item[22] & 0xC00000) / 1024) | (($item[22] & 0x000003) * 16384) | ($item[26] & 0xFF0000) ;# the next blank line is required. 1; } Yep, its just PFM. -- Intel, Corp. 5000 W. Chandler Blvd. Chandler, AZ 85226 -- Intel, Corp. 5000 W. Chandler Blvd. Chandler, AZ 85226