我使用
fastparse
库编写了以下解析器来成对获取单词。执行时它会正确使用 parsePair
进行解析。但对于 parseMultiPairs
,它会进入 100% CPU 使用率,然后以 OutOfMemoryError
退出。
import fastparse.*, MultiLineWhitespace.*
case class Pair(a: String, b: String)
def parsePair[$: P]: P[Pair] = P(CharIn("a-z").repX.! ~ CharIn("a-z").repX.!).map(Pair(_, _))
def parsePairs[$: P]: P[Seq[Pair]] = P(parsePair.rep ~ End)
println(parse("gnu linux", parsePair(_)))
println(parse("gnu linux", parsePairs(_)))
我想也许我写的语法不正确。所以我在Python的
parsy
库中编写了类似的语法:
from parsy import *
word = regex(r'[a-z]+')
pair = word.sep_by(regex(r' +'), min=2, max=2)
pairs = pair.sep_by(regex(r'[ \n]+'))
print(word.parse('hello'))
print(pair.parse('hello world'))
print(pairs.parse('hello world hey there\ngood bye'))
它按预期工作并且能够解析所有输入。我需要对
fastparse
进行哪些更改才能使其正常工作?
在Discord 上得到了Haoyi 本人的回复。我的 fastparse
规范的问题是我对单词的定义为
CharIn("a-z").repX
,即 0 个或多个字符,而不是
CharIn("a-z").repX(1)
,即 1 个或多个字符。以下是完整的工作代码:
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