6

Scala Parser Combinators を使用して、定義された言語のパーサーを実装したいと考えています。ただし、言語をコンパイルするソフトウェアは言語のすべての機能を実装しているわけではないため、これらの機能を使用する場合は失敗したいと考えています。以下の小さな例を偽造しようとしました:

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

つまり、パーサーは "hello" + 何らかの識別子で成功しますが、識別子が "world" の場合は失敗します。Parsers クラスに fail() および err() パーサーが存在することがわかりますが、それらは String ではなく Parser[Nothing] を返すため、それらの使用方法がわかりません。ドキュメントはこのユースケースをカバーしていないようです…</p>

4

2 に答える 2

7

この場合err、 ではなくfailureが必要です。論理和の最初のパーサーが失敗した場合、2 番目のパーサーに進むだけなので、これは望んでいるものではありません。

もう 1 つの問題は、^^は と同等ですが、はではなく であるためmap、 が必要です。メソッド onを使用することもできますが、このコンテキストでは、(完全に同等の)演算子を使用する方がより慣用的です。flatMaperr("whatever")Parser[Nothing]NothingflatMapParser>>

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

どちらのアプローチでも、必要なことを行う必要があります。

于 2013-07-03T12:53:29.953 に答える