Antlr4+python3安装&示例程序+C++版本(VS) 2018-12-21

2021/7/18 17:38:22

本文主要是介绍Antlr4+python3安装&示例程序+C++版本(VS) 2018-12-21,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • 安装
    • Ubuntu安装
    • Windows安装
  • 使用
    • g4部分
    • python部分
  • 示例:Visitor实现四则运算的计算
  • C++版本
    • 官方demo
    • 创建自己的项目
    • ANTLR的lib生成
      • LIB介绍
      • LIB创建
      • LIB使用-引用
      • LIB使用-复制LIB文件
      • ANTLR的lib生成

安装

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

  • 下载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为启动项目,启动即可在【调试】输出中(不是控制台那个黑框)看到输出的示例
    example

创建自己的项目

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

新建项目

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

修改以下属性:

  • 【新建的项目】里【引用】右键【添加引用】,选上antlr4cpp-vs2015
  • 添加引用
  • antlr4cpp-vs2015
  • 【源文件】-右键【添加】-【现有项】,选中上面几级目录的demo\generated文件夹下所有h、cpp文件
  • 添加generate文件
  • 新建一个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

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

生成

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等所有头文件到自己的项目目录下。



这篇关于Antlr4+python3安装&示例程序+C++版本(VS) 2018-12-21的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程