antlr4
本文包括:
antlr4基本操作:下载、安装、测试
Listener模式和Visitor模式比较
通过增加操作修饰文法
antlr4 优先级、左递归及相关性
antlr4 实现的简单计算器(java版)
基本操作
下载安装antlr
sudo curl -O http://www.antlr.org/download/antlr-4.7-complete.jar
alias antlr4='java -jar /usr/local/lib/antlr-4.7-complete.jar'
alias grun='java org.antlr.v4.gui.TestRig'
设置antlr4和grun别名的两句:直接写在命令行,重启就会被抹去,失去效果;推荐写在用户配置文件中(Mac OS 下 vi ~/.bash_profile,写在文件末尾即可)
编写一个文法,保存为hello.g4
grammar hello;
//tokens
s: 'hello' + ID;
ID: [a-z]+;
WS: [ \t\n\r]+ -> skip;
利用antlr生成这个文法的识别器(默认生成的识别器由java编写)
//进入hello.g4所在文件夹后执行
antlr4 hello.g4
测试字符串是否属于这个文法
在使用生成的识别器前要先编译,因为我们生成的识别器是用默认的java语言编写的,所以我们用javac来编译:javac -g *.java。
如果不编译就使用这个识别器,会发生Can't load hello as lexer or parser的错误,原因显而易见,不再赘述
以下方式都可以用来识别字符串是否能够被这个文法识别,敲入下列命令,回车,输入要识别的字符串,以 EOF(UNIX/Mac OS下Ctrl+D,windows下Ctrl+Z)结尾
grun [文法名] [标识符] [TestRig参数]
grun hello s -tokens
grun hello s -tree
grun hello s -gui
上面列出了常见TestRig参数,其他参数可见antlr官方文档
Listener & Visitor
Visitor和Listener是antlr提供的两种树遍历机制。Listener是默认的机制,可以被antlr提供的遍历器对象调用;如果要用Visitor机制,在生成识别器时就需要显式说明 antlr4 -no-listener -visitor Calc.g4,并且必须显示的调用visitor方法遍历它们的子节点,在一个节点的子节点上如果忘记调用visit方法,就意味着那些子数没有得到访问
Listener
文件结构
hello.tokens
helloBaseListener.java
helloLexer.java
helloLexer.tokens
helloListener.java
helloParser.java
ParserTreeWalker类是ANTLR运行时提供的用于遍历语法分析树和触发Listener中回调方法的树遍历器。ANTLR工具根据hello.g4文法自动生成ParserTreeListener接口的子接口helloListener和默认实现helloBaseListener,其中含有针对语法中每个规则的enter和exit方法。
helloListener是语法和Listener对象之间的关键接口 public interface helloListener extends ParserTreeListener
helloBaseListener是ANTLR生成的一组空的默认实现。ANTLR内建的树遍历器会去触发在Listener中像enterProg()和exitProg()这样的一串回调方法
Visitor
文件结构
执行antlr4 -no-listener -visiter hello.g4后,生成以下文件
hello.tokens
helloBaseVisitor.java
helloLexer.java