Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expected type of Parser in method "|"

I have the following code being compiled against scala 2.8.0:

import scala.util.parsing.combinator.{syntactical,PackratParsers}
import syntactical.StandardTokenParsers

object MyParser extends StandardTokenParsers with PackratParsers{
  lexical.reserved ++= Set("int","char","boolean")

  lazy val primitiveType:PackratParser[PrimitiveType[_]] = primitiveChar | primitiveInt | primitiveBool

  lazy val primitiveInt:PackratParser[PrimitiveType[Int]] = "int" ^^ { _ => PrimitiveType[Int]() }

  lazy val primitiveChar:PackratParser[PrimitiveType[Char]] = "char" ^^ { _ => PrimitiveType[Char]() }

  lazy val primitiveBool:PackratParser[PrimitiveType[Boolean]] = "boolean" ^^ { _ => PrimitiveType[Boolean]() }
}

object MyParser2 extends StandardTokenParsers with PackratParsers{
  lexical.reserved ++= Set("int","char","boolean")

  lazy val primitiveType:PackratParser[PrimitiveType[_]] =  primitiveChar | primitiveIntOrBool

  lazy val primitiveIntOrBool:PackratParser[PrimitiveType[_]] = "int" ^^ { _ => PrimitiveType[Int]() } | "boolean" ^^ {_ => PrimitiveType[Boolean]()}

  lazy val primitiveChar:PackratParser[PrimitiveType[Char]] = "char" ^^ { _ => PrimitiveType[Char]()} 
}

case class PrimitiveType[T]()

Compiling MyParser1 gives:

error: inferred type arguments  [this.PrimitiveType[_ >: _1 with Boolean <: AnyVal]] do not conform to method |'s type parameter bounds [U >: this.PrimitiveType[_ >: Char with Int <: AnyVal]]

I believe it fails because of the | method type signature, defined as:

def | [U >: T](q: => Parser[U]): Parser[U]

why does U have to be a supertype of T? What should be the return value of "primitiveType"?

like image 406
Carlos López-Camey Avatar asked Feb 26 '23 12:02

Carlos López-Camey


1 Answers

You need to change your last line into

case class PrimitiveType[+T]()

This allows for PrimitiveType[Int] <: PrimitiveType[AnyVal] which is needed when you want to merge the results of PrimitiveType[Boolean] and PrimitiveType[Int] parsers via |.

BTW, I would also suggest to write

PrimitiveType[AnyVal]

instead of

PrimitiveType[_]

since this is more precise in your case.

like image 93
Stefan Endrullis Avatar answered Mar 01 '23 19:03

Stefan Endrullis