Написание компилятора для DSL на Python - PullRequest
6 голосов
/ 04 декабря 2008

Я пишу игру на python и решил создать DSL для файлов данных карты. Я знаю, что мог бы написать свой собственный синтаксический анализатор с помощью регулярных выражений, но мне интересно, существуют ли существующие инструменты Python, которые могут сделать это проще, например, re2c, который используется в движке PHP.

Дополнительная информация:

  • Да, мне нужен нужен DSL, и даже если бы я этого не делал, мне все еще нужен опыт создания и использования одного в проекте.
  • DSL содержит только данные (декларативные?), Они не выполняются. Большинство строк выглядят так:

    SOMETHING: !abc @123 #xyz/123

    Мне просто нужно прочитать дерево данных.

Ответы [ 8 ]

12 голосов
/ 04 декабря 2008

Я всегда был впечатлен pyparsing . Автор, Пол Макгуайр, активен в списке python / comp.lang.python и всегда очень помогал с любыми вопросами, касающимися этого.

7 голосов
/ 04 декабря 2008

Существует множество инструментов разбора Python: http://nedbatchelder.com/text/python-parsers.html

6 голосов
/ 04 декабря 2008

Вот подход, который действительно хорошо работает.

abc= ONETHING( ... )
xyz= ANOTHERTHING( ... )
pqr= SOMETHING( this=abc, that=123, more=(xyz,123) )

декларативная. Простой в разборе.

И ...

Это на самом деле Python. Несколько объявлений класса и работа сделана. На самом деле DSL - это объявления классов.

Что важно, так это то, что DSL просто создает объекты. Когда вы определяете DSL, сначала вы должны начать с объектной модели. Позже вы поместите некоторый синтаксис вокруг этой объектной модели. Вы начинаете не с синтаксиса, а с модели.

4 голосов
/ 04 декабря 2008

Да, есть много - слишком много - инструментов разбора, но в стандартной библиотеке их нет.

Из того, что я видел, популярны PLY и SPARK. PLY похоже на yacc, но вы все делаете на Python, потому что пишете грамматику в строках документации.

Лично мне нравится концепция синтаксических анализаторов (взятая из функционального программирования), и мне очень нравится pyparsing : вы пишете свою грамматику и действия непосредственно в python, и с ней легко начать. Я закончил тем, что производил свои собственные типы узлов дерева с действиями, вместо того, чтобы использовать их тип ParserElement по умолчанию.

В противном случае вы также можете использовать существующий декларативный язык, например YAML .

2 голосов
/ 02 ноября 2009

Для «малых языков», которые вы описываете, я использую простое разбиение, shlex (помните, что # определяет комментарий) или регулярные выражения.

>>> line = 'SOMETHING: !abc @123 #xyz/123'

>>> line.split()
['SOMETHING:', '!abc', '@123', '#xyz/123']

>>> import shlex
>>> list(shlex.shlex(line))
['SOMETHING', ':', '!', 'abc', '@', '123']

Ниже приведен пример, так как я не знаю точно, что вы ищете.

>>> import re
>>> result = re.match(r'([A-Z]*): !([a-z]*) @([0-9]*) #([a-z0-9/]*)', line)
>>> result.groups()
('SOMETHING', 'abc', '123', 'xyz/123')
2 голосов
/ 05 декабря 2008

Питер,

DSL - это хорошая вещь , так что вам не нужно защищаться :-) Тем не менее, вы рассматривали внутренний DSL? У них так много плюсов по сравнению с внешними (проанализированными) DSL, что их стоит хотя бы рассмотреть. Сочетание DSL с мощью родного языка действительно решает для вас много проблем, и Python неплохо справляется с внутренними DSL, с удобным оператором with.

2 голосов
/ 04 декабря 2008

Я написал что-то подобное в работе, чтобы читать определения уведомлений SNMP и автоматически генерировать Java-классы и файлы SNMP MIB из этого. Используя этот маленький DSL, я мог написать 20 строк своей спецификации, и он генерировал бы примерно 80 строк Java-кода и 100-строчный MIB-файл.

Чтобы реализовать это, я фактически использовал прямую обработку строк Python (split (), нарезку и т. Д.) Для анализа файла. Я считаю, что возможности строки Pythons адекватны большинству моих (простых) потребностей в разборе.

Помимо библиотек, упомянутых другими, если бы я писал что-то более сложное и нуждалось в надлежащих возможностях синтаксического анализа, я бы, вероятно, использовал ANTLR , который поддерживает Python (и другие языки).

1 голос
/ 18 ноября 2011

В строках декларативного python я написал вспомогательный модуль под названием «bpyml», который позволяет объявлять данные в python более структурированным способом XML без подробных тегов, они также могут быть преобразованы в / из XML, но допустимы питон.

https://svn.blender.org/svnroot/bf-blender/trunk/blender/release/scripts/modules/bpyml.py

Пример использования http://wiki.blender.org/index.php/User:Ideasman42#Declarative_UI_In_Blender

...