setReader
具有指数行为,因为它允许数字之间的空白
可选择的
. 所以对于这一行:
12 34 56
它看到了这些解析:
[1,2,3,4,5,6]
[12,3,4,5,6]
[1,2,34,5,6]
[12,34,5,6]
[1,2,3,4,56]
[12,3,4,56]
[1,2,34,56]
[12,34,56]
你可以看到这怎么可能失控的长队。
ReadP
回报
全部的
有效的解析以递增的长度顺序进行,因此要到达最后一个解析,必须遍历所有这些中间解析。更改:
int_list <- integerReader `sepBy1` innocentWhitespace
致:
int_list <- integerReader `sepBy1` mandatoryWhitespace
为了一个合适的定义
mandatoryWhitespace
压制这种指数行为。parsec使用的解析策略对这种错误的抵抗力更强,因为它是贪婪的——一旦它在给定的分支中使用了输入,它就会被提交到该分支,并且永远不会返回(除非您明确要求它返回)。所以一旦正确解析
12
,它将永远不会返回到解析
1 2
. 当然,这意味着你以什么顺序陈述你的选择是很重要的,我总是觉得这是一个有点痛苦的想法。
我还将使用:
head [ x | (x,"") <- readP_to_S setsReader whole_file ]
为了提取一个有效的整个文件解析,万一它很快消耗了所有的输入,但是有无数种方法来解释这个输入。如果你不在乎歧义,你可能宁愿它返回第一个而不是最后一个,因为第一个会更快到达。