2009-07-26 3 views
1

Perl을 사용하여 Gmail에서 제공 한 것과 유사한 검색 문자열을 구문 분석하고 싶습니다. 입력 예는 "tag : thing by : {user1 user2} {-tag : a by : user3}"입니다. AND 연산자로 공간 기본적으로 분리Gmail 스타일의 고급 검색 구문 구문 분석

  1. 토큰 : 나는 같은

    {and => [ 
        "tag:thing", 
        {or => [ 
         "by:user1", 
         "by:user2", 
        ]}, 
        {or => [ 
         {not => "tag:a"}, 
         "by:user3", 
        ]}, 
    } 
    

    일반적인 규칙은, 트리 구조로 넣어 싶습니다.

  2. 중괄호 안에있는 토큰은 대체 옵션 (OR)입니다. 중괄호는 필드 지정자 앞이나 뒤에 올 수 있습니다. 즉 "by : {user1 user2}"및 "{by : user1 by : user2}"는 동일합니다.
  3. 하이픈으로 시작하는 토큰은 제외됩니다.

이러한 요소는 결합 및 중첩 될 수도 있습니다. "{by : user5 - {tag : k by : user3}} etc".

나는이 규칙을 표현하기 위해 문맥 자유 문법을 작성한 다음이를 나무로 파싱 할 생각이다. 이건 불필요한가요? (간단한 regexps를 사용하면 가능합니까?)

구문없는 문법을 구문 분석 할 때 어떤 모듈을 사용 하시길 권장합니까?

는 (결국이 DBIx :: 클래스와 함께 데이터베이스 쿼리를 생성하는 데 사용됩니다.)

답변

1

는 정규식 아주 잘 (괄호 등) 중첩 된 일을하지 않습니다. 정규식 계산 괄호와 올바르게 캡쳐 할 때쯤에는 CFG 파서를 사용할 수 있습니다. CFG는 논리적으로 올바른 구문 분석을 보장 할 수 있지만 정규식 솔루션을 사용하면 많은 마법을 벗어날 수 있습니다. 나는 Perl CFG 라이브러리를 추천 할 수는 없지만 코딩은 매우 카타르시스 적이다.

+0

감사합니다. CFG 사용에 대한 설득력있는 논의입니다. 나는 또한 실제로 어떤 모듈을 사용해야하는지에 대한 권장 사항을 필요로한다. –

+0

신경 쓰지 마라. 나는 Parse :: RecDescent가 종종 추천되는 것으로 보인다. 잘 작동한다. –

+0

Perl 5.10은 내포 된 것들을 아주 잘 처리합니다. 그렇다고 올바른 솔루션이라는 것을 의미하지는 않습니다. –

0

쿼리가 트리 구조가 아닌 경우 regexes가 작업을 수행합니다. 예를 들어

:

my $search = "tag:thing by:{user1 user2} {-tag:a by:user3}" 
my @tokens = split /(?![^{]*})\s+/, $search; 
foreach (@tokens) { 
    my $or = s/[{}]//g; # OR mode 
    my ($default_field_specifier) = /(\w+):/; 
} 

쿼리 구조화 나무하더라도, 정규 표현식에 재귀 구문 분석이 훨씬 더 쾌적한 수 있습니다

$_ = "by:{user1 z:{user2 3} } x {-tag:a by:user3} zz"; 
pos($_) = 0; 
scan_query(""); 

sub scan_query { 
    my $default_specifier = shift; 
    while (/\G\s*((?:[-\w:]+)|(?={))({)?/gc) { 
     scan_query($1), next if $2; 
     my $query_token = $default_specifier . $1; 
    } 
    /\G\s*\}/gc; 
} 

정규 표현식에 끝내 :)입니다!

+0

중괄호와 연산자도 중첩 될 수 있습니다. 이것을 반영하기 위해 편집 된 질문. –

0

YAPP 원하는대로 할 수 있습니다. 이것을 사용하여 LALR (1) 구문 분석 자동화를 생성하고 사용할 수 있습니다.

0

Parse::Recdescent은 이런 종류의 일을위한 파서를 생성 할 수 있습니다. 파서를 효과적으로 사용하려면 파서에 대한 경험이 필요합니다.

관련 문제