我需要使用ANTLR并将给定的表达式转换为它的spring表达式语言等价物。下面是一组简单的示例输入和输出表达式。
输入:(account='233AS77')AND(code='SIMP')AND(cost=270)
输出SpEL:(account.equalsIgnoreCase(“233AS77”))和(code.equalsIgnoreCase(“SIMP”))和(cost eq 270)
我该怎么做?有人可以帮助我开始吗?我熟悉SpEL,但对ANTLR及其概念完全陌生。一个例子,片段或引用一个坚实的文章来理解ANTLR将是惊人的。
1条答案
按热度按时间jei2mxaa1#
我很晚才回答这个问题,主要是为了子孙后代(以及我最近重新燃起的对ANTLR的兴趣)。
我将原始问题中描述的问题整理成一个简单但完整的implementation,包括一个可行的、基于Maven的项目设置。
有几个ANTLR的介绍,但只有少数是值得你花时间,从official documentation开始(沿着The Definitive ANTLR 4 Reference,尽管它的出版日期并没有过时),并继续与Strumenta的ANTLR Mega Tutorial和Baeldung的短,但to-the-point tutorial。当然,在我使用ANTLR的经验,遵循和理解别人的示例通常比编写自己的语法和语言应用程序更直接。此外,你不能不先做点阅读就直接写一个“语言应用程序”(尽管使用ANTLR,并不需要很多)。我将尝试在下面总结这件事的要点,并带领你完成我的实现。
ANTLR(或者更准确地说,*ANTLR工具 *)是一个 * 解析器生成器 *。这意味着你给它一个 * 语法 *,一个对你所定义的语言中所有可能的句子结构的正式文本描述;它就产生了(在一个或几个所谓的 * 目标语言 * 中,Java是其中之一)能够分析用该“输入”语言编写的程序的 * 解析器 * 的代码。当被应用程序的代码调用时,生成的解析器尝试 * 匹配 * 其输入数据(不一定是文本的,但也可以是二进制的),成功后,它会构建一个 * 解析树 *,一个输入的结构化表示。您的应用程序可以使用一个自定义访问器来遍历该树(查看Visitor design pattern上的复习资料)或 *ANTLR运行时 * 提供的
ParseTreeWalker
。在前一种情况下,自定义访问器扩展ANTLR工具沿着分析器生成的基本访问器,并覆盖与各种分析树节点对应的方法使用后一个选项,您可以实现 listener 方法来处理您感兴趣的树节点(请参阅观察者/侦听器设计模式)。请注意,在第二种情况下,您还将获得一个生成的基本侦听器,概述ParseTreeWalker
将调用的可用方法。更准确地说,您需要:
1.将 *ANTLR工具 * 集成到应用程序构建管道中;毫无疑问,您可以在构建应用程序之前偶尔根据语法执行该工具以生成解析器源代码。然而,更好的做法是将解析器源代码生成集成到构建管道中。(或Gradle),您可以使用antlr 4-maven-plugin,其默认值基本没问题。请注意,您必须同时指定
-package
(ANTLR)选项和输出目录,以根据包定义(假设您在语法中定义了包)在文件结构中生成解析器。1.添加 *ANTLR运行时 * 作为项目的编译时依赖项。它包含生成的解析器、访问者、侦听器甚至您的代码都可以使用的类(例如,错误处理策略等)。
1.为你想定义的语言写一个语法;语法是一组词法和句法规则,定义了解析器将如何尝试匹配其输入。在这种情况下,您需要将grammar for the simple expression翻译为SpEL表达式。请注意,一般来说,没有一种语法可以完成这项工作,而是有几种语法可以工作。特别是当您从语言定义开始时,您经常重新组织语法规则;因此,需要在构建管道中集成解析器生成。
1.编写一个监听器或自定义访问器来处理感兴趣的解析树节点。所谓“处理”,我的意思是将解析树结构翻译成另一种语言,like in our use case,生成代码,解释表达式等。
1.将创建、定制和调用解析器示例所涉及的基本对象粘合在一起,然后遍历生成的解析树以生成所需的输出。