ANTLR4中getText()排除空格:如何获取含空格完整字符串?
获取ANTLR4中包含空格的完整语句文本
嘿,这个问题我之前在项目里踩过坑!ANTLR4默认的getText()方法确实会跳过单词间的空格——因为它只拼接那些属于默认通道(DEFAULT_TOKEN_CHANNEL)的token文本,而空格、换行这类通常会被语法里的WS规则标记到隐藏通道(HIDDEN),自然就被排除在外了。除了在语法里把空格纳入规则这种方式,还有几个更灵活的办法:
方法1:用TokenStream的getText()截取上下文区间
这是最简便高效的方式。对于你拿到的ParserRuleContext对象(比如某个语句的上下文ctx),可以直接调用它对应的TokenStream的getText()方法,传入整个上下文作为参数:
// 假设ctx是你解析得到的某个语句的上下文对象 String fullTextWithSpaces = ctx.start.getTokenStream().getText(ctx);
这个方法会直接从原始输入文本中截取上下文对应的整个区间,包括所有隐藏通道的空格、换行,完美还原原始的语句格式。
方法2:遍历所有token(含隐藏通道)拼接文本
如果需要更精细的控制(比如想过滤掉注释但保留空格),可以手动遍历上下文覆盖的所有token,包括隐藏通道的内容:
TokenStream tokenStream = ctx.start.getTokenStream(); StringBuilder sb = new StringBuilder(); // 从上下文的起始token索引遍历到结束token索引 for (int i = ctx.start.getTokenIndex(); i <= ctx.stop.getTokenIndex(); i++) { Token token = tokenStream.get(i); // 可以在这里加判断,比如只保留空格和默认通道的token,过滤注释 if (token.getChannel() == Token.DEFAULT_CHANNEL || token.getType() == YourLexer.WS) { sb.append(token.getText()); } } String fullText = sb.toString();
这种方式的优势是能自定义筛选规则,比如不想包含注释的话,就可以跳过注释类型的token。
补充说明
为什么默认的getText()拿不到空格?因为ANTLR的Lexer会把WS这类规则的token放到隐藏通道,Parser在构建语法树的时候会忽略这些通道的token,所以上下文的getText()只会拼接那些参与语法解析的token文本,自然就没了空格。
内容的提问来源于stack exchange,提问作者Abhishek Attri
相关产品推荐
相关产品推荐

