Scala分析器组合器中的错误和失败

Scala分析器组合器中的错误和失败

本文介绍了Scala分析器组合器中的错误和失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Scala解析器组合器为某些定义的语言实现解析器.但是,将用于编译该语言的软件无法实现该语言的所有功能,因此如果使用这些功能,我将失败.我尝试在下面伪造一个小例子:

I would like to implement a parser for some defined language using Scala Parser Combinators. However, the software that will compile the language does not implements all the language's feature, so I would like to fail if these features are used. I tried to forge a small example below :

object TestFail extends JavaTokenParsers {
  def test: Parser[String] =
    "hello" ~ "world" ^^ { case _ => ??? } |
    "hello" ~ ident ^^ { case "hello" ~ id => s"hi, $id" }
}

也就是说,解析器在"hello" +一些标识符上成功,但是在标识符为"world"的情况下失败.我看到在Parsers类中存在fail()和err()解析器,但是我不知道如何使用它们,因为它们返回Parser [Nothing]而不是String.该文档似乎并未涵盖此用例……

I.e., the parser succeeds on "hello" + some identifier, but fails if the identifier is "world". I see that there exist fail() and err() parsers in the Parsers class, but I cannot figure out how to use them, as they return Parser[Nothing] instead of a String. The documentation does not seem to cover this use case…

推荐答案

在这种情况下,您需要的是err,而不是failure,因为如果析取中的第一个解析器失败,您将继续进行第二个解析器,这不是你想要的.

In this case you want err, not failure, since if the first parser in a disjunction fails you'll just move on to the second, which isn't what you want.

另一个问题是^^等同于map,但是您需要flatMap,因为err("whatever")Parser[Nothing],而不是Nothing.您可以在Parser上使用flatMap方法,但是在这种情况下,使用(完全等效)>>运算符会更加惯用:

The other issue is that ^^ is the equivalent of map, but you want flatMap, since err("whatever") is a Parser[Nothing], not a Nothing. You could use the flatMap method on Parser, but in this context it's more idiomatic to use the (completely equivalent) >> operator:

object TestFail extends JavaTokenParsers {
  def test: Parser[String] =
    "hello" ~> "world" >> (x => err(s"Can't say hello to the $x!")) |
    "hello" ~ ident ^^ { case "hello" ~ id => s"hi, $id" }
}

或者,更简单一点:

object TestFail extends JavaTokenParsers {
  def test: Parser[String] =
    "hello" ~ "world" ~> err(s"Can't say hello to the world!") |
    "hello" ~ ident ^^ { case "hello" ~ id => s"hi, $id" }
}

这两种方法都可以满足您的要求.

Either approach should do what you want.

这篇关于Scala分析器组合器中的错误和失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 12:39