强大的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
    }
相关推荐
paopaokaka_luck10 分钟前
英语单词学习系统的设计与实现(基于艾宾浩斯遗忘曲线的智能复习机制、语音朗读、多题型测试与错题自动收录、Echarts图形化分析)
vue.js·spring boot·后端·echarts
我叫黑大帅1 小时前
MySQL 并发插入竞态问题:原子写入实践指南
后端·mysql·面试
zhangxingchao2 小时前
AI大模型核心八:从 Agent Skill、长文档 RAG 到知识库更新与训练策略
前端·人工智能·后端
我叫黑大帅2 小时前
别再手动写 updated_at了,这坑我踩过
后端·面试·go
zhangxingchao2 小时前
AI大模型核心七:从 Workflow、RAG、记忆治理到幂等性
前端·人工智能·后端
犀利豆4 小时前
AI in Harness(二)
java·人工智能·后端
IT_陈寒4 小时前
Python装饰器竟然偷偷改了函数名?这个坑我爬了三天
前端·人工智能·后端
Elastic 中国社区官方博客4 小时前
Elastic 在 Everest Group 企业搜索产品 PEAK Matrix® 评估 2026 中被评为领导者
大数据·运维·人工智能·elasticsearch·搜索引擎·ai·全文检索
bkl_92134 小时前
GPT-Image-2 文生图:如何稳定生成完整的人物全身照?
后端·gpt·restful
jy4 小时前
支付后端研发的 AI 工作流实践:巡检、排查、开发全流程落地
后端·ai编程