2

I'm working on a Parse::RecDescent grammar to read a given human-readable set of rules and then spit out a file that is much easier for a computer to read.

One of the tokens is a list of "keywords"; about 26 different keywords. These may change over time, and may be referenced by multiple pieces of code. Consequently, I want to store the keyword-y things in a data file and load them in.

A feature of Parse::RecDescent is the ability to interpolate variables in regexes, and I would like to use it.

I wrote up some code as a proof of concept:

@arr = ("foo", "bar", "frank", "jim");


$data = <<SOMEDATA;
This is some data with the word foo in it
SOMEDATA

$arrstr = join("|", @arr);

if($data =~ /($arrstr)/)
{
    print "Matched $1\n";
}
else
{
    print "Failed to match\n";
}

This worked correctly. When I moved to my main program to implement it, I wrote:

{
    my $myerror = open(FILE, "data.txt") or die("Failed to open data");
    my @data_arr = <FILE>;
    close FILE;
    my $dataarrstr = join("|", @data_arr);

}
#many rules having nothing to do with the data array are here...

event : /($dataarrstr)/
    { $return = $item[1]; }
    | 

And at this point, I received this error from P::RD: ERROR (line 18): Invalid event: Was expecting /($dataarrstr)/.

I don't know why. Does anyone have any ideas that would serve to help me out here?

edit: This is not a scoping issue- I've tried that. I've also tried the m{...} syntax.

1 Answer 1

3

After perusing documentation and a very similar question over at http://perlmonks.org/?node_id=384098, I worked out this solution.

event :/\w+/
    {
        $return = ::is_valid_event($item[1]);
    }
    | <error>

Outside the grammar -

#This manages the problem of not being able to interpolate the variable 
#in the grammar action
sub is_valid_event {
    my $word = shift @_;
    if($word =~ /$::data_str/)
    {
        return $word;
    }
    else
    {
        return undef;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.