Использование грамматического парсера для Python и построение файлов из дерева - PullRequest
1 голос
/ 01 февраля 2012

У меня есть специальная грамматика для интерпретируемого языка, и я ищу совет по парсеру, который создаст дерево, к которому я могу обратиться.Из структуры я хотел бы иметь возможность генерировать код на интерпретируемом языке.Большинство парсеров грамматики, которые я видел, проверяют уже существующий код.Вторая часть моего вопроса заключается в том, следует ли абстрагировать грамматику до такой степени, что код Python будет заменять символы в дереве для фактической терминологии кода?В идеале я хотел бы иметь возможность запросить корневой символ и вернуть все символы, которые подпадают под этот корень, и т. Д. Вплоть до конечного символа.

Любые советы по этому процессу или мой словарь относительноэто было бы очень полезно.Спасибо.

Ответы [ 2 ]

2 голосов
/ 01 февраля 2012

Подавляющее большинство библиотек синтаксических анализаторов создают абстрактное синтаксическое дерево (AST) из любого кода, который вы генерируете;Вы можете использовать что угодно, например, pyparsing .Чтобы перейти от AST к коду, вам, возможно, придется написать функции вручную, но сделать это рекурсивно довольно просто.Например:

def generate(ast):
    if ast[0] == '+':
        return generate(ast[1]) + " + " + generate(ast[2])
    elif ast[0] == 'for':
        return "for %s in %s:\n" % (ast[1], generate(ast[2])) + generate(ast[3])
    ...

в предположении, что структура AST - это просто список, в котором первый элемент представляет собой тег для имени узла, за которым следуют деревья для любых аргументов: [+, 4, [*, 'x', 5]].Конечно, вы должны использовать все, что использует ваша библиотека синтаксического анализатора, если вы сами не пишете синтаксический анализатор.

Я не понимаю, что вы подразумеваете под заменой символов Python в дереве для фактической терминологии кода.

Вы могли бы написать простую функцию для перебора всех символов в корневом узле:

def traverse_preorder(ast):
    yield ast[0]
    for arg in ast[1:]:
        for x in traverse_preorder(arg):
            yield x

Если подумать, имя переменной ast может быть плохим выбором из-за модуля ast.

2 голосов
/ 01 февраля 2012

Я бы использовал ANTLR. Версия 3 (текущая) поддерживает генерацию кода Python . Он автоматически сгенерирует абстрактное синтаксическое дерево (AST) во время синтаксического анализа, который затем можно будет просмотреть. Важной частью этого будет аннотирование вашей грамматики, с которой токены должны рассматриваться как поддеревья (например, операторы).

...