问题描述
我想使用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分析器组合器中的错误和失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!