setReader has exponential behavior because it allows you to eliminate spaces between numbers. So for the line:
12 34 56
He sees these analyzes:
[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]
You could see how this could fail for long lines. ReadP returns all valid parses in increasing order of length, so you must go through all these intermediate paragraphs to get to the last parsing. Change:
int_list <- integerReader `sepBy1` innocentWhitespace
To:
int_list <- integerReader `sepBy1` mandatoryWhitespace
For a suitable definition of mandatoryWhitespace for squash this exponential behavior. The parsec strategy used by parsec is more resistant to this error because it is greedy - when it consumes input in this branch, it is bound to this branch and never returns (unless you explicitly set it). Therefore, once he has correctly analyzed 12 , he will never return to analysis 1 2 . Of course, this means that it is important in which order you set out your choice, which always seems a little sick to me to think.
Also I would use:
head [ x | (x,"") <- readP_to_S setsReader whole_file ]
To extract valid parsing of an entire file if it consumes the entire input very quickly, but there are one hundred basic ways of interpreting this input. If you donβt care about the ambiguity, you are more likely to return the first than the last, because the first will be faster.