2010-05-25 3 views
7

Ich habe einen Parser codiert basierend auf Scala Parser Kombinatoren:Wie können Sie Fehlermeldungen in Scala-Parser-Kombinator-basierten Parsern weiter verbessern?

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

Normalerweise sind die resultierenden Parsing-Fehler-Meldungen sind ziemlich nett. Aber manchmal wird es nur

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

Dies geschieht, wenn ein Anführungszeichen nicht geschlossen ist und der Parser erreicht die EOT. Was ich hier sehen möchte, ist (1) welche Produktion der Parser hatte, als er das '' 'erwartete (ich habe mehrere) und (2) wo in der Eingabe diese Produktion zu parsen begann (was ein Indikator dafür ist, wo Zitat ist in der Eingabe.) Weiß jemand, wie ich die Fehlermeldungen verbessern kann und mehr Informationen über den tatsächlichen internen Parsing-Status, wenn der Fehler auftritt (vielleicht etwas wie eine Produktionsregel Stacktrace oder was auch immer hier sinnvoll angegeben werden kann, um besser zu identifizieren die Fehlerstelle). BTW, die über „Zeile 32, Spalte 1“ ist eigentlich die Position EOT und daher nicht von nutzen ist hier natürlich.

Antwort

1

In solchen Fällen können Sie verwenden err, failure und ~! mit Produktionsregeln entworfen speziell um den Fehler zu entsprechen

3

Ich weiß noch nicht, wie mit (1) beschäftigen, aber ich war auch auf der Suche nach (2), wenn ich dieser Webseite gefunden: Ich bin das Kopieren nur die Informationen

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

:

Eine nützliche Erweiterung ist die Aufzeichnung der Eingabeposition (Zeilennummer und Spaltennummer) der signifikanten Token. Um dies zu tun, müssen Sie drei Dinge tun:

  • Machen Sie jeden Typ Ausgang erweitern scala.util.parsing.input.Positional
  • die Parsers.positioned aufrufen() Kombinator
  • Verwenden Sie einen Textquelle, die Datensätze Zeilen- und Spaltenpositionen

und

schließlich sicher, dass die Quelle verfolgt Positionen. Für Streams können Sie einfach scala.util.parsing.input.StreamReader; Verwenden Sie für Zeichenfolgen scala.util.parsing.input.CharArrayReader.

ich zur Zeit mit ihm spielen werde, so werde ich versuchen, ein einfaches Beispiel später hinzuzufügen

+0

Jetzt kann ich bestätigen, dass diese Art und Weise, es zu tun richtig ist (und einfach!). Es funktioniert vollkommen in Ordnung für mich – Vinz

+0

Link zur Verfügung gestellt scheint tot zu sein. – jbx

+0

Danke für die Meldung des Deadlinks, ich fand eine andere Quelle für die gleiche Erklärung. – Vinz