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))
}
我正在摆弄 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))
}