Проектирование компилятора

Контрольная работа - Компьютеры, программирование

Другие контрольные работы по предмету Компьютеры, программирование

В таблице мнемокодов отыскивается данный мнемокод и определяется индекс обработчика. Если мнемокод в таблице отсутствует, то генерируется ошибка. После того, как индекс получен, обработка строки передаётся соответствующему обработчику. На данном проходе обработчик определяет формат команды (в частности её длину) и соответствующим образом изменяет счётчик размещения.

К началу второго прохода адреса всех символических имён известны. Во время второго прохода окончательно генерируются объектные коды команд. Если в команде используется символическое имя, то оно отыскивается в таблице символических имён, и в соответствующее поле объектного кода записывается нужное значение (это может быть адрес символического имени или смещение до данного имени в зависимости от используемой команды). Объектный код записывается в вспомогательные файлы. Кроме того, если объектный код содержит поле, нуждающееся в модификации, то в таблицу vmodif записывается запись-модификатор.

Составление объектного файла.

По окончании второго прохода имеется вся необходимая информация для того, чтобы составить объектный файл. Записи, являющиеся неизменными для всех объектных файлов, записываются в виде констант. Остальные записи формируются на основании тех данных, которые были получены в результате первых двух проходов.

 

4. Исходный текст программы компилятора

 

#include;

#include;

#include;

#include;

#include;

#include;i, c, npr, seg, cnt, pmdf, psym, stk[80], pole[4] [8];

//npr - номер прохода, seg - номер сегмента, cnt - счетчик размещения команд

//pmdf - указатель на конец записи модификатора, psym - указатель на конец

// таблицы меток, stk - сюда считывается строка, pole - поля полученные из

// считанной строки.optab[8] [4]={{mov}, {neg}, {je\0}, {inc}, // таблица

{shl}, {adc}, {int}, {dw\0}}, // мнемокодов[8] [3]={{ax}, {cx}, {dx}, {bx}, // таблицы обозначений

{sp}, {bp}, {si}, {di}}, // регистров и[4] [3]={{es}, {cs}, {ss}, {ds}}, // сегментных регистров[17]={0123456789abcdef},[20]; // таблица модификаторов

struct segt {

char name[8];len;

};segtab[2]; // таблица сегментовsymt {name[8];sgm;dsp;

};symtab[10]; // таблица метокstk2pol (char st[80], char pol[4] [8]); // разбиение строки на поляfindop (char op[8]); // поиск мнемокода в OPTABop2code (char nmb, char dis, char pol[4] [8], char code[4]);

// на входе мнемокод, на выходе длинна команды и объектный кодfindreg (char reg[8]); // поиск обознач. регистра в REGTABfindsegr (char reg[8]); // поиск обознач. сег. регистра в SEGRTAB

char findsym (char sym[8]); // поиск метки в SYMTAB

int str2num (char str[8]); // перевод строки в соотв. числоfindch (char c); // поиск поиск символа в HEXTAB

int step (int a, int b); // возведение A в степень B

int main()

{cod[4], lent, // код и длинна команды; // номер обработчика команды* ft; // исходный ассемблерный файлfn[]={myprim.asm};

ft=fopen (fn, r+);();

////////////////////////////first passage\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\(*** first passage ***\n);

seg=0;=0;=0;(! feof(ft)) // повторять пока не конец файла

{fgets (stk, 80, ft); // чтение строки(\n);();(stk);pol (stk, pole); // разбиение строки на поля

if (! strcmp (pole[1], segment)) //if второе поле SEGMENT

{seg++; // увеличение номера сегмента, запись=0; // названия в SEGTAB, сброс счетчика

strcpy (segtab [seg-1].name, pole[0]); // размещения;

}(! strcmp (pole[1], ends)) //if ENDS, то запись длинны сегм-та

{segtab [seg-1].len=cnt;(add to segtab:%s % d % d\n,[seg-1].name, seg, segtab [seg-1].len);;

}((! strcmp (pole[0], assume))||(! strcmp (pole[0], "\0)))

continue; //if пустое поле-чтение сл. строки=findop (pole[0]);(num) //if код операции - увеличение

{lent=op2code (num, 0, pole, cod); // счет. размещ. на ее длинну

if (lent) {printf (lenght:%d\n, lent);+=lent;

}printf (Error: wrong operand!\n);;

}((pole[0] [strlen (pole[0]) - 1]==:)||(! strcmp (pole[1], dw)))

{if (pole[0] [strlen (pole[0]) - 1]==:)[0] [strlen (pole[0]) - 1]=\0; //if метка(findsym (pole[0])==-1) // не найдена в SYMTAB

{strcpy (symtab[psym].name, pole[0]); // занесение в SYMTAB[psym].sgm=seg;[psym].dsp=cnt;(add to symtab:%s % d % d\n,[psym].name, symtab[psym].sgm, symtab[psym].dsp);++;

} //if метка найдена - ошибкаprintf (Error: label % s retry!\n, pole[0]);(! strcmp(pole[1], "\0)) continue;=findop (pole[1]);

if (num) //if код операции - увеличение

{lent=op2code (num, 1, pole, cod); // счет. размещ. на ее длинну

if (lent) {printf (lenght:%d\n, lent);+=lent;

}printf (Error: wrong operand!\n);

}printf (Error: wrong mnemonic code!\n);

} // во всех др. случаях - ошибка

}

////////////////////////////second passage\\\\\\\\\\\\\\\\\\\\\\\\\\\\\* ftmp; // временные файлыfname[2] [10]={{temp1.dat}, {temp2.dat}};();();(*** second passage ***\n);=0;++;=0;(ft);

while (! feof(ft)) // повторять пока не конец файла

{fgets (stk, 80, ft); // чтение строки(\n);();(stk);pol (stk, pole); // разбиение строки на поля

if (! strcmp (pole[1], segment)) //if второе поле SEGMENT

{seg++; // увеличение номера сегмента=fopen (fname [seg-1], w+b); // открыть соотв. вр. файл=0; // сброс счетчика размещения;

}(! strcmp (pole[1], ends)) //if ENDS-заткрыть соотв. вр. файл

{fclose (ftmp);;

}((! strcmp (pole[0], assume))||(! strcmp (pole[0], "\0)))

continue; //if пустое поле-чтение сл. строки=findop (pole[0]);(num) //if мнемокод операции - запись

{lent=op2code (num, 0, pole, cod); // объектн. кода во вр. файл

if (lent) {printf (code:);(i=0; i<lent; i++)

{printf (%x, cod[i]);(cod[i], ftmp);

}+=lent;(\n);

}printf (Error: wrong operand!\n);;

}=findop (pole[1]);(num) //if мнемокод операции - запись

{lent=op2code (num, 1, pole, cod); // объектн. кода во вр. файл(lent) {printf (code:);(i=0; i<lent; i++)

{printf (%x, cod[i]);(cod[i], ftmp);

}+=lent;(\n);

}printf (Error: wrong operand!\n);

} // во всех др. случаях - ошибка

}

/////////////////////creation object file\\\\\\\\\\\\\\\\\\\\\\\\\\* fobj; // создание объектн. файлаfnobj[]={myprim.obj};=fopen (fnobj, w+b);(fobj, %c % c % c % c % s % c, 0x80,0xc, 0x0,0xa, myprim.asm, 0x5d);

// название исходного ассемблерного файла(fobj, %c % c % c % c % c % c % s % c, 0x88,0x20,0x0,0x0,0x0,0x1c,

Turbo Assembler Version 3.2, 0x99); // версия ассембле