2010-05-25 10 views
7

he codificado un analizador basado en combinadores analizador Scala:¿Cómo mejorar aún más los mensajes de error en los analizadores basados ​​en el analizador-analizador Scala?

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

Por lo general, los mensajes de error de análisis resultantes son bastante agradable. Pero a veces se convierte en

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

Esto ocurre si los caracteres de una cita no se cierran y el analizador llega al EOT. Lo que me gustaría ver aquí es (1) en qué producción estaba el analizador cuando esperaba el '' '(tengo múltiples) y (2) dónde en el input esta producción comenzó a analizar (que es un indicador donde la cita de apertura está en la entrada). ¿Alguien sabe cómo puedo mejorar los mensajes de error e incluir más información sobre el estado de análisis interno real cuando ocurre el error (tal vez algo así como una pila de reglas de producción o lo que se puede dar razonablemente aquí para identificar mejor? la ubicación de error). Por cierto, el de arriba "línea 32, columna 1" es en realidad la posición EOT y por lo tanto de ninguna utilidad aquí, por supuesto.

Respuesta

1

En tales casos puede usar err, failure y ~! con las normas de producción diseñadas específicamente para que coincida con el error.

3

No sé todavía cómo tratar con (1), pero también estaba buscando (2) cuando me encontré con esta página web:

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

Sólo estoy copiando la información:

Una mejora útil es registrar la posición de entrada (número de línea y número de columna) de los tokens significativos. Para ello, debe hacer tres cosas:

  • hacer que cada tipo de salida se extienden scala.util.parsing.input.Positional
  • invocar el Parsers.positioned() COMBINATOR
  • uso de una fuente de texto que los registros de línea y de columna posiciones

y

último, asegurar que la fuente pistas posiciones. Para las transmisiones, simplemente puede usar scala.util.parsing.input.StreamReader; para cadenas, use scala.util.parsing.input.CharArrayReader.

Actualmente estoy jugando con él, así que trataremos de añadir un ejemplo sencillo tarde

+0

Ahora puedo confirmar que esta manera de hacerlo es correcta (y realmente sencillo!). Funciona perfectamente bien para mí – Vinz

+0

El enlace proporcionado parece estar muerto. – jbx

+0

Gracias por informar sobre deadlink, encontré otra fuente para la misma explicación. – Vinz

Cuestiones relacionadas