Ich versuche, eine Grammatik mit Instaparse aufzubauen. Nicht selten finde ich, dass dieser Code die erste Behauptung fehlschlägt, „Leere Liste“ Emittieren:Instaparse: Es gibt einen Fehler, aber es wird nicht berichtet
(defn parse-it []
(let [parser (insta/parser ebnf)
res (insta/parses parser input)
_ (assert (seq res) (str "Empty list"))
choices (count res)
_ (assert (= choices 1))]
(first res)))
ich immer das Problem beheben, aber es geht Versuch und Irrtum. Gibt es eine Möglichkeit, den Fehler zu lokalisieren?
Ein Beispiel für die Behebung des Problems ist das Entfernen nachstehender Leerzeichen aus der Datei, die im obigen Code input
wird.
(defn parse-it []
(let [my-parser (insta/parser ebnf)
xs (insta/parses my-parser input)
num-choices (count xs)
msg (cond
(zero? num-choices) "insta/parses might be able to be corrected"
(> num-choices 1) (str "insta/parses shows more than one way to parse: " num-choices)
(= 1 num-choices) "insta/parses shows one choice, so all good")
res (cond
;; Just fix there being more than one rather than show them all
;(> num-choices 1) xs
(= num-choices 1) (first xs)
(zero? num-choices) (insta/parse my-parser input))
_ (assert res (str "No result. Num of choices is: " num-choices))]
[msg res]))
Der obige Code funktioniert den Trick:
bearbeiten
Basierend auf Stefan Antwort habe ich den Code geändert immer eine zielgenaue Antwort. Für mich ist es nicht so offensichtlich, dass nach insta/parses
eine leere Liste zurückgibt, muss insta/parse
aufgerufen werden, um die Fehlerinformationen zu erhalten. Die Verwendung der Analysefehler documentation führt zu besserem Code als oben. Es zeigt, wie die Fehlerinformationen tatsächlich in den Metadaten vorhanden sind und wie sie abgerufen werden können - die Antwort auf diese Frage befindet sich bereits in der Dokumentation!