Fastparse解析多单词对规则时内存耗尽,求修改方案
问题原因与解决方案
问题根源
你的fastparse解析器出现CPU占用100%和OOM的核心原因是:parsePair中使用了repX(允许0次字符匹配),导致parsePair可以匹配空输入(两个空字符串组成的Pair)。当parsePair.rep尝试重复匹配时,会无限循环生成空Pair,直到内存耗尽。
而你用parsy编写的解析器中,word定义为[a-z]+(要求至少1个字符),pair必须由两个非空单词组成,从根本上避免了空匹配的无限循环。
修改方案
将parsePair中的repX.!替换为rep.!——rep在fastparse中默认要求至少1次匹配,确保每个单词必须包含至少一个字符,parsePair无法匹配空输入,从而终止无限循环。
修改后的Scala代码:
import fastparse.*, MultiLineWhitespace.* case class Pair(a: String, b: String) // 用rep.!替代repX.!,确保每个单词至少有1个字符 def parsePair[$: P]: P[Pair] = P(CharIn("a-z").rep.! ~ CharIn("a-z").rep.!).map(Pair(_, _)) def parsePairs[$: P]: P[Seq[Pair]] = P(parsePair.rep ~ End) println(parse("gnu linux", parsePair(_))) println(parse("gnu linux", parsePairs(_))) // 测试多组pair的情况 println(parse("gnu linux hey there\ngood bye", parsePairs(_)))
补充说明
- 由于你导入了
MultiLineWhitespace.*,fastparse会自动跳过语法元素之间的空白字符(空格、换行等),这和parsy中sep_by(regex(r'[ \n]+'))的效果一致,无需额外处理pair之间的分隔符。 End确保解析器必须消耗完所有输入,避免残留未解析的内容。
内容的提问来源于stack exchange,提问作者Xolve
相关产品推荐
相关产品推荐

