编写自定义表达式解析器或使用ANTLR库?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写自定义表达式解析器或使用ANTLR库?相关的知识,希望对你有一定的参考价值。

我有如下表达式:

eg 1: (f1 AND f2)

eg 2: ((f1 OR f2) AND f3)

eg 3: ((f1 OR f2) AND (f3 OR (f4 AND f5)))

每个f(n)用于生成SQL片段,并且每个片段将使用表达式中描述的OR / AND连接。

现在我想:

1)解析这个表达式

2)验证它

3)为表达式生成“表达式树”,并使用此树生成最终的SQL。

我发现了一系列关于编写标记器,解析器的文章。如下:

http://cogitolearning.co.uk/2013/05/writing-a-parser-in-java-the-expression-tree/

我还遇到了库ANTLR,它想知道我是否可以用于我的案例。

有小费吗?

答案

我猜你可能只对Java感兴趣(将来这样说很好),但如果你有语言选择,那么我建议使用Python和parsy来完成这样的任务。它比ANTLR更轻盈。

下面是一些示例代码,它将您的示例解析为适当的数据结构:

import attr
from parsy import string, regex, generate


@attr.s
class Variable():
    name = attr.ib()


@attr.s
class Compound():
    left_value = attr.ib()
    right_value = attr.ib()
    operator = attr.ib()


@attr.s
class Expression():
    value = attr.ib()
    # You could put an `evaluate` method here,
    # or `generate_sql` etc.


whitespace = regex(r's*')
lexeme = lambda p: whitespace >> p << whitespace


AND = lexeme(string('AND'))
OR = lexeme(string('OR'))
OPERATOR = AND | OR
LPAREN = lexeme(string('('))
RPAREN = lexeme(string(')'))
variable = lexeme((AND | OR | LPAREN | RPAREN).should_fail("not AND OR ( )") >> regex("w+")).map(Variable)


@generate
def compound():
    yield LPAREN
    left = yield variable | compound
    op = yield OPERATOR
    right = yield variable | compound
    yield RPAREN

    return Compound(left_value=left,
                    right_value=right,
                    operator=op)


expression = (variable | compound).map(Expression)

我也使用attrs来处理简单的数据结构。

解析的结果是表达式的层次结构:

>>> expression.parse("((f1 OR f2) AND (f3 OR (f4 AND f5)))")
Expression(value=Compound(left_value=Compound(left_value=Variable(name='f1'), right_value=Variable(name='f2'), operator='OR'), right_value=Compound(left_value=Variable(name='f3'), right_value=Compound(left_value=Variable(name='f4'), right_value=Variable(name='f5'), operator='AND'), operator='OR'), operator='AND'))

以上是关于编写自定义表达式解析器或使用ANTLR库?的主要内容,如果未能解决你的问题,请参考以下文章

Json反序列化器或正则表达式或Json解析以在c#中转换Json字符串

创建在特定事件发生时调用的自定义 appsync 解析器或 lambda 函数

如何使用antlr实现自定义SQL语法

如何使用antlr实现自定义SQL语法

如何使用antlr实现自定义SQL语法

使用 TypeScript,React,ANTLR 和 Monaco Editor 创建一个自定义 Web 编辑器