c# 4.0 - tomassetti - Acceda a los canales en ANTLR 4 y analícelos por separado
antlr4 mega tutorial (4)
Alternativamente, puede poner todas las otras fichas en otro canal y usar el canal predeterminado para su analizador.
Por supuesto, esto no funcionaría si tiene dos analizadores que esperan tokens en canales separados.
He incluido mis comentarios en un canal separado en ANTLR 4. en mi caso es el canal 2.
Esta es mi gramática más lexer.
COMMENT: ''/*'' .*? ''*/'' -> channel(2)
;
Quiero acceder a este canal 2 y hacer un análisis en este canal para acumular comentarios. Así que incluí eso como en el análisis de la gramática de la siguiente manera
comment
:COMMENT
;
En el programa
string s = " paring string"
AntlrInputStream input = new AntlrInputStream(s);
CSSLexer lexer = new CSSLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer,2);
Entonces quiero hacer el análisis en los tokens
var xr = parser.comment().GetRuleContexts<CommentContext>();
porque quiero obtener la información del objeto Start.Column
como Start.Column
etc.
EDITAR:
Esta es la pregunta mejorada
Para ser más específico, quiero obtener todos los tokens en el canal 2 y analizarlos usando la gramática de comentarios para obtener todos los comentarios en una lista ( IReadOnly<CommentContext>
) para que pueda recorrer cada uno de ellos y acceder a la información como , línea de inicio, columna de inicio, columna final de línea final y texto simbólico.
CommonTokenStream tokens = new CommonTokenStream(lexer,2);
Esto no me está dando los tokens en el canal 2. Y otra cosa que descubrí es hasta que estos tokens se pasan como argumentos para la construcción del analizador XParser parser = new XParser(tokens);
Entonces solo puedo acceder a los tokens llamando a GetTokens()
. En los tokes puedo ver que hay comentarios identificados como tokens y está en el canal 2. Aunque CommentTokenStrem
el número de canal como se CommentTokenStrem
arriba. contiene todos los tokens.
¿Cuál es el motivo por el que no se puede acceder a los tokens hasta que se crea el objeto analizador utilizando los tokens?
Quiero obtener un
CommentTokenStrem
en el canal 2 y pasarlo a la creación del objeto XParser para analizar estos tokens utilizando mi gramática decomment
. ¿Cuál es la mejor manera de hacerlo en ANTLR 4 API?
Qué tal esto:
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();
CommonTokenStream
un seguimiento interno de todos los tokens desde cualquier canal. Lo único que no verá cuando llame a getTokens()
son las reglas lexer donde se ejecutó una -> skip
acción de -> skip
(ni siquiera se crea token para esas reglas).
Puede ver los tokens en el canal 2 utilizando los métodos TokenStream.LT
e IntStream.consume
.
Ejemplo de 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 # ejemplo:
CommonTokenStream cts = new CommonTokenStream(tokenSource, 2);
IList<IToken> tokens = new List<IToken>();
while (cts.La(1) != Eof)
{
tokens.Add(cts.Lt(1));
cts.Consume();
}
ANTLR 4 C #:
using Antlr4.Runtime;
...
MyLexer lexer = new MyLexer (inputStream);
var tokenstream = new CommonTokenStream(lexer, TokenConstants.HiddenChannel);
IList<IToken> tokens = new List<IToken>();
while (tokenstream.La(1) != TokenConstants.Eof)
{
tokens.Add(tokenstream.Lt(1));
tokenstream.Consume();
}
foreach (IToken iToken in tokens)
{
Console.WriteLine(" Line : {0} Text : {1} ",
iToken.Line,
iToken.Text
);
}