3

ANTLR 4 の別のチャンネルにコメントを含めました。私の場合はチャンネル 2 です。

これが私のレクサー文法です。

COMMENT: '/*' .*? '*/' -> channel(2) 
       ;

このチャネル 2 にアクセスして、このチャネルで解析を行い、コメントを蓄積したいと考えています。だから私は以下のように文法を解析するようにそれを含めました:

comment
:COMMENT
;

プログラムでは

        string s = " paring string"
        AntlrInputStream input = new AntlrInputStream(s);
        CSSLexer lexer = new CSSLexer(input); 
       
        CommonTokenStream tokens = new CommonTokenStream(lexer,2);

次に、トークンの解析を行いたい

var xr = parser.comment().GetRuleContexts<CommentContext>();

Start.Columnなどの CommentContext オブジェクトから情報を取得したいためです。

編集:

これは改善された質問です

より具体的には、チャネル 2 のすべてのトークンを取得し、コメント文法を使用してそれらを解析して、すべてのコメントを list( IReadOnly<CommentContext>) に取得し、これらのそれぞれを反復処理して、開始行、開始行などの情報にアクセスできるようにします。開始列、終了行終了列、およびトークン テキスト。

CommonTokenStream tokens = new CommonTokenStream(lexer,2);

これは、チャネル 2 のトークンを私に与えていません。そして、私が発見したもう 1 つのことは、これらのトークンが引数としてパーサー コンストラクトに渡されるまでです。XParser parser = new XParser(tokens);

その後、私だけが を呼び出してトークンにアクセスできます。トークンGetTokens()には、トークンとして識別されたコメントがあり、チャンネル 2 にあることがわかりますCommentTokenStrem。上記のようにチャンネル番号を指定しても。すべてのトークンが含まれています。

  1. トークンを使用してパーサー オブジェクトが作成されるまで、トークンにアクセスできない理由は何ですか?

  2. チャネル 2 でを取得CommentTokenStremし、XParser オブジェクトの作成に を渡して、comment文法を使用してこれらのトークンを解析したいと考えています。ANTLR 4 API でこれを行う最善の方法は何ですか?

4

4 に答える 4

4

CommonTokenStream任意のチャネルからのすべてのトークンを内部的に追跡します。呼び出し時に表示されない唯一のものgetTokens()は、アクションが実行されたレクサー ルールです-> skip(これらのルールに対してトークンは作成されません)。

TokenStream.LTメソッドとメソッドを使用して、チャネル 2 のトークンを確認できますIntStream.consume

Java の例

CommonTokenStream cts = new CommonTokenStream(tokenSource, 2);
List<Token> tokens = new ArrayList<Token>();
while (cts.LA(1) != EOF) {
    tokens.add(cts.LT(1));
    cts.consume();
}

C# の例:

CommonTokenStream cts = new CommonTokenStream(tokenSource, 2);
IList<IToken> tokens = new List<IToken>();
while (cts.La(1) != Eof)
{
    tokens.Add(cts.Lt(1));
    cts.Consume();
}
于 2013-09-05T12:26:13.270 に答える
2

これはどう:

 var allowedChannels = new[] { 2 }; // add more if you need to
 var tokensImInterestedIn = tokens.GetTokens().Where(token => allowedChannels.Contains(token.Channel) && token.Type != CSSLexer.Eof).ToArray();

 // if you're just interested in one particular channel
 var tokensImInterestedIn = tokens.GetTokens().Where(token => token.Channel == 2) && token.Type != CSSLexer.Eof).ToArray();
于 2013-09-05T06:52:18.087 に答える
0

または、他のすべてのトークンを別のチャネルに配置し、パーサーにデフォルトのチャネルを使用することもできます。

もちろん、別々のチャネルでトークンを期待する 2 つのパーサーがある場合、これは機能しません。

于 2013-09-05T11:07:55.000 に答える