Parsing scala中RegExpParser、StandardTokenParser和JavaTokenParser之间的差异

Parsing scala中RegExpParser、StandardTokenParser和JavaTokenParser之间的差异,parsing,scala,Parsing,Scala,我正在学习scala中的解析器组合器,并看到了不同的解析方法。我主要看到了三种不同类型的解析器,即RegexpParsers,StandardTokenParsers和JavaTokenParsers。我不熟悉解析,不知道如何根据我们的要求选择合适的解析器。请任何人解释一下这些不同的解析器是如何工作的,以及何时使用它们。RegexpParsers允许您使用RE值(通常以“RE模式”的形式).r但同样适用于任何其他正则表达式实例)。没有预定义的词法结果(标记) JavaTokenParsers定义

我正在学习scala中的解析器组合器,并看到了不同的解析方法。我主要看到了三种不同类型的解析器,即RegexpParsers,StandardTokenParsers和JavaTokenParsers。我不熟悉解析,不知道如何根据我们的要求选择合适的解析器。请任何人解释一下这些不同的解析器是如何工作的,以及何时使用它们。

RegexpParsers
允许您使用RE值(通常以
“RE模式”的形式).r
但同样适用于任何其他正则表达式实例)。没有预定义的词法结果(标记)

JavaTokenParsers
定义Java令牌的词法生成:
decimalNumber
floatingPointNumber
stringLiteral
wholeNumber
ident
(标识符)


StandardTokenParsers
为一种简单、类似Scala的语言定义了词法结果“…它解析关键字和标识符、数字文本(整数)、字符串和分隔符。”它的组成部分实际上是在StdLexical中定义的,有几个不同的解析器特性和基类用于不同的目的

主要特点是
scala.util.parsing.combinator.Parsers
。这有许多主要的组合词,如
opt
rep
elem
accept
,等等。请仔细阅读文档,了解这一组合,因为这是您需要了解的大部分内容。实际的
解析器
类在这里被定义为一个内部类,这一点也很重要

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

一旦有了lexer,就可以定义一个解析器来读取令牌流(由lexer生成)并生成一个抽象语法树。分离lexer和解析器是一个好主意,因为您不需要担心语法中的空格、注释或其他复杂问题。如果您使用<代码> STDCONTROON/COMPUT>,您可以考虑使用<代码> Scala、UTI.Palsix.Copulal.Stry.SttotoKePases<代码>,它内置了解析器来将令牌转换成值(例如,<代码> StringLit <代码> > <代码>字符串< /代码>)。我不确定
StandardTokenParser
有什么区别。如果您定义自己的令牌类,为了简单起见,您应该只使用
解析器

您特别询问了
RegexParsers
JavaTokenParsers
RegexParsers
是一种特性,它通过一个额外的组合词扩展了
parser
regex
,这正是您所期望的。如果要使用正则表达式匹配标记,请将
RegexParsers
混合到lexer中
JavaTokenParsers
提供了一些解析器,这些解析器从Java语法(如标识符、整数)中提取标记,但没有
Lexical
StdLexical
的标记包袱

总之,您可能需要两个解析器:一个用于读取字符并生成标记,另一个用于获取标记并生成AST。首先使用基于
词法
StdLexical
的内容。根据您是否使用
StdLexical
使用基于
解析器或
StdTokenParsers
的内容