2014-01-04 5 views
1

У меня (наконец) завершен синтаксический анализатор, который обрабатывает мою DSL и переводит ее на мои объекты домена. Теперь я хочу добавить правильную обработку ошибок, и я хочу добавить номера строк к ошибкам, сообщаемым синтаксическим анализатором.Добавление номеров строк к ошибкам синтаксического анализа без прямого позиционирования

Приведенные примеры и ответы here и here, похоже, указывают, что я должен изменить объекты своего домена, чтобы расширить scala.util.parsing.input.Positional. Пример слишком упрощен для моего случая, и (из-за моей неопытности) кажется, что мое дело не совсем подходит этой парадигме.

Основная проблема, с которой я сталкиваюсь, заключается в том, что я не хочу, чтобы мои объекты домена напрямую расширялись Positional. Они используются в других местах программы, которые не имеют никакого отношения к разбору (синтаксический анализатор - это просто расширение программы для создания другого способа ввода данных). Кроме того, я не знаю, как обрабатывать случаи, которые выводят String (или другие классы, к которым у меня нет никакого контроля). Также есть проблема, что объекты моего домена уже расширяют другие объекты программы, я не могу просто изменить иерархию таким образом.

Есть ли альтернативный способ справиться с этим, не изменяя объекты домена и связывая их с Positional? (Извиняюсь, если я прошу что-то тривиальное, что связано с внедрением черт и т.д., потому что я еще новичок в Scala)

ответ

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) 
} 
+0

Как это использовать в моем парсере? У меня есть парсер около 300 строк (довольно сложный BNF). Что я могу изменить, чтобы интегрировать это? – jbx