Aleksei Sotnikov
Aleksei Sotnikov

Reputation: 643

Easiest way to get an error message as a string in Instaparse?

Instaparse can pprint nice error messages to the REPL

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

but I can not find a built-in function to get the message as a String. How to do that?

Upvotes: 1

Views: 201

Answers (2)

Alan Thompson
Alan Thompson

Reputation: 29974

You could always wrap it using with-out-str:

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

You may also be interested in using with-err-str documented here.

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

I can't remember if instaparse writes to stdout or stderr, but one of those will do what you want.

Upvotes: 2

Taylor Wood
Taylor Wood

Reputation: 16194

Let's look at the return type of parse in the failure case:

(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

This pretty printing behavior is defined like this in Instaparse:

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

In the REPL this prints as a helpful human-readable description, but it can also be treated as a map:

(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}]

And you could do this:

(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"

Or write your own version of pprint-failure that builds a string instead of printing it.

Upvotes: 2

Related Questions