12
我在写一个Scala分析器组合语法,它读取换行符分隔的单词列表,其中列表由一个或多个空行分隔。鉴于以下字符串:Scala分析器组合器和换行符分隔的文本
cat
mouse
horse
apple
orange
pear
我想要它返回List(List(cat, mouse, horse), List(apple, orange, pear))
。
我写了这个基本的语法,它把单词列表当作换行分隔的单词。请注意,我必须覆盖whitespace
的默认定义。
import util.parsing.combinator.RegexParsers
object WordList extends RegexParsers {
private val eol = sys.props("line.separator")
override val whiteSpace = """[ \t]+""".r
val list: Parser[List[String]] = repsep("""\w+""".r, eol)
val lists: Parser[List[List[String]]] = repsep(list, eol)
def main(args: Array[String]) {
val s =
"""cat
|mouse
|horse
|
|apple
|orange
|pear""".stripMargin
println(parseAll(lists, s))
}
}
这会错误地将空行的空的单词列表,即它会返回
[8.1] parsed: List(List(cat, mouse, horse), List(), List(apple, orange, pear))
(注意中间的空列表。)
我可以把线的一个可选的结束每个列表的结尾。
val list: Parser[List[String]] = repsep("""\w+""".r, eol) <~ opt(eol)
这处理列表之间存在单个空白行但具有多个空行相同问题的情况。
我试图改变lists
定义,允许多个终端的行定界符:
val lists:Parser[List[List[String]]] = repsep(list, rep(eol))
但这挂在上述输入。
将处理多个空行作为分隔符的正确语法是什么?
如果在单词列表之间只有一个空白行,那么这就行得通。如果有_n_空行,我们会在中间以_n-1_伪空列表结束。 (顺便说一句:'skipWhitespace'和'eoi'的例子非常有帮助。) –
@ W.P.McNeill - 我更新了代码以在字符串列表之间寻找'rep1(eol)'。那是你要去的吗? – DaoWen
'rep1(eol)'是我一直在寻找的东西。谢谢。我知道解析器组合器在这里是过度的。为了说明的目的,我故意简化了这个问题。 –