16

パーサー コンビネーターを実装するオブジェクトのファミリが与えられた場合、どのようにパーサーを組み合わせることができますか? Parsers.Parserはインナー クラスであり、Scala ではインナー クラスはアウター オブジェクトにバインドされるため、話は少し複雑になります。

以下は、異なるオブジェクトからの 2 つのパーサーを結合しようとする例です。

import scala.util.parsing.combinator._

class BinaryParser extends JavaTokenParsers {
  def anyrep: Parser[Any] = rep(any)
  def any: Parser[Any] = zero | one
  def zero: Parser[Any] = "0"
  def one: Parser[Any] = "1"
}

object LongChainParser extends BinaryParser {
  def parser1: Parser[Any] = zero~zero~one~one
}

object ShortChainParser extends BinaryParser {
  def parser2: Parser[Any] = zero~zero
}

object ExampleParser extends BinaryParser {
  def parser: Parser[Any] = (LongChainParser.parser1
    ||| ShortChainParser.parser2) ~ anyrep

  def main(args: Array[String]) {
    println(parseAll(parser, args(0) ))
  }
}

これにより、次のエラーが発生します。

<console>:11: error: type mismatch;
 found   : ShortChainParser.Parser[Any]
 required: LongChainParser.Parser[?]
         def parser: Parser[Any] = (LongChainParser.parser1 
           ||| ShortChainParser.parser2) ~ anyrep

この問題の解決策は既に見つけましたが、最近 scala-user ML (パーサーを別のパーサーに挿入する問題) で取り上げられたので、ここにも置く価値があるでしょう。

4

1 に答える 1

17

簡単な答えは、パーサーをstraitでホストする代わりに sを使用することです。object

import scala.util.parsing.combinator._

trait BinaryParser extends JavaTokenParsers {
  def anyrep: Parser[Any] = rep(any)
  def any: Parser[Any] = zero | one
  def zero: Parser[Any] = "0"
  def one: Parser[Any] = "1"
}

trait LongChainParser extends BinaryParser {
  def parser1: Parser[Any] = zero~zero~one~one
}

trait ShortChainParser extends BinaryParser {
  def parser2: Parser[Any] = zero~zero
}

object ExampleParser extends LongChainParser with ShortChainParser  {
  def parser: Parser[Any] = (parser1 ||| parser2) ~ anyrep

  def main(args: Array[String]) {
    println(parseAll(parser, args(0) ))
  }
}

コンビネーター演算子は内部クラスを好み、それに対して書かれているため~|パーサー参照をクラスレベルにエスカレートしても何の役BinaryParser#Parser[_]にも立ちません。Parser[Any]fromLongChainParserShortChainParsernow の両方が object の内部クラスを参照するため、特性を使用すると内部クラスの問題がすべて解決されExampleParserます。

于 2010-04-16T02:49:45.980 に答える