添加行号以解析错误而不直接扩展Positional

时间:2014-01-04 17:40:44

标签: scala parsing line-numbers parser-combinators

我(最终)完成了一个解析器,它处理我的DSL并将其转换为我的域对象。现在我想添加一些正确的错误处理,我希望将行号添加到解析器报告的错误中。

我发现herehere的示例和答案似乎表明我必须修改我的域对象以扩展scala.util.parsing.input.Positional。这个例子对我来说有点过于简单了,而且(由于我的经验不足),我的情况似乎并不适合这种范式。

我遇到的主要问题是我不希望我的域对象直接扩展Positional。它们在程序的其他地方使用,与解析没有任何关系(解析器只是程序的扩展,用于创建输入数据的不同方式)。另外,我不知道如何处理输出String(或其他我无法控制的类)的情况。还有一个问题是我的域对象已经扩展了程序的其他对象,我不能简单地改变那种层次结构。

有没有其他方法可以干净地处理它,而无需修改域对象并将它们与Positional耦合? (如果我要求一些与实现特征有关的微不足道的事情,我会道歉,因为我还是Scala的新手)

1 个答案:

答案 0 :(得分:0)

你可以使用scala.util.matching.Regex.MatchIterator来构建这样的东西

type Token = String

trait TokenIterator extends Iterator[Token] {
  def next: Token
  def hasNext: Boolean
  def pos: Int
}

class Tokenizer(regexStr: String, input: String) {
  val regex = regexStr.r

  def iterator: TokenIterator = new TokenIterator {
    val iter = regex.findAllIn(input)
    var pos = 0
    def next = {
      val n = iter.next
      pos = iter.start
      n
    }
    def hasNext = iter.hasNext
  }
}

val str = "3 + 4 - 5"
val iter = new Tokenizer("""d+|\S+?""", str).iterator

while(iter.hasNext) {
  val token = iter.next
  val pos = iter.pos
  println(pos + ": " + token)
}