Antlr4+python3安装&示例程序+C++版本(VS) 2018-12-21
作者:互联网
文章目录
安装
Ubuntu安装
安装方法:(来自官网首页,Quick Start)
$ 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'
直接运行antlr4
和grun
出现帮助信息就说明成功。
第二步下载的时候如果权限不够,就sudo
下载并且之后sudo chmod 777 antlr-4.7.2-complete.jar
然后为方便使用,在.bashrc
里面添加后三行:
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
java org.antlr.v4.Tool %*
grun.bat
java org.antlr.v4.gui.TestRig %*
要特别注意,.
一定要添加到CLASSPATH中!!!!!!!
使用
(官方GetStarted:https://github.com/antlr/antlr4/blob/master/doc/getting-started.md
g4部分
创建文件Hello.g4
,如下:
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.g4
和javac 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,其中需要声明Dlanguage
:antlr4 -Dlanguage=Python3 Hello.g4
(注意是Python3,P要大写!)
之后在那个执行antlr4的目录下,创建以下程序并运行:
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)
示例:Visitor实现四则运算的计算
文法规则文件Expr.g4
:
grammar Expr;
prog: expr NEWLINE # printExpr;
expr: left=expr op=('*'|'/') right=expr # mulDiv // 用来确定优先级,在上面的优先级高
| left=expr op=('+'|'-') right=expr # addSub
| INT # int
| '(' expr ')' # brackets
;
NEWLINE : [\r\n]+ ;
INT : [0-9]+ ;
MUL : '*' ; // 用来便于当作常量引用
DIV : '/' ;
ADD : '+' ;
SUB : '-' ;
在执行antlr4的时候需要指明-no-listener
和-visitor
,因此执行antlr4 -no-listener -visitor -Dlanguage=Python3 Expr.g4
创建文件Expr.py
:
import sys
from antlr4 import *
from ExprLexer import ExprLexer
from ExprParser import ExprParser
from ExprVisitor import ExprVisitor
class ExprCalculateVisitor(ExprVisitor):
def visitPrintExpr(self, ctx):
# 函数名enterR的R指的是非终结符r
val = self.visit(ctx.expr())
print(val)
return val
def visitBrackets(self, ctx):
return self.visit(ctx.expr())
def visitAddSub(self, ctx):
if ctx.op.type == ExprParser.ADD:
return self.visit(ctx.left) + self.visit(ctx.right)
else:
return self.visit(ctx.left) - self.visit(ctx.right)
def visitMulDiv(self, ctx):
if ctx.op.type == ExprParser.MUL:
return self.visit(ctx.left) * self.visit(ctx.right)
else:
return self.visit(ctx.left) / self.visit(ctx.right)
def visitInt(self, ctx):
return int(ctx.getText())
def main():
lexer = ExprLexer(StdinStream())
stream = CommonTokenStream(lexer)
parser = ExprParser(stream)
tree = parser.prog()
calculator = ExprCalculateVisitor()
calculator.visitPrintExpr(tree)
if __name__ == '__main__':
main()
这里的visitXXX的XXX部分都是上面#后的内容;如果不写#后的东西,就会是visitProg之类的
之后仍然是运行并且输入后回车输入EOF(Ctrl-D/Ctrl-Z)即可看到结果输出
C++版本
官方demo
按照官网首页配置好,测试能够使用antlr4和grun命令之后:
- 下载https://github.com/antlr/antlr4/tree/master/runtime/Cpp中的所有文件
- 运行generate命令(在https://github.com/antlr/antlr4/tree/master/runtime/Cpp/demo/目录下,执行
antlr4 -Dlanguage=Cpp -listener -visitor -o generated/ -package antlrcpptest TLexer.g4 TParser.g4
- 用VS打开其中的sln项目(https://github.com/antlr/antlr4/blob/master/runtime/Cpp/demo/Windows/antlr4cpp-vs2015.sln,注意vs2013及以上的版本才行,因为这样的版本才有完整的C++11支持
- 设置
antlr4cpp-demo
为启动项目,启动即可在【调试】输出中(不是控制台那个黑框)看到输出的示例
创建自己的项目
如果要自己创建antlr4的项目,在刚才几步能正常执行之后,在【这个刚刚打开的解决方案里面】创建自己的项目:
注意选择【添加到解决方案】。
修改以下属性:
- 【新建的项目】里【引用】右键【添加引用】,选上antlr4cpp-vs2015
- 【源文件】-右键【添加】-【现有项】,选中上面几级目录的demo\generated文件夹下所有h、cpp文件
- 新建一个main.cpp,里面复制过来
antlr4cpp-demo
的main.cpp - 在【新建的项目】上右键【属性】打开属性页面(这时,单击
antlr4cpp-demo
这个项目会切换到这个项目的对应属性,可以直接方便地复制粘贴),把antlr4cpp-demo
的以下属性复制过来:- 复制【输出目录】
- 修改【字符集】为Unicode
- 复制【C/C++】-【常规】-【附加包含目录】
- 右上角【配置管理器】-找到这个项目后【编辑】,重命名为Debug DLL
- 运行&改编码(选择是,因为之前把字符集改成了Unicode)
之后就可以运行了!
ANTLR的lib生成
LIB介绍
LIB生成&使用:https://www.cnblogs.com/TenosDoIt/p/3203137.html
LIB创建
用桌面向导创建一个空的LIB
弹出的应用程序类型选择.lib
新建MyLIB.h
#pragma once
void fun(int a);
extern int k;
class testclass
{
public:
testclass();
void print();
};
MyLIB.cpp
#include "stdafx.h"
#include "MyLIB.h"
#include <iostream>
void fun(int a)
{
std::cout << a << "lib gen\n";
}
int k = 222;
testclass::testclass()
{
std::cout << "123\n";
}
void testclass::print()
{
std::cout << "this is testcalss\n";
}
之后设置为启动项目,生成就可以得到lib文件:
【输出】-【生成】可以看到目录
LIB使用-引用
使用:新建空项目,添加引用,创建一个头文件把之前头文件的东西复制进来
新建一个main.cpp
#include <iostream>
#include "MyLIB.h"
int main()
{
fun(4);
std::cout << k << std::endl;
testclass tc;
tc.print();
return 0;
}
LIB使用-复制LIB文件
找到lib文件,复制到main.cpp目录下,复制头文件过来,复制#pragma comment(lib, "lib.lib")
到main.cpp文件中main函数上面即可。
ANTLR的lib生成
antlr4cpp-antlr2015这个项目属性里面改成配置类型-静态库,生成后复制得到的lib文件到自己的项目目录下。
复制antlr4-runtime.h
等所有头文件到自己的项目目录下。
标签:12,21,lib,示例,antlr,self,ctx,antlr4,main 来源: https://blog.csdn.net/qq_36243169/article/details/118879926