这篇文章分享如何用antlr解析odata filter条件表达式。

我最早接触antlr,是在刚开始工作后不久,那次需要用antlr实现一个功能:把gemfire的OQL(object query language)翻译成SQL语句,以便进行数据库操作。其实,简单讲,antlr就是一个非常方便的词法分析和语法分析的类库,基于这个类库,可以很容易的实现很多场景,比如计算器算术表达式的解析、各种编程语言的解析等。

印象很深刻的记得,大学编译原理的课程里面就有类似的两个练习,一个是实现计算器算术表达式的解析,一个是实现C-语言(C语言的简化版)的解析,当时肯定是需要自己手动实现,不能借助这些类库,那如何做的呢?一个很关键的点是状态机,在真正开始实现功能之前,需要根据具体问题的需求画一个状态机(个人觉得和状态图有些类似,或者说是状态图的一种形式),用状态机来描述哪些字符连一起可以构成哪种token,基于这个状态机就可以很方便的实现词法解析。其实,状态机在很多其它地方也有用途,比如:订单的状态变化,其实就可以用状态机来定义。

除了上面提到的场景,还有两个我们平时经常碰到的场景:json解析和html在线编辑器,它们都可以用antlr来实现。

具体odata filter条件表达式的定义可以参考odata官方文档,这里为了描述问题方便,简化基本规则如下:

最小的表达式符合模式 key operator value

表达式和表达式可以用逻辑运算符连接成一个新的表达式 expression AND expression

表达式的前后可以加括号以提高优先级 (expression OR expression) AND expression

根据上面的规则,下面列举几个例子:

1.$filter=Name eq 'John' //查询所有name等于John的人

2.$filter=Name eq 'John' AND age ge 30 //查询所有name等于John并且年龄大于等于30岁的人

3.$filter=(firstName eq 'John' OR firstName eq 'Bill') AND lastName eq 'Smith' //查询所有名为John或Bill,姓为Smith的人

那么,如何解析上面定义的规则呢?

首先,有一种方案:利用关键字(比如eq, AND等)来split这个filter string,在比较简单的情况下也许这个方案可行,但是如果有表达式嵌套的情况(上面第三个例子),直接split string就会有些显得力不从心。

其实,我们可以看到odata filter条件表达式和计算器的算术表达式有些类似,它们都是非常典型的词法分析和语法分析案例,所以同样可以采用antlr来解析。

