3

我见过两种在 Scala 中构建解析器的方法。

第一个是从 RegexParsers 扩展并定义您赢得的词汇模式。我看到的问题是我并不真正了解它如何处理关键字歧义。例如,如果我的关键字与 idents 匹配相同的模式,那么它将关键字作为 idents 处理。

为了解决这个问题,我看到过类似这样的帖子,其中展示了如何使用 StandardTokenParsers 来指定关键字。但是,我不明白如何指定正则表达式模式!是的,StandardTokenParsers 带有“ident”,但它没有附带我需要的其他内容(复杂的浮点数表示、特定的字符串文字模式和转义规则等)。

您如何同时获得指定关键字的能力和使用正则表达式指定标记模式的能力?

4

2 回答 2

8

我只写了RegexParsers- 派生的解析器,但我所做的是这样的:

val name: Parser[String] = "[A-Z_a-z][A-Z_a-z0-9]*".r

val kwIf: Parser[String]    = "if\\b".r
val kwFor: Parser[String]   = "for\\b".r
val kwWhile: Parser[String] = "while\\b".r

val reserved: Parser[String] = ( kwIf | kwFor | kwWhile )

val identifier: Parser[String] = not(reserved) ~> name
于 2010-09-22T15:24:00.417 回答
0

类似于@randall-schulz 的答案,但在正则表达式本身中使用显式的否定前瞻。

这里,empty是一个关键字,但empty?应该是一个标识符。如果空后跟nameCharsRE. kw辅助函数用于多个这样的关键字:

  val nameCharsRE = "[^\\s\",'`()\\[\\]{}|;#]"

  private def kw(kw: String, token: Token) = positioned {
    (s"${kw}(?!${nameCharsRE})").r ^^ { _ => token }
  }
  private def empty        = kw("empty", EMPTY_KW())
  private def and          = kw("and", AND())
  private def or           = kw("or", OR())
于 2021-12-17T13:46:50.530 回答