Разбор строки, содержащей любые символы

Я пытаюсь заставить работать. Итак, у меня есть строки, заключенные в круглые скобки. Строки могут содержать любые символы, и, следовательно, строка, которую я хочу проанализировать, также может содержать круглые скобки. Я думаю, что регулярное выражение в настоящее время соответствует также последним круглым скобкам, которые должны соответствовать ‹~ ")", и, таким образом, синтаксический анализ завершается неудачно. Что мне здесь не хватает?

private def parser: Parser[Any] = a ~ b ~ c ^^ {
    <do stuff here>
}

private def a: Parser[String] = "\"[^\"]*\"".r | "[^(),>]*".r

private def b: Parser[String] = opt("(" ~> ".*".r <~ ")") ^^ {
    case Some(y) => y.trim
    case None       => ""
}

private def c: Parser[String] = rep(".@" ~> "[^>.]*".r) ^^ (new String(_).trim)

Предполагается, что он анализирует следующие типы строк:

test0
test1.@attr
"test2"
"test3".@attr
test4..
test5..@attr
"test6..".@attr
"test7.@attr".@attr
test8(icl>uw)
test9(icl>uw).@attr
"test10..().@"(icl>uw).@attr
test11(icl>uw(agt>uw2,obj>uw3),icl>uw4(agt>uw5))
test12(icl>uw1(agt>uw2,obj>uw3),icl>uw4).@attr1.@attr2
test13(agt>thing,obj>role>effect)

Таким образом, синтаксический анализатор «a» анализирует строку до тех пор, пока не появятся открытые круглые скобки или часть .@attr. Парсер "b" анализирует символы внутри необязательных круглых скобок. «c» анализирует необязательный .@attrs.

В настоящее время я получаю аналогичную ошибку для всех тестовых строк, содержащих часть скобок:

11:07:44.662 [main] DEBUG - Parsed: test8()
11:07:44.667 [main] ERROR - FAILURE parsing: test8(icl>uw) -- `)' expected but `i' found

Итак, я предполагаю, что синтаксический анализатор правильно проанализировал первую часть, но потерпел неудачу, увидев часть со скобками.


person Kitanotori    schedule 23.04.2012    source источник
comment
Вам нужно расширить этот вопрос (возможно) небольшим примером того, что вы пытаетесь сделать и что не работает, так как это просто неясно из вопроса, как в настоящее время сформировался. Например: что должно произойти при получении ввода String (()? Что происходит? Ошибка? Что-то неожиданное?   -  person oxbow_lakes    schedule 23.04.2012
comment
Сделал пример немного понятнее. По сути, я хочу разобрать все, что находится внутри круглых скобок.   -  person Kitanotori    schedule 24.04.2012
comment
Регулярные языки (и, следовательно, регулярные выражения) не могут использоваться для разбора вложенных скобок: они недостаточно выразительны. Вам нужно использовать другую технику, используя либо рекурсию, либо автоматы, либо генератор парсеров.   -  person esope    schedule 24.05.2012


Ответы (1)


Правильным решением для разбора вложенных структур является использование рекурсии, например, следующим образом:

val parser= "regex".r
@tailrec
def extract(string:String,foundTokens:List[String]=List.empty):List[String]={
  parser.findFirstMatchIn(string) match {
  case Some(parser(matchedValue)) => extract(matchedValue,matchedValue::foundedTokens)
  case None=>foundTokens
}

Где в основном при каждом вызове функции вы добавляете найденный токен в список результатов и запускаете функцию по результату совпадения. Когда вы больше не найдете, вы возвращаете найденный токен.

Если внутри каждого субтокена возможно несколько совпадений, вам следует искать такую ​​​​процедуру:

def extract(string:String):Iterator[String]={
   parser.findAllIn(string).flatMap{
      item => extract(item)  
   } 
}
person Edmondo1984    schedule 08.05.2012