2009-05-06 7 views
3

Ich brauche einen Parser für eine Sprache, die nicht so kompliziert ist. Der einzige Haken ist, dass der Parser niemals einen Fehler auslösen soll, wenn er eine fehlerhafte Eingabe erhält. Ich möchte, dass es einfach weitergeht und so viel Sinn wie möglich macht, ähnlich wie es die HTML-Parser in einem Webbrowser tun.Mit einem Parser-Generator wie BISON, während immer noch schlechte Eingabe geschickt

Ich dachte natürlich, einen Parsergenerator zu verwenden, aber ich habe nicht so viel Erfahrung mit ihnen, und alle Beispiele, die ich von Bison und Antlr gesehen habe, zeigen spröde Parser, die aufgeben, sobald sie auf einen treffen Syntax-Fehler. Ist das mit ihnen machbar, oder sollte ich es in Betracht ziehen? Es wäre wahrscheinlich (denke ich) angesichts der Sprache nicht so schwierig.

Antwort

1

Ich bin nicht sicher, dass Sie im Allgemeinen mit einem Parser-Generator ganz im Allgemeinen tun können. Zumindest nicht vollautomatisch. Betrachten Sie den folgenden fehlerhaften Ausdruck:

a - b + c) * d 

Was sollte ein Parser sogar damit tun? Wenn es auf das erste illegale Token, die schließende Klammer, trifft, könnte es irgendwie erraten, dass der Benutzer irgendwo eine offene Klammer haben wollte, aber wo? Jeder Ort, an den es sich bringen ließe, würde einen anderen Wert ergeben.

Stattdessen könnte es nur so tun, dass alles, was vorher kam, nie passiert ist. Es würde dann am Ende mit

* d 

, die immer noch fehlerhaft ist.

+0

Sie bringen einen guten Punkt, aber mein erster Gedanke, wie mit Ihrem Beispiel, ist es, die enge Klammer fallen lassen (und alle nachfolgenden illegalen Token - dh Schleife, bis Sie eine gültige finden), die vielleicht nicht, was Benutzer beabsichtigt, macht es richtig gebildet.Alternativ können Sie die gesamte Anweisung löschen, beispielsweise ein falsch formatiertes Tag in HTML löschen. Je nach Problem könnte es nützlich sein. Ich bin nicht vertraut mit Parser-Generatoren, aber ich kann mir vorstellen, wie ein Parser es implementieren könnte, also könnte ich mir vorstellen, dass es machbar ist, aber vielleicht nicht mit diesen Tools. –

1

Sie müssen Ihre Grammatik mit Checkpoints entwerfen. Mit Prüfpunkten meine ich das Semikolon für C, einen Zeilenumbruch für Python oder einen Punkt für COBOL (als Beispiele). Dieser Checkpointing gibt an, wie viele Compiler wiederhergestellt werden, sodass sie mehr als nur den ersten gefundenen Fehler melden können.

Ich habe Bison nicht verwendet, aber YACC ermöglicht es Ihnen, die Fehlerbehandlung zu überschreiben und ich würde hoffen, dass das äquivalente GNU-Tool mindestens so mächtig wie unsere alten UNIX-Clunker war.

Ich habe dies zuvor mit einer Konfigurationsdatei YACC Grammatik getan. Sagen Sie bitte das folgende korrekt gebildet Segment haben:

item = "bread" { 
    quantity = 7 
    price = 1.50 
    taxrate = 10 
} 

und aus irgendeinem bizarren Grund, der Benutzer mis-Zauber „Quantität“, wodurch es nicht korrekt. An diesem Punkt Ihrer Rückrufe könnten Sie einfach ein Fehler-Flag auslösen, das eine weitere Verarbeitung verhindert, bis der Prüfpunkt erreicht wurde. Sie lassen den Parser weiterlaufen (fangen und ignorieren weitere Fehler) und stellen sicher, dass Ihre Rückrufe nichts als Reaktion auf falsche Erfolge in der beschädigten Syntax tun.

Dies könnte sein, indem Sie einfach alle weiteren Zeilengruppen bis zur schließenden Klammer ignorieren oder sogar einen Standardwert für den Preis festlegen und nur bis zum Zeilenumbruch ignorieren (so dass Sie zumindest ein teilweise geformtes Objekt erhalten).

Wie auch immer Sie es tun, setzen Sie einfach das Fehler-Flag zurück, wenn Sie den Prüfpunkt erreichen, damit Sie die Verarbeitung fortsetzen können.

Ich würde immer noch sicherstellen, dass der Benutzer benachrichtigt wurde, ist es manchmal als schlechte Form, um mit Daten, die der Kunde nicht wollte :-).