2010-04-30 100 views

回答

6

RegexpParsers允许您使用RE值(通常以"re pattern".r的形式,但同样也是其他任何Regex实例)。没有预先定义的词汇生成(令牌)。

JavaTokenParsers定义为Java令牌词法制作:decimalNumberfloatingPointNumberstringLiteralwholeNumberident(标识符)。

StandardTokenParsers定义词汇产生“...为一个简单的类似Scala的语言,它解析关键字和标识符,数字文字(整数),字符串和分隔符。其成分实际上在StdLexical中定义。

22

为了不同的目的,有几种不同的解析器特征和基类。

主要特征是scala.util.parsing.combinator.Parsers。这有大多数主要组合器,如opt,rep,elem,accept等。绝对查看这个文档,因为这是你需要知道的大部分内容。实际的Parser类在这里被定义为内部类,这也是很重要的。其他重要特征是scala.util.parsing.combinator.lexical.Scanners。这是解析器的基本特征,它读取字符流并产生一个令牌流(也称为词法分析器)。为了实现这个特性,你需要实现一个whitespace解析器,该解析器读取空白字符,注释等。你还需要实现一个token方法,该方法读取下一个标记。令牌可以是任何你想要的,但它们必须是Scanners.Token的子类。 Lexical延伸ScannersStdLexical延伸Lexical。前者提供了一些有用的基本操作(如digit,letter),而后者实际上定义和解释了常用的标记(如数字文字,标识符,字符串,保留字)。你只需要定义和reserved,你会得到一些对大多数语言有用的东西。令牌定义在scala.util.parsing.combinator.token.StdTokens

一旦你有了一个词法分析器,你可以定义一个解析器,它读取一个标记流(由词法分析器产生)并生成一个抽象语法树。分离词法分析器和分析器是一个好主意,因为您不需要担心语法中的空白或注释或其他复杂因素。如果您使用StdLexical,则可以考虑使用内置解析器的scala.util.parsing.combinator.syntax.StdTokenPasers将令牌转换为值(例如,StringLit转换为String)。我不确定与StandardTokenParsers有什么不同。如果您定义自己的令牌类,则应简单使用Parsers

您特别询问了有关RegexParsersJavaTokenParsersRegexParsers是一个扩展Parsers与一个额外的组合:regex,这完全符合你的期望。如果您想使用正则表达式来匹配令牌,请将RegexParsers混合到您的词法分析器中。JavaTokenParsers提供了一些解析器,它们从Java语法(如标识符,整数)中抽出令牌,但没有LexicalStdLexical的令牌行李。总之,您可能需要两个解析器:一个读取字符并生成标记,另一个读取标记并生成AST。首先使用基于LexicalStdLexical的东西。取决于您是否使用StdLexical,根据ParsersStdTokenParsers第二次使用。

相关问题