用旧语言为遗留代码编写漂亮的打印机.在编写转换器输出C++之前,我的计划是学习解析和解析.我在6月份用Java和ANTLR进入了深层次,所以我肯定有一些知识空白.
我已经达到了我习惯为自定义监听器编写方法的程度,我希望能够对这些注释进行漂亮打印.我的评论是在一个单独的隐藏频道上.以下是隐藏令牌的语法规则:
/* Comments and whitespace -- Nested comments are allowed, each is redirected to a specific channel */ COMMENT_1 : '(*' (COMMENT_1|COMMENT_2|.)*? '*)' -> channel(1) ; COMMENT_2 : '{' (COMMENT_1|COMMENT_2|.)*? '}' -> channel(1) ; NEWLINES : [\r\n]+ -> channel(2) ; WHITESPACE : [ \t]+ -> skip ;
我一直在玩p上的Cymbol CommentShifter示例.最终的ANTLR 4参考文献中的207,我试图找出如何使其适应我的听众方法.
public void exitVarDecl(ParserRuleContext ctx) { Token semi = ctx.getStop(); int i = semi.getTokenIndex(); ListcmtChannel = tokens.getHiddenTokensToRight(i, CymbolLexer.COMMENTS); if (cmtChannel != null) { Token cmt = cmtChannel.get(0); if (cmt != null) { String txt = cmt.getText().substring(2); String newCmt = "// " + txt.trim(); // printing comments in original format rewriter.insertAfter(ctx.stop, newCmt); // at end of line rewriter.replace(cmt, "\n"); } } }
我通过使用exitEveryRule
而不是exitVarDecl
并且它适用于Cymbol示例来适应这个示例但是当我将它适应我自己的监听器时,无论是否使用exitEveryRule
或者我都会得到一个空指针异常exitSpecificThing
我正在看这个答案,看起来很有希望,但我认为我真正需要的是解释隐藏的频道数据是如何存储以及如何访问它的.我花了几个月的时间才真正在解析树中获得监听器方法和上下文.
它似乎是CommonTokenStream.LT()
,CommonTokenStream.LA()
并且consume()
是我想要使用的,但为什么SO的答案使用与ANTLR书籍示例完全不同的方法?我应该了解令牌索引或令牌类型?
我想更好地理解这背后的逻辑.