Java的Javascript解析器

时间:2011-06-28 18:47:01

标签: java javascript parsing

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

6 个答案:

答案 0 :(得分: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.   
  3. 不解析Firefox样式catch (<Identifier> if <Expression>),因为它们不适用于IE和许多其他解释器。
  4.   
  5. 认识const,因为许多口译员都做(不是IE),但发出警告。
  6.   
  7. 允许(但警告)ArrayObject构造函数中的尾随逗号。
  8.   
  9. 允许关键字作为标识符名称但发出警告,因为不同的解释器具有不同的关键字集。这允许我们使用扩展的关键字集。
  10.         

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


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

答案 1 :(得分: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();

一旦运行此代码,您将在&#39;语句中使用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;

您可能需要添加访问规则才能使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

答案 2 :(得分:4)

之前的回答描述了一种了解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。

答案 3 :(得分:2)

以下是两个ANTLR或多或少的工作或完成(请参阅此帖子的评论)EcmaScript的语法:

来自ANTLR 5 minute intro

  

ANTLR读取一个称为语法的语言描述文件,并生成许多源代码文件和其他辅助文件。 ANTLR的大多数用途至少会产生一种(通常是两种)工具:

     
      
  • Lexer:它读取输入字符或字节流(即字符,二进制数据等),使用您指定的模式将其划分为标记,并生成标记流作为输出。它还可以使用ANTLR解析器自动理解和尊重的协议将一些标记(如空格和注释)标记为隐藏。

  •   
  • A Parser:它读取令牌流(通常由词法分析器生成),并通过您指定的规则(模式)匹配您的语言中的短语,并且通常对每个短语(或子句)执行一些语义操作短语)匹配。每个匹配都可以调用自定义操作,通过StringTemplate编写一些文本,或生成抽象语法树以进行其他处理。

  •   

答案 4 :(得分:1)

对我来说,最好的解决方案是在犀牛下使用橡子 - https://github.com/marijnh/acorn

我只是觉得caja不再受到关注了。

答案 5 :(得分:0)

java https://github.com/DigiArea/es5-model

的EcmaScript 5解析器