作为我研究的一部分,我正在尝试为某种语言编写解析器。目前,我无法让以下代码以我想要的方式工作:
private def _uw: Parser[UW] = _headword ~ _modifiers ~ _attributes ^^ {
case hw ~ mods ~ attrs => new UW(hw, mods, attrs)
}
private def _headword[String] = "\".*\"".r | "[^(),]*".r
private def _modifiers: Parser[List[UWModifier]] = opt("(" ~> repsep(_modifier, ",") <~ ")") ^^ {
case Some(mods) => mods
case None => List[UWModifier]()
}
private def _modifier: Parser[UWModifier] = ("[^><]*".r ^^ (RelTypes.toRelType(_))) ~ "[><]".r ~ _uw ^^ {
case (rel: RelType) ~ x ~ (uw: UW) => new UWModifier(rel, uw)
}
private def _attributes: Parser[List[UWAttribute]] = rep(_attribute) ^^ {
case Nil => List[UWAttribute]()
case attrs => attrs
}
private def _attribute: Parser[UWAttribute] = ".@" ~> "[^>.]*".r ^^ (new UWAttribute(_))
上面的代码只包含了语言的一部分,为了节省时间和篇幅,我不会对整个语言进行过多的详细介绍。_uw 方法应该解析一个由三部分组成的字符串,尽管只有第一部分必须存在于字符串中。
_uw 应该能够正确解析这些测试字符串:
test0
test1.@attr
"test2"
"test3".@attr
test4..
test5..@attr
"test6..".@attr
"test7.@attr".@attr
test8(urel>uw)
test9(urel>uw).@attr
"test10..().@"(urel>uw).@attr
test11(urel1>uw1(urel2>uw2,urel3>uw3),urel4>uw4).@attr1.@attr2
因此,如果词条以 开头和结尾"
,则双引号内的所有内容都被视为词条的一部分。所有以 开头的词.@
,如果它们不在双引号内,都是词条的属性。
例如在 test5 中,解析器应该解析test5.
为词条和attr
属性。只是 .@ 被省略,并且之前的所有点都应该包含在词条中。
因此,在词条之后可以有属性和/或修饰符。顺序是严格的,所以属性总是在修饰符之后。如果有属性但没有修饰符,则直到所有内容都.@
被视为词条的一部分。
主要问题是"[^@(]*".r
。我尝试了各种创造性的替代方案,例如"(^[\\w\\.]*)((\\.\\@)|$)".r
,但似乎没有任何效果。前瞻或后瞻甚至如何影响解析器组合器?我不是解析或正则表达式方面的专家,所以欢迎所有帮助!