Самый простой способ получить сообщение об ошибке в виде строки в Instaparse?

Instaparse может печатать хорошие сообщения об ошибках в REPL

=> (negative-lookahead-example "abaaaab")
Parse error at line 1, column 1:
abaaaab
^
Expected:
NOT "ab"

но я не могу найти встроенную функцию для получения сообщения в виде строки. Как это сделать?

2 ответа

Решение

Вы всегда можете обернуть его, используя with-out-str:

(with-out-str 
  (negative-lookahead-example "abaaaab"))

Вы также можете быть заинтересованы в использовании with-err-str задокументировано здесь.

(with-err-str 
  (negative-lookahead-example "abaaaab"))

Я не могу вспомнить, если instaparse пишет в stdout или stderr, но один из них будет делать то, что вы хотите.

Давайте посмотрим на тип возврата parse в случае отказа:

(p/parse (p/parser "S = 'x'") "y")
=> Parse error at line 1, column 1:
y
^
Expected:
"x" (followed by end-of-string)

(class *1)
=> instaparse.gll.Failure

Это красивое поведение при печати определяется в Instaparse следующим образом:

(defrecord Failure [index reason])  
(defmethod clojure.core/print-method Failure [x writer]
  (binding [*out* writer]
    (fail/pprint-failure x)))

В REPL это печатается как полезное для восприятия человеком описание, но его также можно рассматривать как карту:

(keys (p/parse (p/parser "S = 'x'") "y"))
=> (:index :reason :line :column :text)
(:reason (p/parse (p/parser "S = 'x'") "y"))
=> [{:tag :string, :expecting "x", :full true}]

И вы могли бы сделать это:

(with-out-str
  (instaparse.failure/pprint-failure
    (p/parse (p/parser "S = 'x'") "y")))
=> "Parse error at line 1, column 1:\ny\n^\nExpected:\n\"x\" (followed by end-of-string)\n"

Или напишите свою собственную версию pprint-failure который строит строку вместо ее печати.

Другие вопросы по тегам