Как далее улучшить сообщения об ошибках в Scala основанные на синтаксическом-анализаторе-combinator синтаксические анализаторы?

Я кодировал синтаксический анализатор на основе синтаксического анализатора Scala combinators:

class SxmlParser extends RegexParsers with ImplicitConversions with PackratParsers {
    [...]
    lazy val document: PackratParser[AstNodeDocument] =
        ((procinst | element | comment | cdata | whitespace | text)*) ^^ {
            AstNodeDocument(_)
        }
    [...]
}
object SxmlParser {
    def parse(text: String): AstNodeDocument = {
        var ast = AstNodeDocument()
        val parser = new SxmlParser()
        val result = parser.parseAll(parser.document, new CharArrayReader(text.toArray))
        result match {
            case parser.Success(x, _) => ast = x
            case parser.NoSuccess(err, next) => {
                tool.die("failed to parse SXML input " +
                    "(line " + next.pos.line + ", column " + next.pos.column + "):\n" +
                    err + "\n" +
                    next.pos.longString)
            }
        }
        ast
    }
}

Обычно получающиеся сообщения ошибки анализа довольно хороши. Но иногда это становится справедливым

sxml: ERROR: failed to parse SXML input (line 32, column 1):
`"' expected but `' found
^

Это происходит, если символы кавычки не закрываются, и синтаксический анализатор достигает EOT. Что я хотел бы видеть, вот (1) какое производство синтаксический анализатор был в том, когда это ожидало '"' (у меня есть несколько), и (2) где во входе это производство начало анализировать (который является индикатором, где вводная кавычка находится во входе). Делает кто-либо знает, как я могу улучшить сообщения об ошибках и включать больше информации о фактическом внутреннем состоянии парсинга, когда ошибка происходит (возможно, что-то как порождающее правило stacktrace или независимо от того, что может быть дано обоснованно здесь для лучше идентификации ошибочного местоположения). BTW, вышеупомянутая "строка 32, столбец 1" является на самом деле положением EOT и следовательно бесполезный здесь, конечно.

7
задан Ralf S. Engelschall 25 May 2010 в 16:52
поделиться

2 ответа

В таких случаях вы можете использовать err, failure и ~! с правилами производства, разработанными специально для соответствия ошибке.

1
ответ дан 7 December 2019 в 14:29
поделиться

Я еще не знаю, как поступить с (1), но я также искал (2), когда нашел эту веб-страницу :

https://wiki.scala-lang.org/plugins/viewsource/viewpagesrc.action?pageId=917624

Я просто копирую информацию:

Полезным улучшением является запись позиции ввода (номер строки и номер столбца) значимых токенов. Для этого вы должны сделать три вещи:

  • Заставить каждый тип вывода расширять scala.util.parsing.input.Positional
  • вызывать комбинатор Parsers.positioned ()
  • Использовать текстовый источник, который записывает строку и столбец позиции

и

Наконец, убедитесь, что источник отслеживает позиции. Для потоков вы можете просто использовать scala.util.parsing.input.StreamReader; для строк используйте scala.util.parsing.input.CharArrayReader.

Я сейчас играю с этим, поэтому попробую добавить простой пример позже

3
ответ дан 7 December 2019 в 14:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: