разбор вложенных групп (строки в кавычках) с помощью pyparsing (латекс)

Я хочу проанализировать возможные вложенные группы в файле LaTeX: примерно так:

import pyparsing as pp
qs = pp.QuotedString(quoteChar='{', endQuoteChar='}')
s = r'''{ This is a \textbf{\texttt{example}} of \textit{some $\mb{y}$ text} to parse.}'''
print qs.parseString(s)

Но это не может быть правильным (он останавливается на первой закрывающей фигурной скобке). Результат:

([' This is a \\textbf{\\texttt{example'], {})

Как я могу получить результат, который я могу повторить, я думаю о таком возврате, если все, что я хотел, это группы:

{ This is a \textbf{\texttt{example}} of \textit{some $\mb{y}$ text} to parse.}
{\texttt{example}}
{example}
{some $\mb{y}$ text}
{y}

Пример использования — проверить исходный файл LaTeX на распространенные ошибки тегов.


person Tim    schedule 20.09.2013    source источник
comment
Посмотрите, может ли pyparsing nestedExpr быть лучшим выбором, чем QuotedString.   -  person PaulMcG    schedule 21.09.2013


Ответы (1)


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

import pyparsing as pp

allSections = []
def rememberSection(m):
    allSections.append(''.join(m))
other = pp.Word(pp.printables.replace('{','').replace('}','') + ' \t\r\n')
section = pp.Forward()
section << ('{' + pp.OneOrMore(other | section) + '}').setParseAction(rememberSection)

s = r'''{ This is a \textbf{\texttt{example}} of \textit{some $\mb{y}$ text} to parse.}'''
print section.parseString(s)
print allSections

Это определяет, что разрешено находиться внутри раздела, как все, кроме фигурных скобок или другого раздела. Каждая фигурная скобка затем сопоставляется с соответствующей закрывающей скобкой. Если фигурные скобки не совпадают, будет поднято pyparsing.ParseException.

Обычно все токены возвращаются в виде списка токенов, каждый из которых соответствует либо '{', '}', либо ряду других символов без фигурных скобок. Поскольку мы хотим, чтобы каждое выражение в квадратных скобках запоминалось, здесь parseAction добавляет их во внешний список. Я не уверен в каком-либо более чистом способе справиться с этим, но это создаст список allSections, который содержит группы, как вы хотели.

person Eldritch Cheese    schedule 20.09.2013
comment
Хорошее использование Forward для определения выражения рекурсивного синтаксического анализа. В последних версиях pyparsing добавлен аргумент Word, упрощающий выполнение всех печатных форм, кроме x — Word(printables, excludeChars="{}"). - person PaulMcG; 21.09.2013