强大的ANTLR4语法解析器入门demo

前言

最近在寻觅搜索查询中可以对查询语句进行解析的一个工具,然后偶然就发现了这个ANTLR4 (语法用到了正则,有多个语言的支持,你常用的很多SQL的解析都用到他了)。当然语法解析我是一窍不通的,本篇只是简单的通过一个demo来说下简单的使用。官方示例

简单的回顾下正则

因为ANTLR4语法用到了正则

  • | 表示或(多个可以匹配的条件)
    • 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *
  • ? 配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。
    • 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。
  • ~ 表示取反
  • 范围运算符:.. 或者 -,比如小写字母的表示:'a'..'z' 或者 [a-z]

工具的简单使用

1.IDEA中安装插件

2.简单的分析个查询解析的demo

  • 1.查询单词
  • 2.-是排除特定的单词
  • 3.site:是限定某个范围
  • 4.复杂点的可能就看不懂了,因为各种变量定义到处都是的只不过不妨碍入门(工具嘛先会拿来用
txt 复制代码
//必填项
//文件名为SearchQuery.g4
grammar SearchQuery;

//注意下面定义了很多变量声明
//其实就是定义别名数据、然后使用

//必填项
// 整个查询语句由多个 term 构成 (term为空格隔开的单词)
searchQuery
 : searchTerm* EOF
 ;
 
//匹配的查询内容 必须项
//这里意思每个term可以是site开头的限定域;
//也可以是-开头的排除数据
//每个term是一个单词
searchTerm
 : SITE_INCLUDE
 | SITE_EXCLUDE
 | WORD
 ;

// 匹配包含 site: 但不以 - 开头的项 => 表示包含
//site: 开头后接一个或多个字母、数字、点、冒号、斜杠、减号或下划线的字符串,用于识别类似网站地址的标记。
SITE_INCLUDE
 : 'site:' [a-zA-Z0-9.:/\-_]+
 ;

// 匹配 -site: 开头的项 => 表示排除
SITE_EXCLUDE
 : '-'[a-zA-Z0-9.:/\-_]+
 ;

// 普通词
//因为ANTLR4 不支持\S 所以写成了下面的这种方式
WORD
 : ~[ \t\r\n]+
 ;

// 空格忽略
WS
 : [ \t\r\n]+ -> skip
 ;

3.用安装的插件(ANTLR4)可以进行查看语法树和对写的文件进行一个验证

4.用安装的ANTLR4插件可以进行代码生成

  • 需要填些生成文件的路径和报名

5.实现自己的逻辑

  • 这里生成代码例子是我在网上找的两个个计算器的例子。生成的代码文件名都是固定的

  • 生成代码后,我们还需要要实现自己的逻辑处理(继承后实现自己的逻辑,生成的是默认)

  • ((下面图片右边的东西,可以不指定(就是我们写的变量名)也可以前面是表达式后面用#指定

  • 重写的方法就是上图右侧的四个方法

typescript 复制代码
public class MyCalculatorVisitor extends CalculatorBaseVisitor<Object> {
    @Override
    public Object visitParenExpr(CalculatorParser.ParenExprContext ctx) {
        return visit(ctx.expr());
    }
 
    @Override
    public Object visitMultOrDiv(CalculatorParser.MultOrDivContext ctx) {
        Object obj0 = ctx.expr(0).accept(this);
        Object obj1 = ctx.expr(1).accept(this);
 
        if ("*".equals(ctx.getChild(1).getText())) {
            return (Float) obj0 * (Float) obj1;
        } else if ("/".equals(ctx.getChild(1).getText())) {
            return (Float) obj0 / (Float) obj1;
        }
        return 0f;
    }
 
    @Override
    public Object visitAddOrSubstract(CalculatorParser.AddOrSubstractContext ctx) {
        Object obj0 = ctx.expr(0).accept(this);
        Object obj1 = ctx.expr(1).accept(this);
 
        if ("+".equals(ctx.getChild(1).getText())) {
            return (Float) obj0 + (Float) obj1;
        } else if ("-".equals(ctx.getChild(1).getText())) {
            return (Float) obj0 - (Float) obj1;
        }
        return 0f;
    }
 
    @Override
    public Object visitFloat(CalculatorParser.FloatContext ctx) {
        return Float.parseFloat(ctx.getText());
    }
}

 public static void main(String[] args) {
        String query = "3.1 * (6.3 - 4.51) + 5 * 4";
        //创建一个词法分析器,用于将输入转换为标记
        CalculatorLexer lexer = new CalculatorLexer(new ANTLRInputStream(query));
        // 创建一个解析器,用于将标记转换为AST
        CalculatorParser parser = new CalculatorParser(new CommonTokenStream(lexer));
        // 创建一个AST遍历器,用于计算表达式的值
        CalculatorVisitor visitor = new MyCalculatorVisitor();
        System.out.println(visitor.visit(parser.expr()));  // 25.549
    }
相关推荐
道之极万物灭15 小时前
Go小工具合集
开发语言·后端·golang
瑞士卷@15 小时前
MyBatis入门到精通(Mybatis学习笔记)
java·数据库·后端·mybatis
yuuki23323315 小时前
【C语言】文件操作(附源码与图片)
c语言·后端
IT_陈寒15 小时前
Python+AI实战:用LangChain构建智能问答系统的5个核心技巧
前端·人工智能·后端
无名之辈J16 小时前
系统崩溃(OOM)
后端
码农刚子16 小时前
ASP.NET Core Blazor简介和快速入门 二(组件基础)
javascript·后端
间彧16 小时前
Java ConcurrentHashMap如何合理指定初始容量
后端
catchadmin16 小时前
PHP8.5 的新 URI 扩展
开发语言·后端·php
少妇的美梦16 小时前
Maven Profile 教程
后端·maven
白衣鸽子16 小时前
RPO 与 RTO:分布式系统容灾的双子星
后端·架构