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


Reply via email to