如何过滤解析器组合器中的保留字?

时间:2017-06-02 17:23:12

标签: scala parsing parser-combinators

我正在使用Scala的Parser Combinator框架,扩展了RegexParsers类。我有一个identifier标记,以字母开头,可以包含字母字符,短划线,下划线和数字,只要它不是保留字之一。我尝试使用解析器not()来阻止使用保留字,但它也匹配带有保留字前缀的标识符。

def reserved = "and" | "or"

def identifier: Parser[String] = not(reserved) ~> """[a-zA-Z][\.a-zA-Z0-9_-]*""".r

但是,当我尝试解析and-today这样的标识符时,我收到错误Expected Failure

如果保留字是与令牌完全匹配而不仅仅是前缀,我该如何过滤保留字?

使用not()时,还有一种方法可以改善此情况下的错误报告吗?在其他情况下,我得到了解析器所期望的正则表达式,但在这种情况下,它只是说Failure没有任何细节。

1 个答案:

答案 0 :(得分:3)

您可以使用filterWithError来过滤掉保留字并自定义错误消息,如下所示:

    val reservedWords = HashSet("and", "or")

    val idRegex= """[a-zA-Z][\.a-zA-Z0-9_-]*""".r

    val identifier = Parser(input =>
      idRegex(input).filterWithError(
        !reservedWords.contains(_),
        reservedWord => s"YOUR ERROR MESSAGE FOR $reservedWord",
        input
      )
    )