大家好,欢迎来到IT知识分享网。
ANTLR通过g4语法文件生成很多Java文件,现在简单介绍一下各个文件的含义
通过一个例子来生成相应的文件
这个例子是这样的,把一个整型数组的各项加起来输出一个数字和。比如输入一个数组[8,9,100,99,10],解析完了输出一个数组226。
首先定义整型数组的语法文件ArraySum.g4,简单介绍下这个文件,第一个使用关键字grammar+语法名字,下面定义了两个文法序列array和value,和两个词法规则INT和WS。
// ArraySum.g4 grammar ArraySum; array : '[' value (',' value)+ ']'; value : INT; INT :[0-9]+; WS:[ \t\r\n]+ -> skip;
通过语法文件自动生产一系列文件,文件列表如下图所示,
其中ArraySum.tokens文件是用来指定词法符号的数值类型,其中没有命名的词法字面量会自动创建T__开头的词法规则名。
T__0=1 T__1=2 T__2=3 INT=4 WS=5 '['=1 ','=2 ']'=3
生成的ArraySumListener.java是监听器接口,在遍历语法树的时候会触发事件,这些事件会回调监听的方法。其中ArraySumBaseListener.java是监听器接口的默认实现,如果想要接收事件可以自定义类并实现相应的方法即可。
public interface ArraySumListener extends ParseTreeListener { /** * Enter a parse tree produced by {@link ArraySumParser#array}. * @param ctx the parse tree */ void enterArray(ArraySumParser.ArrayContext ctx); /** * Exit a parse tree produced by {@link ArraySumParser#array}. * @param ctx the parse tree */ void exitArray(ArraySumParser.ArrayContext ctx); /** * Enter a parse tree produced by {@link ArraySumParser#value}. * @param ctx the parse tree */ void enterValue(ArraySumParser.ValueContext ctx); /** * Exit a parse tree produced by {@link ArraySumParser#value}. * @param ctx the parse tree */ void exitValue(ArraySumParser.ValueContext ctx); }
ArraySumLexer.java是词法分析器的类的定义,自动识别语法文件中的文法规则和词法规则,把输入的字符分解成词法符号。
public class ArraySumLexer extends Lexer { static { RuntimeMetaData.checkVersion("4.12.0", RuntimeMetaData.VERSION); } protected static final DFA[] _decisionToDFA; protected static final PredictionContextCache _sharedContextCache = new PredictionContextCache(); public static final int T__0=1, T__1=2, T__2=3, INT=4, WS=5; public static String[] channelNames = { "DEFAULT_TOKEN_CHANNEL", "HIDDEN" }; public static String[] modeNames = { "DEFAULT_MODE" }; private static String[] makeRuleNames() { return new String[] { "T__0", "T__1", "T__2", "INT", "WS" }; } public static final String[] ruleNames = makeRuleNames(); private static String[] makeLiteralNames() { return new String[] { null, "'['", "','", "']'" }; } private static final String[] _LITERAL_NAMES = makeLiteralNames(); private static String[] makeSymbolicNames() { return new String[] { null, null, null, null, "INT", "WS" }; } private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); /** * @deprecated Use {@link #VOCABULARY} instead. */ @Deprecated public static final String[] tokenNames; static { tokenNames = new String[_SYMBOLIC_NAMES.length]; for (int i = 0; i < tokenNames.length; i++) { tokenNames[i] = VOCABULARY.getLiteralName(i); if (tokenNames[i] == null) { tokenNames[i] = VOCABULARY.getSymbolicName(i); } if (tokenNames[i] == null) { tokenNames[i] = "<INVALID>"; } } } @Override @Deprecated public String[] getTokenNames() { return tokenNames; } @Override public Vocabulary getVocabulary() { return VOCABULARY; } public ArraySumLexer(CharStream input) { super(input); _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); } @Override public String getGrammarFileName() { return "ArraySum.g4"; } }
最重要的语法分析器ArraySumParser.java,用它来识别我们自定义个语法ArraySum。
public class ArraySumParser extends Parser { }
实现监听器接口来接收事件
继承ArraySumBaseListener重写exitArray和enterValue方法,在exitArray方法中输出计算结果,在enterValue方法中累加,以下为程序源码:
public class SumListener extends ArraySumBaseListener { private long sum = 0; @Override public void enterArray(ArraySumParser.ArrayContext ctx) { System.out.println("the array is :" + ctx.getText()); } @Override public void exitArray(ArraySumParser.ArrayContext ctx) { System.out.println("sum = " + sum); } @Override public void enterValue(ArraySumParser.ValueContext ctx) { Integer value = Integer.valueOf(ctx.getText()); sum += value; } }
测试生成的语法文件
测试程序比较简单,还是用最初的测试用例[8,9,100,99,10],源码如下:
public class TestArraySum { public static void main(String[] args) { String arrayStr = "[8,9,100,99,10]"; CharStream charStream = CharStreams.fromString(arrayStr); ArraySumLexer jsonLexer = new ArraySumLexer(charStream); CommonTokenStream commonTokenStream = new CommonTokenStream(jsonLexer); //语法分析器 ArraySumParser jsonParser = new ArraySumParser(commonTokenStream); ArraySumParser.ArrayContext array = jsonParser.array(); //遍历语法树 ParseTreeWalker walker = new ParseTreeWalker(); walker.walk(new SumListener(),array); } }
运行程序结果如下;
the array is :[8,9,100,99,10] sum = 226
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/51763.html