ANTLR4:如何注入令牌

时间:2013-08-01 17:43:33

标签: lexer antlr4

我正在尝试为DSL实现预处理器,以代码/附加中的CPP示例为模型。但是,我没有使用令牌工厂。需要一个吗?调用emit(令牌)不会按预期将令牌注入令牌流。

这是词法分析器:

// 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);
                   }
                 }
               }
      ;

这是include方法:

@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;
}

1 个答案:

答案 0 :(得分:3)

您需要覆盖Lexer.nextToken才能提供此功能。在词法分析器中,保留Deque<Token>尚未由nextToken返回的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; } 的实现应根据超类实现返回下一个标记。

这是一些示例代码。我没有尝试编译或运行它,所以它可能不完美。

{{1}}