3

スカラ 2.8.1

QA 用のパーサー/コンビネーターを使用して受け入れテストを作成するための非常に単純な外部 DSL を実装しました。

最近、一連の式を次のようにループする機能を追加しました

sealed trait Expr

...
//insert other case classes extending 'Expr' here
...

case class Repetition(times: Int, expressions: List[Expr]) extends Expr

class TestFixtureParser(....) extends RegexParsers {
  val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
    case (times: Int) ~ (exprs: List[Expr]) => {
      Repetition(times, exprs)
    }
  }

  private val expressions: Parser[List[Expr]] = (repeatParser | 
    /*insert other Parser[Expr]s '|' together here */ | verifyParser ).*

}

warning: non variable type-argument ... is unchecked since it is eliminated by erasureビルド時、パターンマッチング時に警告が出ます。以下でも抽出してみました。

  //Doesn't build with error
  /*
    error: missing parameter type for expanded function ((x0$2) => x0$2 match {
      case $tilde((times @ _), (exprs @ _)) => Repetition(times, exprs)
    })
        r: ~[Int, List[Expr]] => {
  */
  val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
    r: ~[Int, List[Expr]] => {
      case times ~ exprs =>
        Repetition(times, exprs)
    }
  }

  //Actually this does build without warning. 
  //I am unfortunately using intelliJ and it doesn't like it
  val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
    repetitions: ~[Int, List[Expr]] => {
      val ~(times, exprs) = repetitions
      Repetition(times, exprs)
    }
  }

  //Builds but same warning
  val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
    repetitions => {
      val ~(times: Int, exprs: List[Expr]) = repetitions
      Repetition(times, exprs)
    }
  }

exprsこの警告なしでエレガントな方法で抽出するための提案はありますか? そのまま機能します。私はそれを無視する必要がありますか?警告を無視する習慣を身につけたくありません。

編集:答えてください。これは実際に私が最初に試したものでしたが、intelliJ scala プラグインが型を推測できなかったため、型を追加しました。

  val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
      case times ~ exprs =>
          Repetition(times, exprs)
  }
4

2 に答える 2

5

あなたの構文は、最初の「ビルドしない」例には正しくないと思います(それを適用するのではなく、部分的な関数を返しているように見えますが、これはあなたが望むものではありません)。書いてみてください:

val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
    case times ~ exprs =>
        Repetition(times, exprs)
}

残念ながら、依存するコードの残りの部分がないため、これをテストすることはできませんが、この種の構成は通常機能します。

于 2011-11-15T23:35:46.680 に答える
2

受け入れられた答えが最善ですが、それがうまくいかない場合の代替手段は次のとおりです。

r: ~[t1, t2] => {
  case times ~ exprs =>
    Repetition(times, exprs)
}

上記のt1t2と推測されますが、 と推測されるだけかもしれませんAny。ただし、それらがどのように推論されても、その構文で実行できる最善の方法です。

val ~(times: Int, exprs: List[t]) = repetitions

ここでは、値を抽出しているため、実際に型を確認できます。を持っているかどうかをテストしていません~[Int,List[Int]]--抽出された値Intにとの型があるかどうかをテストしていますList[t]。あなたが得た警告は型パラメータから へのものであることに注意してくださいList

于 2011-11-16T03:04:27.933 に答える