2010-08-02 9 views
4

사용자 입력 텍스트 인 검색 엔진 스타일을 해석하는 문법을 작성하려고합니다. AND, OR, NOT 및 ANDNOT 부울 연산자를 지원합니다. 거의 모든 작업을 수행 할 수 있지만 따옴표로 묶은 문자열 외부의 두 인접 키워드는 암시 적으로 AND 절에서와 같이 처리됩니다. 예를 들어 :ANTLR - 암시 적 토큰 및 토큰

치즈와 크래커 = 치즈와 크래커 (위 및 아래)

또는 (왼쪽 및 오른쪽) = (위, 아래) OR (왼쪽 및 오른쪽)

고양이 개 "배가 불룩한 돼지 "= 고양이와 개 그리고"도깨비 돼지 "

나는 마지막 하나에 문제가있어, 누군가가 올바른 방향으로 나를 가리킬 수 있기를 바랍니다. 여기 내 *의 · G 파일까지, 그리고 좋은 바랍니다, 내 ANTLR 경험 작업 일 미만에 걸쳐 : 당신 이후

grammar SearchEngine; 

options { language = CSharp2; output = AST; } 

@lexer::namespace { Demo.SearchEngine } 
@parser::namespace { Demo.SearchEngine } 

LPARENTHESIS : '('; 
RPARENTHESIS : ')'; 

AND : ('A'|'a')('N'|'n')('D'|'d'); 
OR  : ('O'|'o')('R'|'r'); 
ANDNOT : ('A'|'a')('N'|'n')('D'|'d')('N'|'n')('O'|'o')('T'|'t'); 
NOT : ('N'|'n')('O'|'o')('T'|'t'); 

fragment CHARACTER : ('a'..'z'|'A'..'Z'|'0'..'9'); 
fragment QUOTE  : ('"'); 
fragment SPACE  : (' '|'\n'|'\r'|'\t'|'\u000C'); 

WS  : (SPACE) { $channel=HIDDEN; }; 
PHRASE : (QUOTE)(CHARACTER)+((SPACE)+(CHARACTER)+)+(QUOTE); 
WORD : (CHARACTER)+; 

startExpression : andExpression; 
andExpression : andnotExpression (AND^ andnotExpression)*; 
andnotExpression : orExpression (ANDNOT^ orExpression)*; 
orExpression  : notExpression (OR^ notExpression)*; 
notExpression : (NOT^)? atomicExpression; 
atomicExpression : PHRASE | WORD | LPARENTHESIS! andExpression RPARENTHESIS!; 

답변

6

및 규칙은 선택과-키워드를 가지고, 당신은 가상의 앤을 만들어야합니다 토큰을 사용하고 재 작성 규칙을 사용하여 트리에 토큰을 "주입"하십시오. 이 경우 ANTLR의 단 축 ^ 루트 연산자를 사용할 수 없습니다. -> 다시 쓰기 연산자를 사용해야합니다.

귀하의 andExpression가 같아야합니다 : 하위 규칙, The Definitive ANTLR Reference의 페이지 173-174에 의해

이 (아마도 비밀) 표기법에 대한 자세한 설명은 제 7 장에 제시되어있다
andExpression 
    : (andnotExpression  -> andnotExpression) 
    (AND? a=andnotExpression -> ^(AndNode $andExpression $a))* 
    ; 

, 섹션 재 작성 규칙 테렌스 파.

문법이 새로운 andExpression 규칙을 사용하여 올바른 AST를 생성하는지 빠르게 테스트했습니다. AndNodeRootimaginary tokens을 것을

alt text http://img580.imageshack.us/img580/7370/andtree.png

참고 : 문자열 cat dog "potbelly and pig" and FOO를 분석 한 후, 생성 된 파서는 다음과 같은 AST를 생산했다. Visualizing an AST created with ANTLR (in a .Net environment)

편집

모두 one two three(one two) three을 구문 분석, 다음 AST가 만들어 :

이 스레드를, 위의 AST 사진 만들기를 참조하는 방법을 알고 싶다면

alt text http://img203.imageshack.us/img203/2558/69551879.png

(one two) OR three을 구문 분석 할 때 다음 AST는 생성 :

모든 경우에 적절한 방법이 될 것으로 보인다

alt text http://img340.imageshack.us/img340/8779/73390353.png

.

+0

감사! 그것은 트릭을했다. 내 후속 관심사 (현재 제거되고 편집자가 지시 한 내용)는 일부 C# 코드의 버그로 인해 발생했습니다. – user409108

+0

@highbeammeup, 듣기 좋게. 그리고 당신은 환영합니다! –

+0

@BartKiers Iam이 여기에 대한 참조를 가지고 있지만 다시 쓰기 규칙을 이해하는 데 문제가 있습니다. 왜 (...) (..) 부분이 필요하며 달러 운영자가하는 일을 설명해 주시겠습니까? –