Подавляющее большинство библиотек синтаксических анализаторов создают абстрактное синтаксическое дерево (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.