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