编程语言
首页 > 编程语言> > Antlr4+python3安装&示例程序+C++版本(VS) 2018-12-21

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'

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

第二步下载的时候如果权限不够,就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.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的目录下,创建以下程序并运行:

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命令之后:

创建自己的项目

如果要自己创建antlr4的项目,在刚才几步能正常执行之后,在【这个刚刚打开的解决方案里面】创建自己的项目:

新建项目

注意选择【添加到解决方案】。

修改以下属性:

之后就可以运行了!

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

【输出】-【生成】可以看到目录

生成

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