在Instaparse中以字符串形式获取错误消息的最简单方法?

时间:2018-10-12 18:34:23

标签: clojure instaparse

Instaparse可以将漂亮的错误消息打印到REPL

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

但是我找不到内置函数来将消息作为字符串获取。该怎么做?

2 个答案:

答案 0 :(得分:2)

您始终可以使用with-out-str将其包装起来:

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

您可能还对使用with-err-str documented here感兴趣。

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

我不记得instaparse是写到stdout还是stderr,但是其中之一可以满足您的要求。

答案 1 :(得分:2)

让我们看看失败情况下的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版本来构建字符串,而不是打印它。