如果大家以前没有接触过antlr,网上有很多关于它的资料,大家可以自行网上搜索(包括antlr官网https://www.antlr.org/)。下面仅分享一些我使用antlr(antlr 4)解析odata filter条件表达式的经验总结:

antlr的简单使用流程:定义grammar->生成对应语言(比如c#)的词法和语法分析代码->实现自己的Visitor遍历抽象语法树AST(abstract syntax tree)。

词法定义规则须大写打头,语法定义规则须小写打头。

从antlr 4.7开始,提供了对所有unicode的支持。关于这个,举一个实际的例子:由于.NET里面的正则表达式\w可以match很多国家的字符(具体有哪些,see https://docs.microsoft.com/en-us/dotnet/standard/base-types/character-classes-in-regular-expressions#WordCharacter),如果我们需要odata filter条件表达式里面的key也支持\w可以match的字符,怎么做呢?那得益于antlr对Unicode的支持,可以像下面这样定义key:

fragment VALID_ID_CHAR : [\p{General_Category=Other_Letter}\p{General_Category=Lowercase_Letter}\p{General_Category=Uppercase_Letter}\p{General_Category=Titlecase_Letter}\p{General_Category=Modifier_Letter}\p{General_Category=Nonspacing_Mark}\p{General_Category=Connector_Punctuation}\p{General_Category=Decimal_Number}] ;

从antlr 4.5开始,c#的runtime换成了Antlr4.Runtime.Standard;之前的版本是用Sam Harwell提供的一个Runtime。参考https://github.com/antlr/antlr4/tree/master/runtime/CSharp。

Intellij的antlr的插件提供了实时preview的功能,非常方便调试;VS的插件则没有这功能。

关于odata filter条件表达式的示例grammar文件,可以参考https://github.com/huazailmh/ODataFilterParser。

References

Antlr basics:

Unicode support:

java odata filter_用antlr解析odata filter条件表达式相关推荐

  1. Java中高级核心知识全面解析——什么是Spring Cloud、需要掌握哪些知识点?(下)

    目录 一.必不可少的 Hystrix 1.什么是 Hystrix之熔断和降级 2.什么是Hystrix之其他 二.微服务网关--Zuul 1.Zuul 的路由功能 1)简单配置 2)统一前缀 3)路由 ...

  2. 23道易忽略的java面试题及答案解析

    23道易忽略的java面试题及答案解析 转载:https://mp.weixin.qq.com/s/aL1xHKDfpojVVUOsdbvPzQ 1.你认为项目中最重要的过程是那些? 分析.设计阶段 ...

  3. Java中的static关键字解析 转载

    原文链接:http://www.cnblogs.com/dolphin0520/p/3799052.html Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到 ...

  4. java蓝桥杯凑算是,第七届蓝桥杯JAVA B组真题解析-凑算式(第三题)

    第七届蓝桥杯JAVA B组真题解析-凑算式(第三题) 凑算式 A+B/C+DEF/GHI =10 (如果显示有问题,可以参见[图1.jpg]) 这个算式中AI代表19的数字,不同的字母代表不同的数字. ...

  5. Java IO: 字符流的Buffered和Filter

    作者: Jakob Jenkov  译者: 李璟(jlee381344197@gmail.com) 本章节将简要介绍缓冲与过滤相关的reader和writer,主要涉及BufferedReader.B ...

  6. JAVA方法调用中的解析与分派

    JAVA方法调用中的解析与分派 本文算是<深入理解JVM>的读书笔记,参考书中的相关代码示例,从字节码指令角度看看解析与分派的区别. 方法调用,其实就是要回答一个问题:JVM在执行一个方法 ...

  7. 2013第四届蓝桥杯Java组省赛题解析

    2013第四届蓝桥杯Java组省赛题解析 目录 第一题:高斯日记 第二题:马虎的算式 第三题:第39级台阶 第四题:黄金连分数 ​第五题:前缀判断 第六题:三部排序 ​第七题:错误票据 第八题:翻硬币 ...

  8. [转] Java中的static关键字解析

    Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...

  9. Java基础之多态深入解析

    Java基础之多态深入解析 多态的基本概念 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性.简单的说:就是用基类的引用指向子类的对象. 多态的优点 消除类型之间的耦合关系 ...

最新文章

  1. 排好序的数组中,找出两数之和为m的所有组合
  2. ssm jsp跳转jsp_去掉Shiro默认login.jsp跳转
  3. 【Linux】gcc -o 什么意思
  4. 素数判定算法 MILLER RABIN
  5. 两岸三地在线编程学习网站大全
  6. 新兴IT企业特斯拉(四)——Model 3
  7. 数学建模之优化模型详解
  8. 做数据分析不得不看的书有哪些?
  9. SpriteKit快速入门和新时代iOS游戏开发指南
  10. 交换机端口镜像配置大全【汇集 22个各种品牌交换机】
  11. 利用Python爬取3万多条上海二手房信息,我得出的结论是?
  12. 猫眼IPO后,在线票务平台或抛弃补贴战,未来看电影又贵了?
  13. matlab心电显示,请问如何在GUI界面中打开并显示心电信号
  14. chm 文件的阅读、制作和反编译
  15. Hololens2画面传输到电脑上的方法(Hololens2录视频下载方法)
  16. Android攻城狮四大组件之Service
  17. PPT自动翻页的实现和取消
  18. 初探Java反序列化漏洞
  19. jquery:toggle()方法模拟鼠标连续click事件
  20. Week2 Assignment - Princeton-Algorithms-PartI

热门文章

  1. 在Ubuntu18.04安装GMT-6.1.1(在 Linux 下编译 GMT 源代码)
  2. 常用分析模型 ---用户行为分析漏斗分析模型
  3. 北京2022冬奥会落下帷幕,东方旗龙旗杆闪耀赛场
  4. 将matlab数据保存为excel文件
  5. Android API Level与sdk版本对照表
  6. [MUI专题] 上手MUI
  7. 未来,智能交通有多智能?
  8. Echarts loading 动画
  9. matlab call lapack,科学网—fortran lapack的dgesvd和matlab SVD结果不一致,请大神指点! - 周锋的博文...
  10. FTPClient实现ftp的上传和下载