How to improve error message in parsers based on Scala combiner parser?

I encoded a parser based on Scala parser compilers:

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 } } 

Typically, parsing error messages received are pretty nice. But sometimes it just becomes

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

This happens if quotation marks are not closed and the parser reaches EOT. What I would like to see here is (1) in which work the parser had when it expected "(I have several) and (2) where this production started parsing at the input (this is an indicator, an introductory quote is in the input.) Does anyone know how I can improve error messages and include more information about the actual internal syntax state when an error occurs (maybe something like a stacktrace production rule or something, the location of the error). the above row is "row 32, column 1" actually i It appears to be an EOT position and therefore useless here.

+7
scala error-handling parser-combinators
source share
2 answers

I do not know how to deal with (1) yet, but I also searched (2) when I found this web page:

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

I just copy the information:

A useful advantage is to record the input position (line number and column number) of significant tokens. To do this, you must do three things:

  • Make each type of output extension scala.util.parsing.input.Positional
  • call combinator Parsers.positioned ()
  • Use a text source that records the positions of rows and columns.

and

Finally, make sure the original track position. For streams, you can simply use scala.util.parsing.input.StreamReader; for strings, use scala.util.parsing.input.CharArrayReader.

I am currently playing with it, so I will try to add a simple example later

+3
source share

In such cases, you can use err , failure and ~! with production rules specifically designed to match this error.

+1
source share

All Articles