Я пытаюсь написать парсер для определенного языка в рамках моих исследований. В настоящее время у меня есть проблемы, получая следующий код, чтобы работать так, как я хочу:Невозможно разобрать сложный язык с комбинаторами регулярных выражений и Scala
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] = "[email protected]" ~> "[^>.]*".r ^^ (new UWAttribute(_))
Приведенный выше код содержит только одну часть языка, а также сэкономить время и пространство, я не буду вдаваться в подробности много о весь язык. Метод _uw должен анализировать строку, состоящую из трех частей, хотя только первая часть должна существовать в строке.
_uw должен уметь правильно анализировать эти тестовые строки:
test0
[email protected]
"test2"
"test3"[email protected]
test4..
[email protected]
"test6.."[email protected]
"[email protected]"[email protected]
test8(urel>uw)
test9(urel>uw)[email protected]
"test10..()[email protected]"(urel>uw)[email protected]
test11(urel1>uw1(urel2>uw2,urel3>uw3),urel4>uw4)[email protected]@attr2
Так что, если заглавные начинается и заканчивается "
, все в двойных кавычках считаются частью заглавного слова. Все слова, начинающиеся с [email protected]
, если они не находятся внутри двойных кавычек, являются атрибутами заглавного слова.
E.g. в test5 анализатор должен проанализировать test5.
в качестве заглавного слова и attr
в качестве атрибута. Просто. @ Опущено, и все точки перед этим должны содержаться в главном слове.
Итак, после заголовка МОЖЕТ быть атрибутами и/или модификаторами. Порядок строгий, поэтому атрибуты всегда появляются после модификаторов. Если есть атрибуты, но не модификаторы, все до [email protected]
считается частью заглавного слова.
Основная проблема: "[^@(]*".r
. Я пробовал всевозможные творческие альтернативы, такие как "(^[\\w\\.]*)((\\.\\@)|$)".r
, но ничего не работает. Каким образом lookahead или lookbehind влияют на комбинаторы парсеров? Я не специалист по разбору или регулярному выражению, поэтому вся помощь приветствуется!