2009-06-09 13 views
2

Ich arbeite an einer Parse :: RecDescent-Grammatik, um einen gegebenen menschenlesbaren Satz von Regeln zu lesen und dann eine Datei auszuspucken, die für einen Computer viel einfacher zu lesen ist.Variablen in einem Parse :: RecDescent-Regex interpolieren

Einer der Token ist eine Liste von "Schlüsselwörtern"; ungefähr 26 verschiedene Schlüsselwörter. Diese können sich im Laufe der Zeit ändern und können durch mehrere Codeabschnitte referenziert werden. Folglich möchte ich die Dinge mit dem Schlüsselwort y in einer Datendatei speichern und sie laden.

Eine Eigenschaft von Parse :: RecDescent ist die Fähigkeit, Variablen in Regexes zu interpolieren, und ich möchte es verwenden.

Ich schrieb einen Code als Proof of Concept up:

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

Diese richtig funktionierte. Als ich zu meinem Hauptprogramm bewegt, sie umzusetzen, schrieb ich:

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

Und an diesem Punkt, ich diesen Fehler von P erhalten :: RD: ERROR (line 18): Invalid event: Was expecting /($dataarrstr)/.

Ich weiß nicht warum. Hat jemand irgendwelche Ideen, die dazu dienen würden, mir hier zu helfen?

bearbeiten: Dies ist kein Scoping-Problem - das habe ich ausprobiert. Ich habe auch die m {...} Syntax ausprobiert.

Antwort

3

Nach Durcharbeiten der Dokumentation und einer sehr ähnlichen Frage über http://perlmonks.org/?node_id=384098 habe ich diese Lösung ausgearbeitet.

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

Außerhalb der Grammatik -

#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; 
    } 
} 
Verwandte Themen