Добавление номеров строк к ошибкам разбора без непосредственного расширения Positional
Я (наконец) завершил анализатор, который обрабатывает мой DSL и переводит его в мои доменные объекты. Теперь я хочу добавить правильную обработку ошибок и добавить номера строк к ошибкам, сообщенным анализатором.
Примеры и ответы, которые я нашел здесь и здесь, по- видимому, указывают на то, что мне нужно изменить свои доменные объекты, чтобы расширить scala.util.parsing.input.Positional
, Этот пример слишком упрощен для моего случая, и (из-за моей неопытности) кажется, что мой случай не совсем соответствует этой парадигме.
Основная проблема у меня заключается в том, что я не хочу, чтобы мои доменные объекты расширялись напрямую Positional
, Они используются в других местах программы, которые не имеют ничего общего с синтаксическим анализом (синтаксический анализатор является просто расширением программы для создания другого способа ввода данных). Кроме того, я не знаю, как обрабатывать случаи, которые выводят String
(или другие классы, которые я не могу контролировать). Существует также проблема в том, что мои доменные объекты уже расширяют другие объекты программы, я не могу просто изменить иерархию таким образом.
Есть ли альтернативный способ справиться с этим чисто, не изменяя доменные объекты и не связывая их с Positional
? (Извиняюсь, если я спрашиваю что-то тривиальное, что связано с реализацией черт и т. Д., Потому что я все еще новичок в Scala)
1 ответ
Вы можете использовать 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)
}