レガシーコード用のきれいなプリンタを古い言語で書く。私が翻訳を書いてC++を出力する前に、解析と解読を学ぶ予定です。私は6月にJavaとANTLRを使って深いところに投げ込まれたので、間違いなくいくつかの知識のギャップがあります。ANTLR 4 - カスタムリスナーから隠しコメントチャンネルにアクセスするには?
私は自分のカスタムリスナーのためのメソッドを書くのが楽しいと思っています。コメントもきれいに印刷したいと思っています。私のコメントは、別の隠しチャンネルにあります。
/* 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 ;
私はCymbol CommentShifterの例をpで再生しています。 「Definitive ANTLR 4 Reference」の207ページを参照してください。これをリスナーのメソッドに適用する方法を理解しようとしています。
public void exitVarDecl(ParserRuleContext ctx) {
Token semi = ctx.getStop();
int i = semi.getTokenIndex();
List<Token> cmtChannel = 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
を使用するかどうか、nullポインタ例外を取得this answerを見て、それは有望だと思うが、私は本当に必要なのはだと思います。構文解析ツリーでリスナーのメソッドとコンテキストを実際に取得するには数か月かかりました。
CommonTokenStream.LT()
、CommonTokenStream.LA()
、およびconsume()
は私が使いたいものですが、ANTLRの本の例とは全く異なる方法を使って答えているのはなぜですか?トークンインデックスまたはトークンタイプについてはどうすればよいですか?
私はこれの背後にある論理をよりよく理解したいと思います。