Каковы некоторые методы для генерации кода? - PullRequest
4 голосов
/ 17 ноября 2008

Я генерирую код C ++, и кажется, что он будет очень запутанным, даже у моих простых генерирующих классов уже есть тонны особых случаев. Вот код, который стоит сейчас: http://github.com/alex/alex-s-language/tree/local%2Fcpp-generation/alexs_lang/cpp.

Ответы [ 8 ]

9 голосов
/ 17 ноября 2008

Я написал Cog частично для генерации кода C ++ из схемы данных XML. Он позволяет использовать код Python, встроенный в исходные файлы C ++, для генерации исходного кода C ++.

7 голосов
/ 17 ноября 2008

Одна из техник, которые я использовал для генерации кода, - вообще не беспокоиться о форматировании в генераторе кода. Затем, в качестве следующего шага после генерации кода, выполните его через indent, чтобы разумно отформатировать его, чтобы вы могли прочитать (и, что более важно, отладить) его.

4 голосов
/ 17 ноября 2008

См. Инструменты для создания тестовых случаев .

Непонятно, в чем ваша проблема.

Если вы задаетесь вопросом "как мне обработать все особые случаи в моих генерирующих классах?" тогда вот несколько советов. Если ваш вопрос - что-то еще, обновите ваш вопрос.

  1. Используйте генератор шаблонов. Мако , например, сделает вашу жизнь проще.

    Напишите пример вашего результата. Замените детали заполнителями ${thing}. Поскольку вы начали с чего-то, что сработало, превратить его в шаблон очень просто.

  2. При создании кода на другом языке вам необходимо иметь все определения классов на другом языке, предназначенные для гибкой сборки. Вы хотите генерировать как можно меньше свежего, нового кода. Вы хотите немного настроить и настроить, но не хотите создавать много вещей с нуля.

  3. Особые случаи лучше всего обрабатывать обычным полиморфизмом. Отдельные подклассы общего суперкласса могут реализовывать различные исключения и особые случаи. Действительно сложные ситуации хорошо обрабатываются с помощью шаблона проектирования Strategy .

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

1 голос
/ 04 марта 2012

, как предположил Нед, Cog - отличный инструмент для написания шаблонного кода. Например, мне пришлось написать поддержку системы событий в стиле AOP для определенных классов, чтобы она работала так:

  • вы объявляете метод для класса
  • для каждого метода событие должно вызываться при вызове, передавая аргументы метода в качестве параметров события

Итак, я сделал специальную функцию объявления python, которую я бы вызывал в области cog, которая генерировала бы стандартные объявления и определения для каждого метода и события. В конце области cog пользователь помещает блок кода для функции, которая скрывает реализацию и вызывается оболочкой AOP, примерно так:

class MyFoo
{

public:
/*[[[cog
import myAOPDeclarators
AOP = myAOPDeclarators.AOP

AOP.declareAOPInterceptorMethod( 'invokeSomeStuff' , '(int param1, std::string param2)' )
]]]*/
//AOP wrapper
void invokeSomeStuff_ImplementationAOP(int param1, std::string param2);
void invokeSomeStuff(int param1, std::string param2) {
 sendAOPPreEvent( param1 , param2 , "invokeSomeStuff" );
 invokeSomeStuff_ImplementationAOP( param1 , param2);
}
void invokeSomeStuff_ImplementationAOP(int param1, std::string param2)
//[[[end]]]
{
// ...invokeSomeStuff implementation, not automatically generated
}

Лучшее руководство для генерации кода, которое я могу вам дать; сделает ваш сгенерированный код таким же читабельным, как и написанный вами от руки . Это делает использование генерации кода прозрачным (даже более прозрачным, чем код шаблона, покупайте YMMV). Конечно, как предположил Грег, отступ может быть применен впоследствии, так что на самом деле нет смысла тратить время на смешивание операций над отступами с генерацией кода. если инструмент может обработать исходные файлы в любом случае

1 голос
/ 21 ноября 2008

Я согласен с S.Lott, что вам следует написать пример того, что вы хотите сгенерировать.

Решение проблемы с генерацией кода должно быть менее сложным, чем без.

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

Сгенерированный код также должен работать намного быстрее, потому что он менее общий.

В вашем конкретном случае создание кода за 2 (или более) прохода не повредит. Как и на проходе 1, вы генерируете объявления. На проходе 2 вы генерируете код процесса. В качестве альтернативы вы можете сгенерировать два выходных потока и объединить их в конце.

Надеюсь, это поможет. Извините, если я просто говорю, что очевидно.

0 голосов
/ 19 октября 2012

Я тоже искал что-то подобное и нашел этот вопрос. Я не был очень доволен Cog, поэтому я написал свою собственную, которая похожа, но добавляет некоторые (imo) очень необходимые функции.

https://github.com/icholy/swapm

0 голосов
/ 17 ноября 2008

На самом деле это будет просто рекурсивно, за исключением того, что мне нужно вытащить все объявления функций и поместить их в другое место, а также тот факт, что для всех вызовов функций мне нужно построить вектор всех аргументов, а затем передать к функции, так как C ++ не имеет синтаксиса для векторов.

0 голосов
/ 17 ноября 2008

У меня есть система генерации кода, и один из лучших вариантов, которые я выбрал, это поместить большую часть полученной программы в несгенерированный код, например библиотека / время выполнения. Использование шаблонов также хорошо работает. Сложными системами шаблонов может быть сложно работать вручную, но вы не работаете с ними вручную, так что используйте это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...