13

Click here to load reader

Makroprocesori

  • Upload
    rhona

  • View
    33

  • Download
    1

Embed Size (px)

DESCRIPTION

Makroprocesori. Zadatak. - PowerPoint PPT Presentation

Citation preview

Page 1: Makroprocesori

Makroprocesori

Page 2: Makroprocesori

Zadatak

• Navesti jedan primer ugneždene parametrizovane makroekspanzije po sintaksi C pretprocesora. Makrodefinicija treba da ima jedan parametar X koji se dva puta pojavljuje u telu makroa: jednom bez operatora ## i drugi put sa njim. Potrebno je navesti ulazni program, kao i izlaz pretprocesora.

• Jedno od mogućih rešenja:

#define MACRO(X) X, X ## 1#define ORIGINAL ZAMENAMACRO(ORIGINAL) • Ovaj ulazni tekst daće sledeći izlaz:ZAMENA, ORIGINAL1

• Pretprocesiranje fajlova:– Gcc:gcc -E <naziv ulaznog fajla>– Microsoft Visual Studio (iz konzole Microsoft VS):cl -E <naziv ulaznog fajla>

Page 3: Makroprocesori

Zadatak

• Definisati strukturu podataka u kojoj biste pamtili jednu makrodefiniciju C pretprocesora u okviru tabele makrodefinicija (tabelu nije potrebno elaborirati). Navesti kako biste popunili tu strukturu podataka primerom makrodefinicije iz rešenja tačke a)?

• Napomena: Prihvatljiva su i druga rešenja, ovde će biti opisano jednostavnije koje zadovoljava postavku zadatka:

struct Mdef {char Name[100]; // ime makrodefinicije int numArgs; // broj formalnih argumenata,

// -1 ako makro nema zagraduchar Body[1000];// telo makrodefinicije

// U telu sa @i označena je normalna // upotreba makroargumenta, a sa // #i upotreba sa operatorom ##

}

• Struktura za MACRO bila bi popunjena na sledeći način:struct Mdef { "MACRO", 1, "@1, #1 ## 1 }

Page 4: Makroprocesori

Zadatak

• Jedan makroprocesor tekst obrađuje na nivou pojedinih atoma (atom je niz neblanko znakova, ograničen blanko znacima). Parametri se ekspanduju po vrednosti. Izuzetak je slučaj kada se na dva parametra primeni operator spajanja ## kada se parametri ne ekspanduju nego se u tekst zamene neposredno nadovežu njihove originalne vrednosti, na primer:

• Makrodefinicije:#define IME1 ZAMENA1#define IME2 ZAMENA2#define MACRO(x,y) x ## y• Makropoziv:MACRO(IME1, IME2) daje tekst zamene IME1IME2• Napisati makrodefiniciju, koja bi u datim uslovima, za gornji

primer dala tekst zamene ZAMENA1ZAMENA2. Objasniti korak po korak ekspanziju te makrodefinicije.

Page 5: Makroprocesori

Rešenje

• Tražena makrodefinicija glasi:

#define MACRO2(x, y) MACRO(x,y)• Pri pozivu: MACRO2(IME1, IME2) prvo se vrši

ekspanzija parametara IME1 i IME2 u ZAMENA1 i ZAMENA2 repsektivno, zatim se obrađuje telo makrodefinicije MACRO2 i u okviru toga vrši poziv MACRO(ZAMENA1, ZAMENA2) koji daje spojene vrednosti svojih argumenata, dakle konačni rezultat ekspanzije je ZAMENA1ZAMENA2.

Page 6: Makroprocesori

EKSPANZIJA PARAMETARA MAKROA

• Šta ako je (stvarni) parametar P makropoziva M zadat tako da i sam za sebe predstavlja makropoziv?

• Dve semantike:– ekspanzija parametra po vrednosti: parametar P se

prvo zasebno ekspanduje i zapamti njegova ekspanzija PE. Zatim, kada se procesira originalni makro M, ekspandovana vrednost parametra (PE)se zamenjuje na svim mestima gde se taj parametar (njegov pozicioni marker) pojavljuje u telu makroa M

– ekspanzija parametra po imenu: počinje se sa ekspandovanjem tela makroa M i gde god se u telu naiđe na korišćenje P, to se tretira kao zaseban (ugneždeni) makropoziv

Page 7: Makroprocesori

Zadatak

• Date su makrodefinicije:MCDEFNMAX A1,A2,A3

LOAD A1CMP A2BGT A3 LOAD A2

A3: NOP MCEND MCSET N=1 MCDEFN GENLABL##NMCSET N=N+1MCEND

• Koji tekst generiše makropoziv MAX 1,2,GENLAB pod pretpostavkom da su makropozivi:

• po vrednostiMAX(1,2, GENLAB)

 • b) po imenu?

