2013-08-01 3 views
2

코드/엑스트라의 CPP 예제를 모델로하여 DSL 용 전처리기를 구현하려고합니다. 그러나 토큰 팩토리를 사용하고 있지 않습니다. 하나가 필요합니까? emit (토큰)을 호출해도 예상대로 토큰이 토큰 스트림에 삽입되지 않습니다.ANTLR4 : 토큰 삽입 방법

// string-delimited path 
SPATH  : '"' (~[\n\r])*? '"' 
       { 
       emit(); // inject the current token 
       // launch another lexer on the include file, get tokens, 
       // emit them all at once here 
       List<CommonToken> tokens = Preprocessor.include(getText()); 
       if (null != tokens) { 
        for (CommonToken tok : tokens) { 
        emit(tok); 
        } 
       } 
       } 
     ; 

이 여기에 포함 방법이다 :

@SuppressWarnings("unchecked") 
public static List<CommonToken> include(String filename) { 
    List<CommonToken> tokens = null; 
    try (FileReader fr = openFile(filename.substring(1, filename.length() - 1)); 
      BufferedReader br = new BufferedReader(fr)) { 
     ANTLRInputStream input = new ANTLRInputStream(br); 
     PreprocessorLexer lexer = new PreprocessorLexer(input); 

     tokens = (List<CommonToken>) lexer.getAllTokens(); 

    } catch (IOException ioe) { 
     log.error("Can't load ~{}~", ioe.getLocalizedMessage()); 
    } 
    return tokens; 
} 

답변

3

당신은이 기능을 제공하기 위해 Lexer.nextToken를 오버라이드 (override) 할 필요가

다음은 렉서입니다. 귀하의 렉서에서 아직 nextToken에 의해 반환되지 않은 주사 된 토큰 중 Deque<Token>을 보관하십시오. 대기열이 비어있는 경우 nextToken 구현은 수퍼 클래스 구현에 따라 다음 토큰을 반환해야합니다.

다음은 몇 가지 샘플 코드입니다. 컴파일이나 실행을 시도하지 않았으므로 완벽하지 않을 수 있습니다.

private final Deque<Token> pendingTokens = new ArrayDeque<>(); 

@Override 
public Token nextToken() { 
    Token pending = pendingTokens.pollFirst(); 
    if (pending != null) { 
     return pending; 
    } 

    Token next = super.nextToken(); 
    pending = pendingTokens.pollFirst(); 
    if (pending != null) { 
     pendingTokens.addLast(next); 
     return pending; 
    } 

    return next; 
} 
+0

대체하지 않고 어떻게 현재 토큰을 방출합니까? emit()은 toString()이 [@ 56,110 : 123 = ' "strategy.ccl"', <0>, 7 : 15]을 반환하는 토큰을 제공합니다. <0>은 존재하지 않는 토큰을 나타내는 토큰 번호가 아닙니까? – user2643128

+0

lexer 규칙에서 emit()을 제거하면 현재 토큰을 적절히 방출 할 수있었습니다. – user2643128

+0

토큰에서 nextToken()을 짧게하여 다음으로 돌아갑니다. super.nextToken()을 반환합니다. 또한 도움이되었습니다. – user2643128