有什么方法可以加速instaparse?

rwa*_*ace 5 clojure instaparse

我正在尝试在小于700k的dimacs文件上使用instaparse,具有以下语法

<file>=<comment*> <problem?> clause+
comment=#'c.*'
problem=#'p\s+cnf\s+\d+\s+\d+\s*'
clause=literal* <'0'>
<literal>=#'[1-9]\d*'|#'-\d+'
Run Code Online (Sandbox Code Playgroud)

像这样打电话

(def parser
  (insta/parser (clojure.java.io/resource "dimacs.bnf") :auto-whitespace :standard))
...
(time (parser (slurp filename)))
Run Code Online (Sandbox Code Playgroud)

这需要大约一百秒.这比我希望的慢三个数量级.有没有办法加快速度,某种方式来调整语法或某些我缺少的选项?

Thu*_*ail 3

语法错误。是无法满足的。

  • 每个file都以clause.
  • 每个clause都以'0'.
  • 作为一个贪婪的正则表达式literal,将吃掉最后的。clause'0'

结论:clause永远找不到。

例如 ...

=> (parser "60")
Parse error at line 1, column 3:
60
  ^
Expected one of:
"0"
#"\s+"
#"-\d+"
#"[1-9]\d*"
Run Code Online (Sandbox Code Playgroud)

我们可以解析一个literal

=> (parser "60" :start :literal)
("60")
Run Code Online (Sandbox Code Playgroud)

...但不是clause

=> (parser "60" :start :clause)
Parse error at line 1, column 3:
60
  ^
Expected one of:
"0" (followed by end-of-string)
#"\s+"
#"-\d+"
#"[1-9]\d*"
Run Code Online (Sandbox Code Playgroud)

为什么这么慢?

如果有comment

  • 它可以吞掉整个文件;
  • 或在任何'c'字符处被分成连续的comments;
  • 在初始 后的任何点'c'终止。

literal这意味着每个尾部都必须呈现给语法的其余部分,其中包括Instaparse 无法看到内部的正则表达式。因此,一切都必须尝试,而最终都会失败。怪不得这么慢。


我怀疑这个文件实际上是分为几的。你的问题是由于试图将换行符与其他形式的空白混为一谈而产生的。

我可以温和地指出,使用一些小例子(这就是我所做的一切)可能会为您节省很多麻烦。