2009-06-09 9 views
2

私はParse :: RecDescentの文法を使って、人間が読める規則を読み込み、コンピュータが読むのがはるかに簡単なファイルを吐き出しています。Parse :: RecDescent正規表現での変数の補間

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

Parse :: RecDescentの機能は、正規表現で変数を補間する機能であり、これを使用したいと思います。

私はコンセプトの証明としていくつかのコードを書いた:

@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 {...}構文も試しました。

答えて

3

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

#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; 
    } 
} 
- 文法外

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