如何解析前缀式“查询表示法”字符串?求现成工具或解析方案
解决方案
一、现成解析工具推荐
1. ANTLR
这是处理这类语法解析场景的首选工具,专门用于生成语法解析器,能轻松应对运算符优先级、嵌套表达式等复杂逻辑。实现步骤:
- 定义语法规则:明确运算符优先级(
NOT>AND>OR)、比较运算符的结构,示例语法片段:grammar QueryExpr; expr: NOT expr # NotExpr | AND expr expr # AndExpr | OR expr expr # OrExpr | COMPARE '(' ID ',' VALUE ')' # CompareExpr ; COMPARE: 'EQUAL' | 'GREATER_THAN' | 'LESS_THAN'; NOT: 'NOT'; AND: 'AND'; OR: 'OR'; ID: [a-zA-Z_][a-zA-Z0-9_]*; VALUE: '"' ~["]* '"' | [0-9]+; WS: [ \t\r\n]+ -> skip; - 用ANTLR生成Java解析器代码,自动生成词法分析器和语法分析器。
- 实现AST访问器:遍历生成的抽象语法树,将节点转换为对应的条件判断逻辑(如
EqualNode、AndNode),每个节点实现boolean evaluate(Item item)方法验证Item是否符合条件。 - 遍历Item列表,用AST根节点的
evaluate方法过滤结果。
2. JavaCC
和ANTLR类似的语法解析器生成工具,通过定义语法规则快速生成解析器,适合熟悉JavaCC语法的开发者。
3. Spring Expression Language (SpEL)
如果项目已使用Spring,可将前缀表达式转换为SpEL支持的中缀表达式(比如把OR(EQUAL(id,"id1"),AND(...))转为id == 'id1' || (views > 100 && id == 'id2')),再用SpEL的ExpressionParser解析评估Item。该方式适合简单场景,转换过程需处理嵌套结构。
二、手动解析思路(递归下降法)
若不想引入第三方工具,递归下降解析是适配前缀表达式的最优手动实现方案:
1. 词法预处理
- 去除字符串多余空格,处理引号包裹的字符串值(防止被逗号错误拆分)。
- 实现智能参数分割器:用计数器跟踪括号层级,仅当括号层级为0时的逗号才作为参数分隔符。比如
OR(EQUAL(id,"id1"),AND(GREATER_THAN(views,100),EQUAL(id,"id2")))会被拆分为EQUAL(id,"id1")和AND(GREATER_THAN(views,100),EQUAL(id,"id2"))两个参数。
2. 递归解析表达式
前缀表达式的结构天然适配递归处理,核心逻辑:
- 读取当前表达式的运算符(如开头的
OR、EQUAL等)。 - 提取运算符括号内的参数列表。
- 根据运算符类型递归处理参数:
- 比较运算符(EQUAL/GREATER_THAN/LESS_THAN):参数为字段名和值,直接生成对应的条件判断节点(如
EqualNode接收字段名id和值"id2")。 - 逻辑运算符:
NOT:一元运算符,递归解析唯一参数表达式,生成NotNode。AND/OR:二元运算符,递归解析两个参数表达式,生成AndNode或OrNode。
- 比较运算符(EQUAL/GREATER_THAN/LESS_THAN):参数为字段名和值,直接生成对应的条件判断节点(如
3. 构建表达式树并过滤数据
- 每个节点实现
evaluate(Item item)方法,比如EqualNode取出Item对应字段值与目标值比较;AndNode调用左右子节点的evaluate并返回逻辑与结果。 - 遍历Item列表,用根节点的
evaluate方法判断是否符合条件,收集结果。
优先级说明
前缀表达式的嵌套结构已天然体现优先级,比如OR(A, AND(B,C))中AND逻辑会先执行,再与OR结合,只要按递归结构解析,就能自动遵循NOT > AND > OR的优先级规则。
内容的提问来源于stack exchange,提问作者Eran Gabriel
相关产品推荐
相关产品推荐

