Интерполяция переменных в регулярном выражении Parse::RecDescent
Я работаю над грамматикой Parse::RecDescent, чтобы прочитать заданный человеком понятный набор правил, а затем выложить файл, который намного легче читать компьютеру.
Одним из токенов является список "ключевых слов"; около 26 разных ключевых слов. Они могут изменяться со временем, и на них могут ссылаться несколько фрагментов кода. Следовательно, я хочу сохранить ключевые слова в файле данных и загрузить их в.
Особенностью 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{...}.
1 ответ
После изучения документации и очень похожего вопроса на 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;
}
}