LARA

package minijava.lexer
 
object Tokens {
  sealed trait TokenClass {
    self =>
    def tokenClass: self.type = self
  }
 
  case object IDCLASS extends TokenClass { override def toString: String = "identifier" }
  case object NUMLITCLASS extends TokenClass { override def toString: String = "integer literal" }
  case object STRLITCLASS extends TokenClass { override def toString: String = "string literal" }}
 
  sealed trait TokenInfo {
    def tokenClass: TokenClass
  }
 
  case object BAD extends TokenInfo with TokenClass		// represents incorrect tokens.
  case object EOF extends TokenInfo with TokenClass
  case object SEMICOLON extends TokenInfo with TokenClass	// ;
 
  /* etc. */
 
  // Identifiers
  case class ID(value: String) extends TokenInfo {
    override def toString: String = value
    def tokenClass: TokenClass = IDCLASS
  }
 
  /* etc. */
 
  // A Token is a positional wrapper around a  TokenInfo
  class Token(val info: TokenInfo) extends Positional {
    override def toString: String = info.toString
    def tokenClass: TokenClass = info.tokenClass
  }
 
  object Token {
    def apply(info: TokenInfo): Token = new Token(info)
    def unapply(token: Token): Option[TokenInfo] = Some(token.info)
  }
}