Я пытаюсь написать синтаксический анализатор в scala с помощью Parser Combinators. Если я сопрягать рекурсивно,, возвращающий содержательные сообщения об ошибках из анализатора, написанного с помощью компиляторов Scala Parser
def body: Parser[Body] =
("begin" ~> statementList ) ^^ {
case s => { new Body(s); }
}
def statementList : Parser[List[Statement]] =
("end" ^^ { _ => List() })|
(statement ~ statementList ^^ { case statement ~ statementList => statement :: statementList })
тогда я получаю хорошие ErrorMessages всякий раз, когда есть ошибка в заявлении. Однако этот уродливый длинный код. Так что я хотел бы написать это:
def body: Parser[Body] =
("begin" ~> statementList <~ "end" ) ^^ {
case s => { new Body(s); }
}
def statementList : Parser[List[Statement]] =
rep(statement)
Этот код работает, но печатает только значимые сообщения, если есть ошибка в первом заявлении. Если в последующем заявлении, сообщение становится мучительно непригодным, так как анализатор хочет видеть все ошибочное утверждение заменено «конечным» лексемы:
Exception in thread "main" java.lang.RuntimeException: [4.2] error: "end" expected but "let" found
let b : string = x(3,b,"WHAT???",!ERRORHERE!,7)
^
Мой вопрос: есть ли способ, чтобы получить респ и repsep работают в сочетании со значимыми сообщениями об ошибках, которые помещают каретку в нужное место вместо начала повторяющегося фрагмента?
'фраза' возвращает' Parser', что будет успешным только в том случае, если в нем нет ввода после его принятия. Я понятия не имею, почему это изменило бы такой путь назад. –
Оказывается, он вообще не меняет обратный отсчет, но фраза имеет немного состояния, чтобы проверить сбой, который имел самый длинный результат совпадения. Он описан в параграфе «Отчеты об ошибках» в главе о парсерах в книге Одерского. – Jan