Errors and failures in Scala Parser Combinators

parser-combinators, parsing, scala

Solution

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.

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" }
}

Or, a little more simply:

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.

Problem

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" } } ``` 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…

Original source