Instaparse:有错误,但没有报告

时间:2016-08-24 06:51:26

标签: instaparse

我正在尝试使用Instaparse构建语法。我经常发现这个代码在第一个断言失败,发出“空列表”:

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

我总是解决问题,但它涉及反复试验。有没有办法确定错误?

修复问题的一个示例是从上面代码中变为input的文件中删除尾随空格。

修改

根据Stefan的回答,我改变了代码:

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

上面的代码可以解决问题:始终得到精确答案。对我来说,在insta/parses返回空列表后,需要调用insta/parse来获取错误信息并不是那么明显。使用解析错误documentation将产生比上述更好的代码。它显示了错误信息实际上是如何存在于元数据中的,以及如何检索它 - 这个问题的答案已经在文档中了!

1 个答案:

答案 0 :(得分:1)

当您在输入上使用parser本身而不是通过insta/parses时,它会在REPL处打印出错误的错误消息。

一个例子:

(def ebnf
  "expr = A DOT
   A    = 'A'
   DOT  = '.'")

user> ((insta/parser ebnf) "A.")
[:expr [:A "A"] [:DOT "."]]
user> ((insta/parser ebnf) "B.")
Parse error at line 1, column 1:
B.
^
Expected:
"A"