Ho letto alcuni post qui su parser-combinators di Scala e una migliore gestione degli errori, ma molte "soluzioni" sembrano dire "basta usare" ~! "", O "Anticipare i casi di errore con le regole grammaticali".
Così ho tentato di implementare alcuni di questi consigli, ma sono bloccato a capire come funzionano i parser di errori / errori:
val foo: Parser[String] = """foo""".r | err("Custom Message")
val test: Parser[List[String]] = repsep(foo, ",") | err("Custom Message Repsep")
val r = parseAll(foo, ""bar") //[1.1] error: Custom Message -- YAY
val r = parseAll(test, "foo, bar") //[1.2] failure: string matching regex `foo" expected but `b" found -- NOOOOOO
La mia domanda è fondamentalmente: se foo
viene ripetutamente tentato contro la stringa di input a causa di repsep
, allora perché - poiché la sua definizione include a |
in caso di fallimento di provare e forzare un err
- è il messaggio di errore dal terminale più a sinistra nel foo
la produzione viene visualizzata?
C'è un modo per visualizzare una pila di messaggi di errore nel risultato di analisi e trovare sempre il mio e visualizzare all'utente? O devo implementare la mia versione di repsep
o qualcosa? Credo che mi manchi qualcosa sul modello concettuale di ciò che sta succedendo :(
risposte:
0 per risposta № 1No, non è necessario riscrivere repsep
o tieni traccia dei tuoi messaggi di errore. Il parser-combinator sembra comportarsi proprio come te l'hai chiesto. Corrisponde a "pippo" una volta e poi trova ",". Ma poi ha fallito su "bar", ma dato che aveva già inghiottito "foo" e ",", non poteva restituirli e quindi provare la seconda alternativa (il tuo messaggio di errore). Potresti provare a usare un parser packrat invece se questo è davvero il comportamento che vuoi.
0 per risposta № 2
Per il mio commento sopra: Ho finito per risolvere questo problema usando FastParse (lihaoyi.com/fastparse). Esiste un metodo opaco che avvolge un parser e genera un messaggio di errore personalizzato utile in caso di errore. Per esempio.:
val test = foo.rep(1,",").opaque("Custom Message Repsep")
Complessivamente, trovo FastParse molto più veloce e più facile da usare rispetto a Scala Parser Combinators.