通过一个例子学习ANTLR从G4语法文件生成的Java文件

通过一个例子学习ANTLR从G4语法文件生成的Java文件数组ANTLR通过g4语法文件生成很多Java文件,现在简单介绍一下各个文件的含义通过一个例子来生成相应的文件这个例子是这样的,把一个整型数组的

大家好,欢迎来到IT知识分享网。

通过一个例子学习ANTLR从G4语法文件生成的Java文件

数组

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;

通过语法文件自动生产一系列文件,文件列表如下图所示,

通过一个例子学习ANTLR从G4语法文件生成的Java文件

自动生成的文件

其中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; } }

测试生成的语法文件

通过一个例子学习ANTLR从G4语法文件生成的Java文件

测试一下

测试程序比较简单,还是用最初的测试用例[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
通过一个例子学习ANTLR从G4语法文件生成的Java文件

待续

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/51763.html

(0)
上一篇 2024-08-15 22:00
下一篇 2024-08-16 16:45

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信