2012-04-12 2 views
2

'^'와 '!'를 사용해야한다는 내용을 읽었습니다. 연산자를 사용하여 ANTLR Works에 표시된 트리와 유사한 구문 분석 트리를 작성합니다 (ANTLR Works에서 트리를 생성하는 데 사용할 필요는 없지만). 내 질문은 그런 나무를 어떻게 만들 수 있는가? 나는 두 사업자 및 재 작성을 사용하여 트리 구조에 몇 페이지를 볼 수, 아직 내가 입력 문자열 abc abc123과 문법을 가지고 있다고했습니다ANTLR Works 스타일 구문 분석 트리를 작성하려면 어떻게해야합니까?

grammar test; 

program : idList; 
idList : id* ; 
id : ID ; 

ID : LETTER (LETTER | NUMBER)* ; 
LETTER : 'a' .. 'z' | 'A' .. 'Z' ; 
NUMBER : '0' .. '9' ; 

ANTLR 작품의 출력 :

ANTLR Works Interpreter Output

내가 이해하지 못하는 것은 실제로이 문법뿐만 아니라이 트리의 맨 위에 'idList'노드를 얻을 수있는 방법입니다. 재 작성 및 해당 연산자를 사용하여이 트리를 어떻게 재현 할 수 있습니까?

답변

2

내가 이해하지 못하는 것은 실제로이 문법뿐만 아니라이 트리의 맨 위에 'idList'노드를 가져올 수있는 방법입니다. 재 작성 및 해당 연산자를 사용하여이 트리를 어떻게 재현 할 수 있습니까?

당신은 ^! 혼자 사용할 수 없습니다. 이 연산자는 기존 토큰에 대해서만 작동하며 추가 토큰을 만들고 싶을 때만 사용할 수 있습니다 (하위 트리의 루트로 사용). 당신은 rewrite rules and defining some imaginary tokens를 사용합니다.

빠른 데모 : 위의 데모를 실행하면

grammar test; 

options { 
    output=AST; 
    ASTLabelType=CommonTree; 
} 

tokens { 
    IdList; 
    Id; 
} 

@parser::members { 

    private static void walk(CommonTree tree, int indent) { 
    if(tree == null) return; 
    for(int i = 0; i < indent; i++, System.out.print(" ")); 
    System.out.println(tree.getText()); 
    for(int i = 0; i < tree.getChildCount(); i++) { 
     walk((CommonTree)tree.getChild(i), indent + 1); 
    } 
    } 

    public static void main(String[] args) throws Exception { 
    testLexer lexer = new testLexer(new ANTLRStringStream("abc abc123")); 
    testParser parser = new testParser(new CommonTokenStream(lexer)); 
    walk((CommonTree)parser.program().getTree(), 0); 
    } 
} 

program : idList EOF -> idList; 
idList : id*  -> ^(IdList id*); 
id  : ID   -> ^(Id ID); 

ID : LETTER (LETTER | DIGIT)*; 
SPACE : ' ' {skip();}; 

fragment LETTER : 'a' .. 'z' | 'A' .. 'Z'; 
fragment DIGIT : '0' .. '9'; 

, 당신이 표시되는 콘솔에 인쇄되는 다음 당신이 볼 수 있듯이

IdList 
    Id 
     abc 
    Id 
     abc123 

은, 가상 토큰도 시작해야합니다 렉서 규칙처럼 대문자로 당신이 상상들이 나타내는 파서 규칙과 동일한 text 토큰을 부여하려면,이 대신 같은 것을 할 :

idList : id*  -> ^(IdList["idList"] id*); 
id  : ID   -> ^(Id["id"] ID); 

인쇄 할 : 깊이 대답 그러한위한

idList 
    id 
     abc 
    id 
     abc123 
+0

감사합니다. 어떤 이유로 든 나는 문서에서 그것을 얻을 수 없었습니다. –

+0

@ChrisCovert도 환영합니다. –