2

私は Parse::RecDescent 文法に取り組んでおり、特定の人間が読める一連のルールを読み取り、コンピューターにとってはるかに読みやすいファイルを吐き出します。

トークンの 1 つは「キーワード」のリストです。約 26 の異なるキーワード。これらは時間の経過とともに変化する可能性があり、複数のコードによって参照される可能性があります。したがって、キーワードのようなものをデータ ファイルに保存してロードしたいと考えています。

Parse::RecDescent の機能の 1 つは、正規表現で変数を補間する機能であり、私はそれを使用したいと考えています。

概念実証としていくつかのコードを書きました。

@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";
}

これは正しく機能しました。それを実装するためにメインプログラムに移動したとき、私は次のように書きました。

{
    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]; }
    | 

この時点で、 P::RD: からこのエラーを受け取りましたERROR (line 18): Invalid event: Was expecting /($dataarrstr)/

どうしてか分かりません。ここで私を助けるのに役立つアイデアはありますか?

編集:これはスコープの問題ではありません-私はそれを試しました. m{...} 構文も試しました。

4

1 に答える 1

3

http://perlmonks.org/?node_id=384098でドキュメントと非常によく似た質問を熟読した後、私はこの解決策を考え出しました。

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

文法の外 -

#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;
    }
}
于 2009-06-09T18:33:16.520 に答える