2011-05-16 5 views
3

저는 ANTLR을 처음 접했고 Lexer 및 Parser 규칙이 어떻게 작동하는지 이해하려고합니다. 필자는 필자가 작성한 문법에 문제가 있습니다. 처음 몇 개의 문자 만 실제로 일치하는 경우에도 여러 문자가 "일치"로 보이는 렉서 토큰과 관련이있는 것 같습니다.ANTLRv3 독서 옵션이 없음

apple basic say sponsor speeds speckled specific wonder 

내가 얻을 출력은 다음과 같습니다 :

apple basic say nsor ds led ic wonder 
나는 다음 테스트 입력을 구문 분석 AntlrWorks을 사용하고

grammar test; 
options { 
    k=3; 
} 

@lexer::header { package test;} 
@header {package test;} 

sentence : (CHARACTER)*; 

CHARACTER : 'a'..'z'|' '; 
SPECIAL  : 'special'; 

:이 문제를 설명하기 위해 간단한 ANTLR 3 문법을 작성했습니다

LEXER가 k = 1을 사용하고 있으므로 내 SPECIAL 토큰을 두 문자 'sp'가 포함 된 것으로 일치시키는 것으로 보입니다. 'sp'라는 문자를 만나면 실제 입력이 예상 토큰과 일치하지 않을 때까지 SPECIAL 리터럴 내에서 연속되는 문자를 찾습니다.이 때 (문자를 사용하는) 오류가 발생하고 나머지 문장이 계속됩니다 . 각 오류의 형식은 다음과 같습니다.

line 1:18 mismatched chracter 'o' expecting 'e' 

그러나 이것은 작성하려고하는 동작이 아닙니다. 이 테스트 예제에 포함되지 않은 다른 구문 분석기 규칙에 사용하기 위해 키워드 ('special')와 일치하는 렉서 토큰을 만들고 싶습니다. 실제로 같은 K와 같은 ANTLR 3 옵션 (설정하는 방법

  1. : 그러나, 나는 다른 규칙을 원하지 않는/단지 에 어떻게 입력 요약하면

    영향을받을 수 같은 초기 문자를 포함 = 2 또는 k = 3 등)? 적어도 여기서는 사용하려는 옵션이 설정되지 않은 것 같습니다.

  2. 완전한 일치를 포함하지 않는 입력의 다른 부분의 처리에 영향을주지 않으면 서 내 입력의 특정 키워드와 일치시키기 위해 구문 분석기 또는 렉서 규칙을 만드는 더 좋은 방법이 있습니까?
+0

ANTLRWorks 1.4.2에서 샘플을 실행하면 구문 분석이 잘되며 출력은 무엇입니까? –

+0

재미 있습니다. @Bas. 또한 ANTLRWorks 1.4.2 (일반적으로 IntelliJ 10.0.3에서 실행)를 사용하고 있습니다. 디버그 모드에서 나는 오류를 보여주는 "Output"탭을 가지고있다. 또한 구문 분석 트리 (Parse Tree 탭)를 검사하여 "spe .."비트가 삭제되는지 확인할 수 있습니다. 마찬가지로 "스택 탭"은 내 컴퓨터의 문제를 보여줍니다. 너는 문제를 보이지 않는가? ParseTree를 검사하고 "spec ..."문자로 시작하는 비트를 포함하여 전체 문장을 볼 수 있습니까? – Glennn

+0

예제 입력에서 문장 규칙을 실행할 때 구문 분석 트리를 생성하는 해석기 탭을 사용하고 있습니다. –

답변

4

options { ... } 섹션의 k 섹션은 렉서가 아닌 파서의 모양을 정의합니다. 문법

CHARACTER : 'a'..'z'|' '; 
SPECIAL  : 'special'; 

이 모호

참고 : 당신은 'special'도 7 'a'..'z' 년대로 간주 될 수 있습니다. 입력 구문 분석

grammar Test; 

