使用Scala中的StandardTokenParsers捕获所有出现的交错节点

时间:2013-01-08 16:23:07

标签: parsing scala

我正在学习如何在Scala中使用Parsers,并且我正在尝试为一个文本文件构建一个解析器(从StandardTokenParsers扩展),该文本文件可能出现相同的节点类型,其中包含其他节点类型。例如:

[NodeA上] ...

[Node B] ...

[节点A] ...

[节点A] ...

[节点A] ...

如何捕获节点A的所有实例并将其存储在集合中?我认为repsep只能捕获顺序实例。

最后,我希望能够将所有节点实例存储在不同的集合中。

这可能吗?

1 个答案:

答案 0 :(得分:1)

你想要的是一个接受[NodeA]或[NodeB]序列的解析器。 鉴于解析器nodeAParser和解析器nodeBParser,您只需使用|组合器来解析[NodeA]或[NodeB](nodeAParser | nodeBParser),并且然后使用组合子*接受一个序列((nodeAParser | nodeBParser).*)。

一些虚拟的例子:

import scala.util.parsing.combinator.syntactical._
import scala.util.parsing.input._
abstract sealed class Node
case object NodeA extends Node
case object NodeB extends Node

object MyParser extends StandardTokenParsers {
  lexical.delimiters ++= Seq("[", "]")
  lexical.reserved ++= Seq("NodeA", "NodeB")
  lazy val nodeAP: Parser[Node] = "[" ~ "NodeA" ~ "]" ^^ { case _ => NodeA }
  lazy val nodeBP: Parser[Node] = "[" ~ "NodeB" ~ "]" ^^ { case _ => NodeB }
  lazy val nodesP: Parser[List[Node]] = phrase((nodeAP | nodeBP).*)
  def parse( s: String ) = { nodesP( new lexical.Scanner( s ) ) }
}

MyParser.parse(
"""
[NodeA]
[NodeB]
[NodeA]
[NodeA]
[NodeA]
"""
)