IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> Antlr g4 idea中配置使用 -> 正文阅读

[开发工具]Antlr g4 idea中配置使用

ANTLR 是用JAVA写的语言识别工具,它用来声明语言的语法,简称为“元语言”。

Idea中配置使用

pom.xml添加

        <dependency>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4-runtime</artifactId>
            <version>4.7</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

Idea setting中安装ANTLR插件(我本机安装完了)? ?Eclipse也类似的安装插件

?示例:计算机四则计算(官网照抄)

1、新建g4文件,如Math.g4

grammar Math;

prog : stat+;

stat: expr NEWLINE          # printExpr
    | ID '=' expr NEWLINE   # assign
    | NEWLINE               # blank
    ;

expr:  expr op=('*'|'/') expr   # MulDiv
| expr op=('+'|'-') expr        # AddSub
| INT                           # int
| ID                            # id
| '(' expr ')'                  # parens
;

MUL : '*' ; // assigns token name to '*' used above in grammar
DIV : '/' ;
ADD : '+' ;
SUB : '-' ;
ID : [a-zA-Z]+ ;
INT : [0-9]+ ;
NEWLINE:'\r'? '\n' ;
WS : [ \t]+ -> skip;

?Idea 安装完ANTLR插件 右键g4文件可以看到,点击Configure ANTLR...

配置目录如下,按照你们自己的目录设置,点击OK

?右键Math.g4文件,点击Generate ANTLR Recognizer

自动生成代码:

编写实现类,继承上面自动生成的类MathBaseVisitor,实现计算

public class MathVisitorImp extends MathBaseVisitor<Integer> {
    // 存储变量的值
    private Map<String, Integer> variable;

    public MathVisitorImp() {
        variable = new HashMap<>();
    }

    // 当遇到printExpr节点,计算出exrp的值,然后打印出来
    @Override
    public Integer visitPrintExpr(MathParser.PrintExprContext ctx) {
        Integer result  = ctx.expr().accept(this);
        System.out.println(result);
        return null;
    }

    // 分别获取子节点expr的值,然后做加减运算
    @Override
    public Integer visitAddSub(MathParser.AddSubContext ctx) {
        Integer param1 = ctx.expr(0).accept(this);
        Integer param2 = ctx.expr(1).accept(this);
        if (ctx.op.getType() == MathParser.ADD) {
            return param1 + param2;
        }else {
            return param1 - param2;
        }
    }

    // 分别获取子节点expr的值,然后做乘除运算
    @Override
    public Integer visitMulDiv(MathParser.MulDivContext ctx) {
        Integer param1 = ctx.expr(0).accept(this);
        Integer param2 = ctx.expr(1).accept(this);
        if (ctx.op.getType() == MathParser.MUL) {
            return param1 * param2;
        }else {
            return param1 / param2;
        }
    }

    // 当遇到int节点,直接返回数据
    @Override
    public Integer visitInt(MathParser.IntContext ctx) {
        return Integer.parseInt(ctx.getText());
    }

    // 当遇到Id节点,从变量表获取值
    @Override
    public Integer visitId(MathParser.IdContext ctx) {
        return variable.get(ctx.getText());
    }

    // 当遇到赋值语句,获取右边expr的值,然后将变量的值保存到variable集合
    @Override
    public Integer visitAssign(MathParser.AssignContext ctx) {
        String name = ctx.ID().getText();
        Integer value = ctx.expr().accept(this);
        variable.put(name, value);
        return null;
    }

}

测试:

public class MathVisitorTest {
    public static void exec(String input) {
        MathLexer lexer = new MathLexer(CharStreams.fromString(input));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        MathParser parser = new MathParser(tokens);
        parser.setBuildParseTree(true);
        ParseTree root = parser.prog();
        MathBaseVisitor<Integer> visitor = new MathVisitorImp();
        root.accept(visitor);
    }

    public static void main(String[] args) {
        String input = "1+2+3+5-7+1\n";
//        String input = "a = 14\n" +
//                "b = a - 3\n" +
//                "a + b\n";
        exec(input);
    }
}

结果输出为:5

g4检查语法是否通过

1.新建g4Test.txt内容如下

a=3
b=4
c=a+b
d=a+b+c
e=4**2
f=d+e

2.测试g4是否通过

public class g4Main {
    public static void main(String[] args) throws Exception {
        CharStream inputStream = CharStreams.fromFileName("D:\\g4\\g4Test.txt", Charset.forName("UTF-8"));
        MathLexer lexer = new MathLexer(inputStream);
        CommonTokenStream token=new CommonTokenStream(lexer);
        MathParser parser=new MathParser(token);
        MathParser.ProgContext tree = parser.prog();
        tree.accept(new MathBaseVisitor<Object>(){
            @Override
            public Object visitPrintExpr(MathParser.PrintExprContext ctx) {
                return super.visitPrintExpr(ctx);
            }
        });
        System.out.println("g4执行结束");
    }
}

结果输出为:

line 5:4 extraneous input '*' expecting {'(', ID, INT}
g4执行结束

line 5:4? 这是第5行第4列有语法不匹配的情况。

正常去修改Math.g4文件。以匹配语法。

后续会继续补充...

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2021-07-14 23:09:10  更:2021-07-14 23:10:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 8:42:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码