Я пишу DSL, используя комбинаторы синтаксического анализатора Scala. Недавно я изменил свой базовый класс со StandardTokenParsers на JavaTokenParsers, чтобы воспользоваться функциями регулярных выражений, которые, как мне кажется, мне нужны для последней части головоломки. (см. Анализ многострочной строки с разделителями с использованием scala StandardTokenParser)
Я пытаюсь извлечь блок текста, разделенный некоторыми символами ({{
и }}
в этом примере). Этот блок текста может занимать несколько строк. На данный момент у меня есть:
def docBlockRE = regex("""(?s)(?!}}).*""".r)
def docBlock: Parser[DocString] =
"{{" ~> docBlockRE <~ "}}" ^^ { case str => new DocString(str) }}
где DocString
- это класс случая в моем DSL. Однако это не работает. Это не сработает, если я скармливаю ему следующее:
{{
abc
}}
{{
abc
}}
Я не уверен, почему это не удается. Если я поставлю оболочку Deubg, вокруг парсера будет оболочка отладки (http://jim-mcbeath.blogspot.com/2011/07/debugging-scala-parser-combinators.html) Я получаю следующее:
docBlock.apply for token
at position 10.2 offset 165 returns [19.1] failure: `}}' expected but end of source found
Если я попробую один блок с разделителями и несколькими строками:
{{
abc
def
}}
тогда он также не может быть проанализирован с помощью:
docBlock.apply for token
at position 10.2 offset 165 returns [16.1] failure: `}}' expected but end of source found
Если я удалю директиву DOTALL (?s)
, я смогу проанализировать несколько однострочных блоков (что мне не очень помогает).
Есть ли способ объединить многострочное регулярное выражение с отрицательным просмотром вперед?
Еще одна проблема, с которой я сталкиваюсь с этим подходом, заключается в том, что независимо от того, что я делаю, закрывающий разделитель должен находиться на отдельной строке от текста. В противном случае я получаю то же сообщение об ошибке, что и выше. Это почти похоже на то, что отрицательный прогноз не работает так, как я ожидал.