2009-06-09 4 views
2

저는 사람이 읽을 수있는 규칙을 읽고 컴퓨터에서 읽을 때 훨씬 쉬운 파일을 추출하기 위해 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 {...} 구문을 시도했습니다.

답변

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>