Errors and crashes in Scala Combiners Parser

I would like to implement a parser for a specific language using Scala Parser Combiners. However, the software that will compile the language does not implement all the functions of the language, so I would like to crash if these functions are used. I tried to fake a small example below:

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

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

+6
source share
2 answers

In this case, you want err , not failure , because if the first parser in the disjunction does not work, you simply go to the second, which you do not need.

Another problem is that ^^ is the equivalent of map , but you want flatMap , since err("whatever") is Parser[Nothing] , not Nothing . You can use the flatMap method on Parser , but in this context it is more idiomatic to use the (fully 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 easier:

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

Any approach should do what you want.

+7
source

Can you use ^? method ^? :

 object TestFail extends JavaTokenParsers { def test: Parser[String] = "hello" ~> ident ^? ( { case id if id != "world" => s"hi, $id" }, s => s"Should not use '$s' here." ) } 
+3
source

Source: https://habr.com/ru/post/948625/


All Articles