Antlr 我可以在解析器程序中获得原始令牌模式吗?

Antlr 我可以在解析器程序中获得原始令牌模式吗?,antlr,antlr4,Antlr,Antlr4,我在ANTLRv4的顶部编写了一个演示代码,如下所示: String expression = "var c = a + b()"; ExprLexer lexer = new ExprLexer(CharStreams.fromString(expression)); CommonTokenStream tokens = new CommonTokenStream(lexer); ExprParser parser = new

我在ANTLRv4的顶部编写了一个演示代码,如下所示:

String expression = "var c = a + b()";
        ExprLexer lexer = new ExprLexer(CharStreams.fromString(expression));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        ExprParser parser = new ExprParser(tokens);

        lexer.removeErrorListeners();
        parser.removeErrorListeners();
        CountingErrorListener errorListener = new CountingErrorListener();
        parser.addErrorListener(errorListener);
        
        Vocabulary vocabulary = lexer.getVocabulary();
        System.out.println("vocabulary : "+vocabulary.getDisplayName(4));
对于最后一行,控制台上将显示符号名称
ID
ID
在.g4文件中定义,如

ID: [a-zA-Z] [a-zA-Z0-9_]*;

我的问题是,我可以通过一些类或方法在我的程序中获得原始ID模式
[a-zA-Z][a-zA-Z0-9\*

没有直接的方法。您可以使用ANTLR自己的解析器解析语法:

然后创建一个侦听器,该侦听器收集
映射中的所有lexer规则模式

快速演示:

import org.antlr.v4.runtime.*;
导入org.antlr.v4.runtime.misc.Interval;
导入org.antlr.v4.runtime.tree.ParseTreeWalker;
导入java.util.LinkedHashMap;
导入java.util.Map;
公共班机{
公共静态void main(字符串[]args)引发异常{
String source=“语法T;\n”+
“\n”+
“解析\n”+
“:ID+EOF\n”+
“;\n”+
“\n”+
“变量\n”+
“:“$”ID\n”+
“;\n”+
“\n”+
“ID\n”+
“:[a-zA-Z][a-zA-Z0-9\]*\n”+
" ;";
ANTLRv4Lexer lexer=新的ANTLRv4Lexer(CharStreams.fromString(source));
ANTLRv4Parser parser=新的ANTLRv4Parser(新的CommonTokenStream(lexer));
LexerRuleListener LexerRuleListener=新的LexerRuleListener(lexer.getInputStream());
parserruleListener,parser.grammarSpec());
System.out.println(“ID的模式:+lexerRuleListener.getPatternForToken(“ID”);
}
}
类LexerRuleListener扩展了AntlRv4ParserBaseSelListener{
私有最终地图lexerRuleMap;
私有最终CharStream-inputStream;
公共LexerRuleListener(CharStream inputStream){
this.lexerRuleMap=新建LinkedHashMap();
this.inputStream=inputStream;
}
公共字符串getPatternForToken(字符串标记名){
返回这个.lexerRuleMap.get(tokenName);
}
//lexerRuleSpec
//:DOC\u COMMENT*FRAGMENT?标记\u REF冒号lexerRuleBlock SEMI
//  ;
@凌驾
public void enterLexerRuleSpec(ANTLRv4Parser.LexerRuleSpecContext ctx){
int startIndex=ctx.lexerRuleBlock().start.getStartIndex();
int stopIndex=ctx.lexerRuleBlock().stop.getStopIndex();
String text=inputStream.getText(新间隔(startIndex,stopIndex));
lexerRuleMap.put(ctx.TOKEN\u REF().getText(),text);
}
}
运行上述代码将打印:

ID's pattern: [a-zA-Z] [a-zA-Z0-9_]*