我正在学习如何在Scala中使用Parsers,并且我正在尝试为一个文本文件构建一个解析器(从StandardTokenParsers扩展),该文本文件可能出现相同的节点类型,其中包含其他节点类型。例如:
[NodeA上] ...
[Node B] ...
[节点A] ...
[节点A] ...
[节点A] ...
如何捕获节点A的所有实例并将其存储在集合中?我认为repsep只能捕获顺序实例。
最后,我希望能够将所有节点实例存储在不同的集合中。
这可能吗?
答案 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]
"""
)