4

我有这个涉及scalaParsers类的代码:

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 | b尝试解析 a,如果成功则返回,如果失败则 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 回答