Parser.Parser[Nonterminal] 类型的表达式不符合 Parser.Parser[TypeParameter]

Expression of type Parser.Parser[Nonterminal] doesn't conform to Parser.Parser[TypeParameter]

我正在摆弄 Scala 的解析器组合器,我被一个我似乎不太理解的错误难住了。

相关代码如下:

trait ASTNode
trait Terminal extends ASTNode
trait Nonterminal extends ASTNode
case class Identifier(id: String) extends Terminal
case class TypeDefinition(identifier: Identifier, optionalType: Option[TypeParameters]) extends Nonterminal
case class TypeParameters(params: List[TypeParameter]) extends Nonterminal
case class TypeParameter(typeDef: Either[TypeDefinition, Identifier]) extends Nonterminal

object Parser extends RegexParsers {
  def identifier: Parser[Identifier] = """([a-zA-Z_][\w'-]*)""".r ^^ Identifier

  def typeDef: Parser[TypeDefinition] = identifier ~ opt("of" ~> typeParams) ^^ {
    case id ~ optional => TypeDefinition(id, optional)
  }

// the bit causing the error
  def typeParam: Parser[TypeParameter] = "(" ~> typeDef <~ ")" | identifier ^^ {
    case td: TypeDefinition => TypeParameter(Left(td))
    case id: Identifier => TypeParameter(Right(id))
  }

这个错误让我烦恼的是 a) typeParam return 和 TypeParameter 的两种情况和 b) TypeParameter 是 [= 的实现16=],所以据我所知,应该不会产生任何错误。

这是怎么回事,我该如何解决这个错误?

由于优先级的原因,案例与您想象的不同。您的两个案例是:

"(" ~> typeDef <~ ")"

identifier ^^ {
  case td: TypeDefinition => TypeParameter(Left(td))
  case id: Identifier => TypeParameter(Right(id))
}

所以动漫笑脸只适用于identifier,所以"(" ~> typeDef <~ ")"的类型是Parser[TypeDefinition],不是Parser[TypeParameter]。因此,Scala 看到您将 Parser[TypeDefinition]Parser[TypeParameter] 进行 ORing,并决定结果必须是 Parser[NonTerminal],因为这是它们最具体的公共超类。

要解决此问题,您只需在 "(" ~> typeDef <~ ")" | identifier 周围添加括号,使优先级符合您的预期,或者将动漫笑脸分别应用于两种情况,这也使您不必进行模式匹配:

def typeParam: Parser[TypeParameter] =
  "(" ~> typeDef <~ ")" ^^ {
    td => TypeParameter(Left(td))
  } | identifier ^^ {
    id => TypeParameter(Right(id))
  }