Antlr4+python3安装&示例程序

Antlr系列(配合Python3)文章:https://www.jianshu.com/nb/32570686

Ubuntu安装

安装方法:(来自官网首页,Quick Start)

1
2
3
4
5
$ cd /usr/local/lib
$ wget https://www.antlr.org/download/antlr-4.7.2-complete.jar
$ export CLASSPATH=".:/usr/local/lib/antlr-4.7.2-complete.jar:$CLASSPATH"
$ alias antlr4='java -jar /usr/local/lib/antlr-4.7.2-complete.jar'
$ alias grun='java org.antlr.v4.gui.TestRig'

直接运行antlr4grun出现帮助信息就说明成功。

第二步下载的时候如果权限不够,就sudo下载并且之后sudo chmod 777 antlr-4.7.2-complete.jar

然后为方便使用,在.bashrc里面添加后三行:

1
2
3
export CLASSPATH=".:/usr/local/lib/antlr-4.7.2-complete.jar:$CLASSPATH"
alias antlr4='java -jar /usr/local/lib/antlr-4.7.2-complete.jar'
alias grun='java org.antlr.v4.gui.TestRig'

一定要注意这里的classpath里面要有.

Windows安装

添加下载的jar文件与.添加到CLASSPATH中,同时在Path内的路径里面建立两个bat文件:

antlr4.bat

1
java org.antlr.v4.Tool %*

grun.bat

1
java org.antlr.v4.gui.TestRig %*

要特别注意,.一定要添加到CLASSPATH中!!!!!!!

使用

(官方GetStarted:https://github.com/antlr/antlr4/blob/master/doc/getting-started.md

创建文件Hello.g4,如下:

1
2
3
4
grammar Hello;
r : 'hello' ID ; // match keyword hello followed by an identifier
ID : [a-z]+ ; // match lower-case identifiers
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines

执行antlr4 Hello.g4javac Hello*.java

之后grun Hello r -tree或者grun Hello r -gui,输入某一个输入串(如hello pjio)后回车并按下Ctrl-D(Windows下为Ctrl-Z),就可以看到解析结果。

这里的r表示的是第二行的起始符号r

python部分

(官方说明:https://github.com/antlr/antlr4/blob/master/doc/python-target.md

准备python库:

pip install antlr4-python3-runtime

执行antlr4,其中需要声明Dlanguageantlr4 -Dlanguage=Python3 Hello.g4 (注意是Python3,P要大写!)

之后在那个执行antlr4的目录下,创建以下程序并运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import sys
from antlr4 import *
from HelloLexer import HelloLexer
from HelloParser import HelloParser
from HelloListener import HelloListener

class HelloPrintListener(HelloListener):
def enterR(self, ctx):
# 函数名enterR的R指的是非终结符r
print("Hello: %s" % ctx.ID())


def main():
lexer = HelloLexer(StdinStream())
stream = CommonTokenStream(lexer)
parser = HelloParser(stream)
tree = parser.r()
printer = HelloPrintListener()
walker = ParseTreeWalker()
walker.walk(printer, tree)

if __name__ == '__main__':
main()

还是直接启动后输入hello wjgoiwejgoiw并且回车,输入Ctrl-D或者Ctrl-Z(Windows)