Clojure 有没有办法加快instaparse的速度?

Clojure 有没有办法加快instaparse的速度?,clojure,instaparse,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+' 大约需要100秒。这比我希望的要慢三个数量级。有什么方法可以加快速度,有什么方法可

我尝试在一个小于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+'

大约需要100秒。这比我希望的要慢三个数量级。有什么方法可以加快速度,有什么方法可以调整语法,或者有什么我没有的选择吗?

我认为是你对*的大量使用造成了这个问题。(我想)你的语法太模棱两可了。我要检查两件事:

;;run it as
 (insta/parses grammar input)
;; with a small input
这将告诉你在你的语法定义中有多少歧义:“歧义语法”


阅读Engelberg,它将有助于理解你自己的问题,并可能找出最适合你的问题。

语法错误。不能满足

  • 每个
    文件
    都以
    子句
    结尾
  • 每个
    子句
    都以
    '0'
    结尾
  • 子句
    中的
    文本
    ,作为一个 最后的
    '0'
结论:不会发现任何
条款

例如

=> (parser "60")
Parse error at line 1, column 3:
60
  ^
Expected one of:
"0"
#"\s+"
#"-\d+"
#"[1-9]\d*"
我们可以解析
literal

=> (parser "60" :start :literal)
("60")
。。。但不是
子句

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

为什么这么慢

如果有
注释

  • 它可以吞下整个文件
  • 或者在任何
    'c'
    字符处被分解成连续的
    注释
    s
  • 或在首字母
    'c'
    之后的任意点终止
这意味着每个尾部都必须呈现给语法的其余部分,其中包括Instaparse无法看到的
literal
的regexp。因此,一切都必须尝试,最终都会失败。难怪这么慢


我怀疑这个文件实际上被分成了几行。你的问题来自于试图将新行和其他形式的空白合并

请允许我温和地指出,玩几个小例子——这就是我所做的——可能会为你省下很多麻烦

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