4

私はscalaのParsersクラスを含むこのコードを持っています:

trait SomeTrait extends SomeTrait2 {
  def myParse = {
    phrase(rep(
            ElemName(Some("http://someUri/"), "someNode1") ~       //compiles well, but fails sometimes at runtime
            ElemName(Some("http://someUri/"), "someNode2") ^^
            {
              case p1 ~ p2 ⇒  //......
            }) ^^
            {
              case p1 ⇒  // ....
            })
  }
}

どこ

case class ElemName(namespace: Option[String], name: String) {
   // .....
}

通常、入力 SOAP 文字列には " someNode1" と " someNode2" の両方が存在します (ここでは指定されていませんが、問題ありません)。ただし、場合によっては、それらのいずれかが存在するか、まったく存在しない場合があり、この場合、実行時にクラッシュします。

<items>
  <subItems>
    <someNode1 val1="123" val2="456" />
    <someNode1 val1="123a" val2="456c" />
    <someNode1 val1="123b" val2="456d" />
    <someNode2 val1="123" val2="456" />
  </subItems>
  <subItems>
    <someNode2 val1="123cd" val2="456de" />
  </subItems>
  <subItems>
  </subItems>
  <subItems>
    <someNode1 val1="777" val2="888" />
  </subItems>
<items>

私はそれを処理しなければなりません。だから私はした:

trait SomeTrait extends SomeTrait2 {
  def myParse = {
    phrase(rep(
      ElemName(Some("http://someUri/"), "someNode1") |          // should work
      ElemName(Some("http://someUri/"), "someNode2") ^^ 
      {
        case p1 ~ p2 ⇒  //......
      }) ^^
      {
        case p1 ⇒  // ....
      })

      //or, I'm not sure which one to choose
      //ElemName(Some("http://someUri/"), "someNode1") |||      // should work also
      //ElemName(Some("http://someUri/"), "someNode2") ^^ 
  }
}

これは私が理解しているように機能するはずです。ただし、この時点では、次のように記述されているため、コンパイルされません。

constructor cannot be instantiated to expected type;
[error]  found   : SomeTrait.this.~[a,b]
[error]  required: ElemName
[error]           case p1 ~ p2 ⇒ {
[error]                   ^
[error] one error found

ケース p1 ~ p2 を別のものに置き換える必要があると思います。

4

1 に答える 1

1

問題はそれです | と ||| どちらも単一のトークンを返します。具体的には:

a | ba の解析を試み、成功した場合は戻り、失敗した場合 a ||| bは b の解析を試み、a と b の解析を試み、最も多くの文字を解析した結果を使用します。どちらもあなたが望むものではないと思います。そうである場合は、p1notを使用する必要がありますp1 ~ p2。あなたが本当に欲しいのは次のことだと思います:

phrase(rep(
  ElemName(Some("http://someUri/"), "someNode1").? ~
  ElemName(Some("http://someUri/"), "someNode2").? ^^ 
  {
    case Some(p1) ~ Some(p2) ⇒  //......
    case Some(p1) ~ None => //.....
    case None ~ Some(p2) => //.....
  })
于 2013-12-24T04:42:51.857 に答える