sentence : (special | word | space)+ EOF; 
special : SPECIAL; 
word  : WORD; 
space : SPACE; 

SPECIAL : 'special'; 
WORD  : 'a'..'z'+; 
SPACE : ' '; 

: 같은

specia special specials 

은 다음과 같습니다

enter image description here

즉, 다음과 같이 일반적으로, 그것은 lexed 할 것 그것은 LL (1)과 "가장 긴 일치"의 조합으로 토큰 화됩니다 (어느 정도). 죄송합니다. 다소 모호합니다. 그러나 Definitive ANTLR Reference은이 사실을 정확히 설명하지 않습니다 (적어도 찾을 수는 없습니다 ...). 그러나 이것이 당신이 찾고있는 것이 아닐 수도 있다는 것을 알고 있습니다.

AFAIK, 단일 는 하나의 규칙이 두 토큰을 병합하여 수행됩니다, 이러한 단일 숯불 토큰에서 만든 키워드를 정의 숯불 토큰 및 사용 조건 및 수동 look-를 생산하는 유일한 방법 먼저 키워드가 키워드를 준수하는지 확인하고, 그렇지 않은 경우 'fall through'하위 규칙에서 토큰 유형을 변경하십시오. 당신이 볼 수 있듯이, 입력을 구문 분석 할 때

import org.antlr.runtime.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     ANTLRStringStream in = new ANTLRStringStream("apple basic special speckled keyword keywor"); 
     testLexer lexer = new testLexer(in); 
     CommonTokenStream tokens = new CommonTokenStream(lexer); 
     testParser parser = new testParser(tokens); 
     parser.sentence(); 
    } 
} 

: 다음

apple basic special speckled keyword keywor 

을 다음 데모는 :

grammar test; 

tokens { 
    LETTER; 
} 

@lexer::members { 
    // manual look ahead 
    private boolean ahead(String text) { 
    for(int i = 0; i < text.length(); i++) { 
     if(input.LA(i+1) != text.charAt(i)) { 
     return false; 
     } 
    } 
    return true; 
    } 
} 

sentence 
    : (t=. {System.out.printf("\%-7s :: '\%s'\n", tokenNames[$t.type], $t.text);})+ EOF 
    ; 

SPECIAL 
    : {ahead("special")}?=> 'special' 
    | {ahead("keyword")}?=> 'keyword' 
    | 'a'..'z' {$type = LETTER;} // Last option and no keyword is found: 
           // change the type of this token 
    ; 

SPACE 
    : ' ' 
    ; 

위의 문법에서 생성 된 파서는 클래스를 테스트 할 수 있습니다 출력이 생성됩니다 :

LETTER :: 'a' 
LETTER :: 'p' 
LETTER :: 'p' 
LETTER :: 'l' 
LETTER :: 'e' 
SPACE :: ' ' 
LETTER :: 'b' 
LETTER :: 'a' 
LETTER :: 's' 
LETTER :: 'i' 
LETTER :: 'c' 
SPACE :: ' ' 
SPECIAL :: 'special' 
SPACE :: ' ' 
LETTER :: 's' 
LETTER :: 'p' 
LETTER :: 'e' 
LETTER :: 'c' 
LETTER :: 'k' 
LETTER :: 'l' 
LETTER :: 'e' 
LETTER :: 'd' 
SPACE :: ' ' 
SPECIAL :: 'keyword' 
SPACE :: ' ' 
LETTER :: 'k' 
LETTER :: 'e' 
LETTER :: 'y' 
LETTER :: 'w' 
LETTER :: 'o' 
LETTER :: 'r' 

ANTLR의 술어에 대한 자세한 정보는 Q & A What is a 'semantic predicate' in ANTLR?을 참조하십시오.

+0

정말 대단한 답변입니다! – John

+0

고마워요 @ 바트. 매우 명확하고 유용한 답장! 대단히 감사합니다. – Glennn

+0

@ 존, 감사합니다! @ 글렌, 천만에요. –