Java的Javascript解析器

xyb*_*rek 33 javascript java parsing

任何人都可以为Java推荐一个像样的Javascript解析器?我相信Rhino可以使用,但是对于解析来说似乎有点过分,或者它是唯一合适的解决方案?任何建议将不胜感激.谢谢.

Mik*_*uel 12

来自https://github.com/google/caja/blob/master/src/com/google/caja/parser/js/Parser.java

下面的语法是这个解析器解析的语法的无上下文表示.它不同意EcmaScript 262 Edition 3(ES3),其中实现不同意ES3.分号插入的规则和正确处理回溯所需的表达式中可能的回溯在代码中得到了彻底的评论,因为分号插入需要来自词法分析器和解析器的信息,并且无法通过有限前瞻来确定.

值得注意的功能

  1. 报告队列上的警告,其中错误不会阻止任何进一步的错误,这样我们就可以在单个编译过程中报告多个错误,而不是强迫开发人员玩whack-a-mole.
  2. 不解析Firefox样式,catch (<Identifier> if <Expression>)因为那些不适用于IE和许多其他解释器.
  3. 认识到,const因为许多口译员(不是IE),但警告.
  4. 允许,但警告,尾随逗号ArrayObject构造函数.
  5. 允许关键字作为标识符名称,但警告,因为不同的解释器具有不同的关键字集 这允许我们使用扩展的关键字集.

要解析严格的代码,请传入一个PedanticWarningMessageQueue转换为MessageLevel#WARNING及以上的代码MessageLevel#FATAL_ERROR.


CajaTestCase.js演示如何设置解析器,同一类中的[ fromResource]和[ fromString]显示如何获得正确类型的输入.


Luk*_*ski 11

使用Java V1.8时,您可以使用一种技巧来解析框中出现的Nashorn实现.通过查看OpenSDK源代码中的单元测试,您可以看到如何仅使用解析器,而无需进行所有额外的编译等...

Options options = new Options("nashorn");
options.set("anon.functions", true);
options.set("parse.only", true);
options.set("scripting", true);

ErrorManager errors = new ErrorManager();
Context context = new Context(options, errors, Thread.currentThread().getContextClassLoader());
Source source   = new Source("test", "var a = 10; var b = a + 1;" +
            "function someFunction() { return b + 1; }  ");
Parser parser = new Parser(context.getEnv(), source, errors);
FunctionNode functionNode = parser.parse();
Block block = functionNode.getBody();
List<Statement> statements = block.getStatements();
Run Code Online (Sandbox Code Playgroud)

运行此代码后,您将在"语句"列表中获得3个表达式的抽象语法树(AST).

然后可以根据您的需要对其进行解释或操作.

上一个示例适用于以下导入:

import jdk.nashorn.internal.ir.Block;
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.Statement;
import jdk.nashorn.internal.parser.Parser;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.options.Options;
Run Code Online (Sandbox Code Playgroud)

您可能需要添加访问规则才能jdk/nashorn/internal/**访问.


在我的上下文中,我使用Java Script作为我自己的域特定语言(DSL)的表达式语言,然后我将在运行时编译为Java类并使用它.AST允许我生成适当的Java代码来捕获Java Script表达式的意图.


Nashorn适用于Java SE 8.

有关获取Nashorn源代码的信息的链接如下:https: //wiki.openjdk.java.net/display/Nashorn/Building+Nashorn


Luk*_*ski 5

之前的答案描述了一种深入 JDK 8 来解析 javascript 的方法。他们现在正在 Java 9 中对其进行主线处理。太好了!

这意味着您不需要包含任何库,相反,我们可以依赖 Java 人员的官方实现。以编程方式解析 javascript 更容易实现,而无需进入 Java 代码的禁忌区域。

这种应用程序可能是您希望将 javascript 用于规则引擎的地方,该引擎在运行时被解析并编译成其他语言。AST 让你“理解”用简洁的 javascript 语言编写的逻辑,然后用其他语言或框架生成不太漂亮的逻辑来执行或评估。

http://openjdk.java.net/jeps/236

来自上面链接的摘要:

为 Nashorn 的 ECMAScript 抽象语法树定义一个受支持的 API。

目标

  • 提供接口类来表示 Nashorn 语法树节点。
  • 提供一个工厂来创建一个配置的解析器实例,配置通过 API 传递 Nashorn 命令行选项来完成。
  • 提供一个访问者模式 API 来访问 AST 节点。
  • 提供示例/测试程序以使用 API。

非目标

  • AST 节点将尽可能表示 ECMAScript 规范中的概念,但它们不会完全相同。ECMAScript 将尽可能采用 javac 树 API 的接口。
  • 不会使用外部解析器/树标准或 API。
  • 将没有脚本级解析器 API。这是一个 Java API,尽管脚本可以调用 Java 并因此使用此 API。