我根据Parsing M-Expressions in Scala with combinators制作词法分析器。
import scala.util.parsing.combinator.lexical._
import scala.util.parsing.combinator.token._
trait MyTokens extends Tokens {
case class Id(chars: String) extends Token
case class Num(chars: String) extends Token
}
class MyLexical extends Lexical with MyTokens {
def whitespace = rep(whitespaceChar)
def token: Parser[Token] = (
rep1(letter) ^^ { case charList => Id(charList mkString "") }
| rep1(digit) ^^ { case charList => Num(charList mkString "") }
)
}
object Main extends App {
val lexical = new MyLexical
val scanner = new lexical.Scanner("abc012def345")
def tokenList(s: lexical.Scanner): List[lexical.Token] =
if (s.atEnd) Nil
else s.first :: tokenList(s.rest)
println(tokenList(scanner))
}
效果很好,导致List(Id(abc), Num(012), Id(def), Num(345))
。但是,函数tokenList
应该是Scanner将其称为scanner.tokenList
的方法。为了实现它,似乎应该覆盖内部类MyLexical.Scanner
。可能吗?如果可以,怎么做?
答案 0 :(得分:1)
我认为你不能在内部类中添加方法,但是你可以使用隐式转换来实现类似的结果。它看起来像是:
object ScannerImplicits {
implicit class BetterScanner(scanner: MyLexical.Scanner) {
def tokenList(s: MyLexical.Scanner): List[MyLexical.Token] = {
if (s.atEnd) Nil
else s.first :: tokenList(s.rest)
}
}
}
比你能写的
import ScannerImplicits ._
new lexical.Scanner("abc012def345").tokenList