2016-04-20 2 views
0

У меня есть два класса C1 и C2, которые могут генерировать код C++ с помощью метода printCode(). Используя объекты C1, C2, я может генерировать C++ код следующим образом:Сгенерировать исходный код с помощью цикла

C1* array1[100]; 
C2* array2[100]; 

// Create objects to generate code 
for (int i = 0; i < 100; i++) { 
    array1[i] = new C1(i); 
    array2[i] = new C2(i); 
} 
[...] 
// Generate code 
for (int i = 0; i < 100; i++) { 
    array1[i]->printCode(); 
    array2[i]->printCode(); 
} 

Сгенерированный код:

// f represents a set of operations 
// code generated by array1[0], array2[0] 
(x[0], x[1], ..., x[n]) := f(0, x[0], x[1], ..., x[n]); 
// code generated by array1[1], array2[1] 
(x[0], x[1], ..., x[n]) := f(1, x[0], x[1], ..., x[n]); 
[...] 
// code generated by array1[99], array2[99] 
(x[0], x[1], ..., x[n]) := f(99, x[0], x[1], ..., x[n]); 

Как можно генерировать этот вместо (тот же результат, меньший размер кода):

for (int i = 0; i < 100; i++) 
    (x[0], x[1], ..., x[n]) := f(i, x[0], x[1], ..., x[n]); 

Изменить: Пример определения C1, C2:

const int n = 1000; 
class C1 { 
public: 
    C1(int x) : my_var(x) {} 
    void printCode() { 
     for (int i = 0; i < n - 1; i++) { 
      // func1 is defined in the generated code 
      // the generated code sees foo(my_var) as a constant 
      cout << "x[" << i << "] = func1(x[" << i << "], x[" << i + 1 "] + " << bar(my_var) << endl; 
     } 
    } 

private: 
    int my_var; 
    int foo(int x) { ... } 
} 

C2 похож:

class C2 { 
public: 
    C2(int x) : my_var(x) {} 
    void printCode() { 
     for (int i = 0; i < n - 1; i++) { 
      // func2 is defined in the generated code 
      // the generated code sees bar(my_var) as a constant 
      cout << "x[" << i << "] = func2(x[" << i << "], x[" << i + 1 "] + " << bar(my_var) << endl; 
     } 
    } 

private: 
    int my_var; 
    int bar(int x) { ... } 
} 

С C1, C2, как определено выше, сгенерированный код будет:

// definitions of func1, func2 
int func1(int x, int y) { ... } 
int func2(int x, int y) { ... } 

... 

// Code generated by C1(0) 
x[0] = func1(x[0], x[1]) + f0; // f0 = C1.foo(0) 
x[1] = func1(x[1], x[2]) + f0; 
... 
x[998] = func1(x[998], x[999]) + f0; 
// Code generated by C2(0) 
x[1] = func2(x[0], x[1]) + b0; // b0 = C2.bar(0) 
x[2] = func2(x[1], x[2]) + b0; 
... 
x[999] = func2(x[998], x[999]) + b0; 

// Code generated by C1(1), C2(1) 
// Code generated by C1(2), C2(2) 
... 
// Code generated by C1(99), C2(99) 

Что я хочу:

for (int i = 0; i < 100; i++) { 
    x[0] = func1(x[0], x[1]) + f[i]; // f[i] = C1.foo(i) 
    x[1] = func1(x[1], x[2]) + f[i]; 
    ... 
    x[998] = func1(x[998], x[999]) + f[i]; 

    x[1] = func2(x[0], x[1]) + b[i]; // b[i] = C2.bar(i) 
    x[2] = func2(x[1], x[2]) + b[i]; 
    ... 
    x[999] = func2(x[998], x[999]) + b[i]; 
} 
+0

Вам нужно предоставить более подробную информацию о том, как реализованы ваши классы 'C1' и' C2' – teivaz

+0

@teivaz Я добавил код для C1, C2. – vhl

+0

По-видимому, примеры, которые я добавил, вызывают некоторую путаницу. Цикл for внутри 'printCode()' просто иллюстрирует, что функция печатает много кода. В моем приложении printCode() не может быть оптимизирован. – vhl

ответ

0

Вам нужна некоторая форма абстрактного представления цикла for. Таким образом, вместо того, чтобы писать цикл от 1 до 100, вы создаете на объект цикла типа, как это:

auto loop = createLoop("int", "i", 1, 100); 
loop->add(createC1("i")); 
loop->add(createC2("i")); 
loop->printCode(stdout); 

инкапсулируя конструкторов в фабричных методов, вы можете позволить фабричные методы возврата unique_ptr, и, следовательно, избежать утечек памяти , и избавление от всего ручного отслеживания объектов кучи (вообще не используйте необработанное новое в вашей кодовой базе).

С1 и С2 необходимо, чтобы они могли хранить символы, а не просто константы, как и у вас. Лучший способ поддержать это, чтобы позволить им иметь строковое значение как член вместо int.

printCode from loop должен вызывать printCode от его членов C1 и C2.

0

Было бы, вероятно, будет что-то вроде:

void printCode() { 
    cout << "for (int i = 0; i < " << n - 1 << " ; i++) {" << endl; 
     // func2 is defined in the generated code 
     // the generated code sees bar(my_var) as a constant 
    cout << "x[i] = func2(x[i], x[i + 1] + " << bar(my_var) << ");" << endl; 
    cout << "}" << endl; 
} 
+0

Извините, если мои объяснения были неясны. Ваше исправление создаст: 'code_generated_by C1 [0], C2 [0]; code_generated_by C1 [1], C2 [1]; ...; code_generated_by C1 [99], C2 [99] '. Я хотел: 'for (int i = 0; i <100; i ++) {code_generated_by C1 [i], C2 [i]; } ' – vhl

+0

uhm, в таком случае вы не можете вызвать это в цикле. Какой код генерируется, зависит от того, как вы вызываете методы (т. Е. Если вы вызываете «C1, C2, C1, C2', это именно то, что будет сгенерировано). Вам нужен генератор обертки. –

+0

Итак, в основном генератор, который генерирует генератор? – vhl

Смежные вопросы