2010-10-21 8 views
6

Me gustaría lanzar una excepción cuando el idioma no se ajusta a la gramática para un analizador de combinación scala. He aquí un ejemplo de una regla:¿cómo tiro excepciones con mensajes significativos con un analizador de combinación scala?

def record: Parser[Record] = "-" ~ opt(recordLabel) ~ repsep(column, ",") ^^ { 
    case "-" ~ label ~ columns => new Record(label, columns) 
} 

Digamos que en el repsep (columna "") parte, que accidentalmente hacer una cadena como esta

a, b, c, d, 

Esto no es válida, ya que termina con un "," que no se supone que debe estar allí. En lugar de que el analizador simplemente se detenga cuando llama a parseAll(), ¿cómo hace que arroje una excepción significativa que sea legible por humanos? (Texto personalizado, número de línea, etc.)

EDIT: Bueno, he encontrado algo que funciona, pero no estoy satisfecho con su capacidad de personalización:

def loadFrom(filename: String) { 
    val source = 
     Source.fromFile(filename).getLines.mkString("\n") 
    val parseResult = parseAll(tables, source) 
    if(!parseResult.successful) { 
     throw new TestDataParseException(parseResult.toString) 
    } 
} 

El toString imprime un mensaje de bien, pero se imprime cosas raras como querer "\ z" cuando encontró un espacio (que a veces parece un bloque/cuadrado en mi IDE). Prefiero decir: "¡Oye, olvidaste una coma!"

Los números/columnas de línea se imprimen en forma de [x.y]. De hecho, me gustaría mostrar [Line: x, Column: y] porque la gente sabrá qué es eso de manera más intuitiva.

Gracias

Respuesta

7
parseAll(tables, source) match { 
    case Success(ast, _) => //do something 
    case NoSuccess(msg, next) => { 
     println("Failed at line %s, column %s: %s".format(
        next.pos.line, next.pos.column, msg)) 
    } 
} 
+0

Booya! Eso es exactamente eso. ¡Muchas gracias! – egervari

Cuestiones relacionadas