Перевести алгоритмический C на Python - PullRequest
9 голосов
/ 25 сентября 2008

Я хотел бы перевести некоторый код C в код Python или байт-код. Рассматриваемый код C - это то, что я бы назвал чисто алгоритмическим: независимым от платформы, без ввода-вывода, только алгоритмы и структуры данных в памяти.

Примером может служить библиотека регулярных выражений. Инструмент перевода будет обрабатывать исходный код библиотеки и создавать функционально эквивалентный модуль Python, который может быть запущен в среде изолированной .

Какие конкретные подходы, инструменты и методы вы можете порекомендовать?


Примечание. Расширение Python C или ctypes не является опцией , поскольку среда находится в изолированной программной среде.

Еще одно замечание : похоже, есть компилятор C-to-Java-bytecode , они даже скомпилировали libjpeg в Java. Байт-код Java + VM слишком отличается от байт-кода CPython + VM?

Ответы [ 9 ]

12 голосов
/ 25 сентября 2008

Откровенно говоря, нет никакого способа механически и осмысленно перевести C на Python, не понеся безумного снижения производительности. Как мы все знаем, Python не так близко к скорости C (с текущими компиляторами и интерпретаторами), но хуже того, что C хорош (битник, целочисленная математика, трюки с блоками памяти) Python очень медленный, и то, что Python хорош в этом, вы не можете выразить непосредственно в C. Поэтому прямой перевод был бы крайне неэффективным, до абсурда.

Гораздо лучше, в общем случае, действительно сохранить C и C и обернуть его в модуль расширения Python (используя SWIG , Pyrex , Cython или написание оболочки вручную ) или прямой вызов библиотеки C с использованием ctypes . Все преимущества (и недостатки) C для того, что уже C или вы добавите позже, а также все удобства (и недостатки) Python для любого кода в Python.

Это не удовлетворит ваши потребности в «песочнице», но вы должны понимать, что в любом случае вы не можете особенно хорошо тестировать Python; это требует больших усилий и модификации CPython, и если вы забудете одну маленькую дыру где-то, ваша тюрьма сломана. Если вы хотите изолировать Python от песочницы, вы должны начать с песочницы всего процесса, а затем расширения C тоже могут оказаться в песочнице.

4 голосов
/ 28 июля 2011

используйте indent (1) и ctopy (1) ... для дополнительной скорости тестирования кредита на pypy ... для бонусного кредита используйте pyastra для генерации кода сборки.

Независимо от языка, вам всегда придется жертвовать хранением выходов различных конструкций и функций между пространством времени выполнения (CPU) или пространством памяти (RAM).

Проверьте отличную языковую перестрелку, если вы хотите увидеть, о чем я говорю, так или иначе, это слишком много компьютерного снобизма ...

Вот пример, хотите использовать математику с плавающей запятой без использования чисел с плавающей запятой?

x * 1,000,000 = a
y * 1,000,000 = b
a {function} b = result
result / 1,000,000 = z

Не увязай, не примиряйся, используй математику пещерного человека, если нужно.

3 голосов
/ 25 сентября 2008

Самый быстрый способ (с точки зрения усилий программиста, а не эффективности), вероятно, будет включать использование существующего компилятора для компиляции C в нечто простое (например, LLVM) и либо:

  • интерпретировать это в Python (непомерное снижение производительности)
  • перевести это на Python (огромный штраф производительности)
  • перевести это в байт-код Python (большое снижение производительности)

Возможен прямой перевод C в Python (и, вероятно, дает более быстрый код, чем описанные выше подходы), но вы, по сути, будете писать бэкэнд компилятора C, что является огромной задачей.

Редактирование, запоздалая мысль: Возможно, еще более быстрый и грязный способ сделать это - взять дерево разбора для кода C, преобразовать его в структуру данных Python и интерпретировать это в Python.

1 голос
/ 23 апреля 2009

Написать интерпретатор C на чистом Python? ; -)

0 голосов
/ 26 сентября 2008

Я бы лично использовал инструмент для извлечения uml sheme из кода C, а затем использовал его для генерации кода Python.

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

Я думаю, что это был бы более безопасный и эффективный способ.

0 голосов
/ 25 сентября 2008

Вы всегда можете скомпилировать код C и загрузить библиотеки, используя ctypes в python.

0 голосов
/ 25 сентября 2008

Любой автоматический перевод пострадает из-за неиспользования возможностей Python. Процедурный код типа C будет работать очень медленно, если его переводить непосредственно на Python, вам потребуется профилировать и заменять целые разделы более оптимизированным для Python кодом.

0 голосов
/ 25 сентября 2008

Во-первых, я хотел бы рассмотреть обертывание существующей библиотеки C с Pythonic, чтобы обеспечить API в форме модуля Python. Я бы посмотрел на swig, ctypes, pyrex и все остальное, что есть в наши дни. Сама библиотека C останется там без изменений. Сохраняет работу.

Но если бы мне действительно пришлось писать оригинальный код Python, основанный на C, я бы не использовал инструмент, только мой мозг. C допускает слишком много забавных трюков с указателями, умных вещей с макросами и т. Д., Что я никогда бы не стал доверять автоматизированному инструменту, даже если бы кто-то указал мне один.

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

Преобразование из более ограниченных, более укрощенных языков, таких как IDL (языки данных, которые любят использовать ученые, а не другие IDL), является сложным процессом, требующим ручных и умственных усилий. C? Забудьте об этом, пока люди из НЛО не предоставят нам свои модные программные инструменты, которые на тысячу лет опережают наше современное состояние!

0 голосов
/ 25 сентября 2008

Почему бы не сохранить код C и создать модуль Python C , который можно импортировать в работающую среду Python?

...