parsing - Scala中Regex Parsers,Standard TokenParsers和JavaTokenParsers之间的区别

标签 parsing scala

我正在学习 scala 中的 Parser Combinators 并看到不同的解析方式。我主要看到三种不同类型的解析器,即 RegexpParsers、StandardTokenParsers 和 JavaTokenParsers。我是解析新手,不知道如何根据我们的选择合适的解析器要求。谁能解释一下这些不同的解析器是如何工作的以及何时使用它们。

最佳答案

有几种不同的解析器特征和基类用于不同的目的。

主要特征是scala.util.parsing.combinator.Parsers .这具有大多数主要组合符,例如 opt , rep , elem , accept等。一定要查看此文档的文档,因为这是您需要了解的大部分内容。实际Parser class 在这里被定义为内部类,这也很重要。

另一个重要特征是scala.util.parsing.combinator.lexical.Scanners .这是读取字符流并生成标记流(也称为词法分析器)的解析器的基本特征。为了实现这个特性,你需要实现一个 whitespace解析器,它读取空白字符、注释等。您还需要实现 token方法,它读取下一个 token 。 token 可以是任何你想要的,但它们必须是 Scanners.Token 的子类. Lexical扩展 ScannersStdLexical扩展 Lexical .前者提供了一些有用的基本操作(如 digitletter ),而后者实际定义和词法化常见标记(如数字文字、标识符、字符串、保留字)。您只需定义 delimitersreserved , 你会得到对大多数语言有用的东西。 token 定义位于 scala.util.parsing.combinator.token.StdTokens .

一旦有了词法分析器,就可以定义一个解析器,它读取标记流(由词法分析器生成)并生成抽象语法树。分离词法分析器和解析器是一个好主意,因为您无需担心语法中的空格或注释或其他复杂情况。如果您使用 StdLexical ,您可以考虑使用 scala.util.parsing.combinator.syntax.StdTokenPasers它具有内置的解析器以将标记转换为值(例如, StringLitString )。我不确定与 StandardTokenParsers 有什么区别.如果您定义自己的 token 类,您应该只使用 Parsers为简单起见。

您专门询问了RegexParsersJavaTokenParsers . RegexParsers是扩展 Parsers 的特征加上一个额外的组合器:regex ,这正是您所期望的。混入RegexParsers如果您想使用正则表达式来匹配标记,请发送给您的词法分析器。 JavaTokenParsers提供了一些解析器,它们从 Java 语法(如标识符、整数)中提取标记,但没有 Lexical 的标记包袱。或 StdLexical .

总而言之,您可能需要两个解析器:一个读取字符并生成标记,另一个获取标记并生成 AST。使用基于 Lexical 的东西或 StdLexical为了第一。使用基于 Parsers 的东西或 StdTokenParsers第二个取决于您是否使用 StdLexical .

关于parsing - Scala中Regex Parsers,Standard TokenParsers和JavaTokenParsers之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2743835/

相关文章:

Java:StreamWriter 和 BufferWriter 有什么区别?

scala - 在 Scala IDE 中运行简单的 Spark 代码

scala - 在没有继承层次结构的scala中编写通用代码

scala - 将单例对象编码为惰性值

python - python 中的 XML 解析 : expaterror not well-formed

ios - 如何在iOS中修复此字符串格式?

xml - JSTL - 解析不适​​用于具有命名空间的元素

javascript - 使用 jquery/javascript 从 Yahoo 管道解析 json

scala - 在 Scala 中正确扩展 Java 异常的最佳方法是什么?

scala - 在意想不到的地方需要类型转换