简体   繁体   English

Scala 解析器组合器与 ANTLR/Java 生成的解析器?

[英]Scala parser combinators vs ANTLR/Java generated parser?

I am writing an expression parser for an app written mostly in Scala.我正在为主要用 Scala 编写的应用程序编写表达式解析器。 I have built AST objects in Scala, and now need to write the parser.我已经在 Scala 中构建了 AST 对象,现在需要编写解析器。 I have heard of Scala's built-in parser combinators, and also of ANTLR3, and am wondering: which would provide better performance and ease of writing code?我听说过 Scala 的内置解析器组合器,也听说过 ANTLR3,我想知道:哪个会提供更好的性能和更容易编写代码? So far:迄今为止:

ANTLR pros ANTLR 优点

  1. Well-known知名
  2. Fast快速地
  3. External DSL外部DSL
  4. ANTLRWorks (great IDE for parser grammer debugging/testing) ANTLRWorks(用于语法分析器调试/测试的优秀IDE)

ANTLR cons ANTLR 的缺点

  1. Java-based (Scala interop may be challenging, any experience?)基于 Java(Scala 互操作可能具有挑战性,有经验吗?)
  2. Requires a large dependency at runtime在运行时需要很大的依赖

Parser combinator pros解析器组合器的优点

  1. Part of Scala斯卡拉的一部分
  2. One less build step少一个构建步骤
  3. No need for a runtime dependency;不需要运行时依赖; eg already included in Scala's runtime library例如已经包含在 Scala 的运行时库中

Parser combinator cons解析器组合器的缺点

  1. Internal DSL (may mean slower execution?)内部 DSL(可能意味着执行速度较慢?)
  2. No ANTLRWorks (provides nice parser testing and visualization features)没有 ANTLRWorks(提供很好的解析器测试和可视化功能)

Any thoughts?有什么想法吗?

EDIT: This expression parser parses algebraic/calculus expressions.编辑:这个表达式解析器解析代数/微积分表达式。 It will be used in the app Magnificalc for Android when it is finalized.最终确定后,它将在 Android 版 Magnificalc 应用程序中使用。

Scala's parser combinators aren't very efficient. Scala 的解析器组合器效率不高。 They weren't designed to be.它们不是被设计的。 They're good for doing small tasks with relatively small inputs.它们适合用相对较小的输入来完成小任务。

So it really depends on your requirements.所以这真的取决于你的要求。 There shouldn't be any interop problems with ANTLR. ANTLR 不应该有任何互操作问题。 Calling Scala from Java can get hairy, but calling Java from Scala almost always just works.从 Java 调用 Scala 可能会很麻烦,但从 Scala 调用 Java 几乎总是有效。

I wouldn't worry about the performance limitations of parser combinators unless you were planning on parsing algebraic expressions that are a few pages long.除非您打算解析几页长的代数表达式,否则我不会担心解析器组合器的性能限制。 The Programming Scala book does mention that a more efficient implementation of parser combinators is feasible. Programming Scala 一书确实提到解析器组合器的更有效实现是可行的。 Maybe somebody will find the time and energy to write one.也许有人会抽出时间和精力写一篇。

I think with ANTLR you are talking about two extra build steps: ANTLR compiles to Java, and you need to compile both Scala and Java to bytecode, instead of just Scala.我认为对于 ANTLR,您正在谈论两个额外的构建步骤:ANTLR 编译为 Java,并且您需要将 Scala 和 Java 编译为字节码,而不仅仅是 Scala。

I have created external DSLs both with ANTLRv4 and Scalas parser combinators and I clearly prefer the parser combinators, because you get excellent editor support when designing the language and it's very easy to transform your parsing results to any AST case class data structure.我已经使用 ANTLRv4 和 Scalas 解析器组合器创建了外部 DSL,我显然更喜欢解析器组合器,因为在设计语言时您可以获得出色的编辑器支持,并且很容易将解析结果转换为任何 AST 案例类数据结构。 Developing ANTLR grammars takes much more time, because, even with the ANTLRWorks editor support, developing grammars is very error-prone.开发 ANTLR 语法需要更多时间,因为即使有 ANTLRWorks 编辑器支持,开发语法也很容易出错。 The whole ANTLR workflow feels quite bloated to me compared to the parser combinators' one.与解析器组合器的工作流程相比,整个 ANTLR 工作流程让我感觉非常臃肿。

I would be inclined to try to produce an external DSL using parser combinators.我倾向于尝试使用解析器组合器生成外部DSL。 It shouldn't need to be an internal DSL.它不需要是内部 DSL。 But I don't know that it would be better.但我不知道这样会更好。

The best approach to figuring this out would be to take a simplified version of the grammar, try it both ways and evaluate the differences.解决这个问题的最佳方法是采用语法的简化版本,尝试两种方式并评估差异。

Just been writing a parser for a home brew 8 bit CPU assembler.刚刚为自制 8 位 CPU 汇编器编写解析器。

I got so far with Antlr4 before feeling that there had to be a better way.在觉得必须有更好的方法之前,我已经使用 Antlr4 走了这么远。 I decided to have a go at Scala parser combinators and have to say that it is way more productive IMHO.我决定尝试一下 Scala 解析器组合器,不得不说它的效率更高,恕我直言。 However, I do know scala.但是,我确实知道 Scala。

If you still interested about an integer expression parser please take a look at my example interpreter here: https://github.com/scala-szeged/hrank-while-language .如果您仍然对整数表达式解析器感兴趣,请在此处查看我的示例解释器: https : //github.com/scala-szeged/hrank-while-language It is 200 hundred lines Scala code using the officail parser combinators.这是使用官方解析器组合器的 20000 行 Scala 代码。 It has expression parsing.它有表达式解析。 It also handle nested if, nested while, variables, and boolean expressions.它还处理嵌套 if、嵌套 while、变量和布尔表达式。 I also implemented array handling in this github repository.我还在这个 github 存储库中实现了数组处理。 If you need String handling I can help you, too.如果您需要字符串处理,我也可以帮助您。

An other, somewhat more simple expression parser is also present here in my other public repository https://github.com/scala-szeged/top-calc-dsl另一个更简单的表达式解析器也存在于我的其他公共存储库https://github.com/scala-szeged/top-calc-dsl

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM