I wrote following parses using fastparse library to get words in pairs. On execution it parses using parsePair properly. But for parseMultiPairs it goes into 100% CPU usage and then exit with OutOfMemoryError.
Got a reply from Haoyi themself here on Discord. Issue with my fastparse spec was my definition of word as CharIn("a-z").repX which is 0 or more characters, instead of CharIn("a-z").repX(1) which is 1 or more characters.
Following is the complete working code:
object Test extends App:
import fastparse.*, MultiLineWhitespace.*
case class Pair(a: String, b: String)
def parsePair[$: P]: P[Pair] = P(CharIn("a-z").repX(1).! ~ CharIn("a-z").repX(1).!).map(Pair(_, _))
def parseMultiPairs[$: P]: P[Seq[Pair]] = P(parsePair.rep ~ End)
println(parse("gnu linux", parsePair(_)))
println(parse("hello world hey there\ngood bye", parseMultiPairs(_)))
end Test
Side note: using rep with a parser that can consume 0 input is a somewhat common class of bug. The implementation of cats-parse removes this class of bug by separating into two types parsers that can parse 0 or more vs 1 or more, and only the 1 or more type has the .rep method:
A second class of bug this library prevents is exponential blow-up in parsing time due to overuse of backtracking. In cats-parse, backtracking is opt-in vs opt-out. You should really try to absolutely minimize use of backtracking in order to avoid accidentally exponential parsers.