MAX(1,2, GENLAB)

Page 8: Makroprocesori

Rešenje

• Date su makrodefinicije:MCDEFNMAX A1,A2,A3

LOAD A1CMP A2BGT A3 LOAD A2

A3: NOP MCEND MCSET N=1 MCDEFN GENLABL##NMCSET N=N+1MCEND

• a) po vrednostiMAX(1,2, GENLAB) MAX(1,2,L1) LOAD 1CMP 2BGT L1LOAD 2L1: NOP

• b) po imenu?MAX(1,2, GENLAB)   LOAD 1 CMP 2 BGT L1 Prva verzija: BGT GENLAB LOAD 2L2: NOP Prva verzija: GENLAB: NOP

Page 9: Makroprocesori

Zadatak

• Za potrebe razvoj softvera koji koristi periferiju X razvijen je simulator te periferije. Simulator je u obliku biblioteke koja se u toku razvoja koristi umesto biblioteke za pristup periferiji X. U fajlu “hardHeader.h” dat je potpis funkcije koja se koristi za pristup periferiji, dok je u fajlu “simHeader.h” potpis odgovarajuće funkcije koja umesto periferije koristi simulator. Prikazati deo koda koji, koristeći C pretprocesor, može da se prevede na dva načina: za testiranje koristeći simulator i za produkciju koristeći periferiju. Jedina izmena u kodu smije da bude u komandi za prevođenje. Fajlovi zaglavlja su dati na narednom slajdu.

Page 10: Makroprocesori

Zadatak

• “hardHeader.h”:

void test(int param1, int param2, int* result);

// primer poziva:// test(a1, a2,// &result);

• “simHeader.h”:

int test(int simStream, int param1, int param2);

// primer poziva:// result =// test(simStream,// a1, a2);

Page 11: Makroprocesori

Varijanta 1

#ifdef SIMULACIJA#include "simHeader.h"#else#include "hardHeader.h"#endif

void main() {

int result, a1 = 1, a2 = 2#ifdef SIMULACIJA, simStream = 4#endif;

// ostatak koda

#ifdef SIMULACIJAresult = test(simStream, a1, a2);

#elsetest(a1, a2, &result);

#endif

//koriscenje rezultata}

Prevođenje za simulaciju:gcc –o p –DSIMULACIJA p.c -lsim

Prevođenje za produkciju:gcc –o p p.c -lhard

Page 12: Makroprocesori

Varijanta 2

#if SIMULACIJA#include "simHeader.h"#else#include "hardHeader.h"#endif

void main() {

int result, a1 = 1, a2 = 2#if SIMULACIJA, simStream = 4#endif;

// ostatak koda

#if SIMULACIJAresult = test(simStream, a1, a2);

#elsetest(a1, a2, &result);

#endif

//koriscenje rezultata}

Prevođenje za simulaciju:gcc –o p –DSIMULACIJA=1 p.c -lsim

Prevođenje za produkciju:gcc –o p –DSIMULACIJA=0 p.c -lhard

Page 13: Makroprocesori

Varijanta 3

#if SIMULACIJA#include "simHeader.h"

#define testCall(p1,...) p1 = test(__VA_ARGS__)#define simStreamDef , simStream = 4

#else#include "hardHeader.h“

#define testCall(p1,p2,p3,...) test(p2,p3,&p1)#define simStreamDef

#endif

void main() {

int result, a1 = 1, a2 = 2 simStreamDef;

// ostatak koda

testCall(result,a1,a2,simStream);

//koriscenje rezultata}

Prevođenje za simulaciju:gcc –o p –DSIMULACIJA=1 p.c -lsim

Prevođenje za produkciju:gcc –o p –DSIMULACIJA=0 p.c -lhard