我正在学习Scala中的Parser Combinators,并且看到了不同的解析方法.我主要看到三种不同类型的解析器,即.gegexpParsers,StandardTokenParsers和JavaTokenParsers.我是解析的新手,并没有根据我们的想法选择合适的Parser.要求.任何人都可以解释这些不同的解析器如何工作以及何时使用它们.
Jay*_*rod 22
有几种不同的解析器特征和基类用于不同的目的.
主要特点是scala.util.parsing.combinator.Parsers.这有大部分主力组合子像opt,rep,elem,accept,等绝对寻找这一个文件过来,因为这是你最需要知道的.实际Parser的类在这里定义为内部类,这也是重要的.
另一个重要特征是scala.util.parsing.combinator.lexical.Scanners.这是解析器读取字符流并生成标记流(也称为词法分析器)的基本特征.为了实现这个特性,你需要实现一个whitespace解析器,它可以读取空格字符,注释等.你还需要实现一个token读取下一个标记的方法.标记可以是你想要的任何东西,但它们必须是它的子类Scanners.Token.Lexical扩展Scanners和StdLexical扩展Lexical.前者提供了一些有用的基本操作(如digit,letter),而后者实际上定义和修饰了常见的令牌(如数字文字,标识符,字符串,保留字).你只需要定义delimiters和reserved,你将获得对大多数语言有用的东西.令牌定义在scala.util.parsing.combinator.token.StdTokens.
一旦你有了词法分析器,你就可以定义一个解析器来读取一个令牌流(由词法分析器产生)并生成一个抽象语法树.分离词法分析器和解析器是一个好主意,因为您不需要担心语法中的空格或注释或其他复杂性.如果您使用StdLexical,您可以考虑使用scala.util.parsing.combinator.syntax.StdTokenPasers内置解析器的标记将标记转换为值(例如,StringLit转换为String).我不确定与众不同之处StandardTokenParsers.如果您定义自己的令牌类,您应该只是Parsers为了简单起见.
你特别询问RegexParsers和JavaTokenParsers.RegexParsers是一个特性,它扩展Parsers了一个额外的组合器:regex,它完全符合你的期望.RegexParsers如果要使用正则表达式来匹配标记,请混合到词法分析器中.JavaTokenParsers提供了一些解析器,它们从Java语法中获取lex标记(如标识符,整数),但没有Lexical或者标记包含StdLexical.
总而言之,您可能需要两个解析器:一个读取字符并生成标记,另一个使用标记并生成AST.使用基于Lexical或StdLexical第一个的东西.根据您是否使用,根据Parsers或使用某些东西.StdTokenParsersStdLexical
RegexpParsers允许您使用RE值(通常在表单中,"re pattern".r但与任何其他Regex实例相同).没有预定义的词汇作品(代币).
JavaTokenParsers定义的Java令牌词法制作:decimalNumber,floatingPointNumber,stringLiteral,wholeNumber,ident(标识符).
StandardTokenParsers定义词汇制作"......用于简单的类Scala语言.它解析关键字和标识符,数字文字(整数),字符串和分隔符." 其成分实际上是在StdLexical.