Разбор «простой» грамматики

Извините заранее; Я уверен, что этот вопрос будет казаться почти идиотским людям, которые привыкли играть с парсерами и грамматиками, но для меня это чужие темы, и это моя попытка осторожно перейти в практический случай, требующий их.

Я хотел бы написать синтаксический анализатор для следующего «языка», который содержит одну «специальную структуру», которая выглядит так:

\command[ options ]{ contents } 

Содержимое может быть любым, включая вложенные команды, и может содержать экранированные скобки или обратную косую черту \{ \} \\ . Я понимаю, что «что-то» не является конкретным, но в идеале они должны определяться путем сопоставления скобок (исключая экранированные), если это возможно.

Параметры должны быть разделены запятыми списком выражений присваивания, такими как name = value , но значение может быть кавычкой, содержащей = или , символы. Наконец, предыдущее name и command должны проверять регулярное выражение \w[\w\d\._-+*]* то есть первым символом должна быть буква, а остальные символы должны быть буквой, цифрой или один из . _ - + * . _ - + * .

Написание этого с помощью регулярных выражений кажется чрезмерно сложным (например, поскольку значения могут содержать цитируемые символы , = , которые иначе разделяли бы назначения или пары имя / значение). Поэтому я считаю, что наиболее подходящим инструментом здесь является грамматика, но, несмотря на поверхностные чтения, я просто не уверен, как ее написать (BNF, PEG и т. Д.), Какой тип парсеров использовать (LR, рекурсивный и т. Д.)? , и как я мог бы использовать вывод синтаксического анализа в практической программе.

Я бы предпочел ответы с Python, что объясняет тег, но, конечно, я был бы совершенно доволен комбинацией инструментов, если это необходимо / лучше подходит.


ПРИМЕЧАНИЕ: это НЕ о LaTeX. Я понимаю сходство, конечно, но LaTeX чрезвычайно сложнее, чем предыдущий язык, например, с кодами символов, зависящими от контекста. Я просто прошу практический пример, который (я думаю) достаточно прост для SO, и все же был бы полезен для меня в моей повседневной работе.

One Solution collect form web for “Разбор «простой» грамматики”

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

 program := element+ element := command | literal literal := (not '\')+ command := '\'identifier options? '{' program '}' options := option | options ',' option option := identifier '=' value value := number | string string := '"' (escape | not '\' or '"')* '"' escape : = '\' char 

Затем либо подайте это на генератор синтаксического анализатора (pyParsing, pyYACC, ANTLR), либо напишите парсер вручную. В последнем случае простейший вариант – сверху вниз: начинайте с вершины грамматики и конвертируйте каждое правило в функцию, которая либо вернет анализируемый узел АСТ, либо поглотит вход, либо ничего не вернет или не выбросит. Пример:

  def program(): elements = [] while next_sym(): elements.append(element()) return {'type': 'program', 'children': elements} def element(): return command() or literal() def command(): if next_sym() == '\\': get_sym() ...parse command here return {'type': 'command', 'children': ...} return None 

где next_sym возвращает следующий символ из ввода (или None на EOF), а get_sym потребляет символ и продвигает входной буфер.

  • Как проверить наличие атрибутов и тегов в XML перед разбором?
  • Профилировщик строк для кода требует дерева синтаксического анализа и является ли это достаточным?
  • Гибкая обработка числовых строк в Python
  • Что такое хороший синтаксический анализатор потока XML для Python?
  • Странный выход для поточных подпроцессов
  • Лучший способ определить и извлечь даты из текста Python?
  • Как удалить переменные пространства в каждой строке текстового файла на основе специального условия - однострочный в Python?
  • создание словаря-объекта из строки, которая похожа на словари
  • Python - лучший язык программирования в мире.