Автор работы: Пользователь скрыл имя, 21 Марта 2015 в 19:50, курсовая работа
Транслятор С0 переводит исходную программу с языка С0 на язык ассемблера IBM PC. Таким образом, использование языка ассемблера в качестве объектного языка делает его однопроходным и более удобным в понимании основных методов трансляции, избежав многочисленных деталей генерации машинного кода.
ЗАДАНИЕ……………………………………………………………..
ОПИСАНИЕ ПРИМЕНЕНИЯ………………………………………..
Общие сведения о трансляторе С0…………………………….
Возможности языка C0………………………………………...
Использование компилятора C0………………………………
Сообщения об ошибках………………………………………...
ОПИСАНИЕ ПРОГРАММЫ…………………………………………
Описание новых возможностей языка C0…………………….
3.1.1 Тип данных: char………………………………………..…
3.1.2 Дополнительные операции: ++,--……………………...
3.1.3 if else…………………………………………………
3.1.4 Тип комментария: \………………………………………...
3.1.5 Тип констант: 16……………………………………………
Список подпрограмм транслятора С0 ………………………..
ТЕСТИРОВАНИЕ ПРОГРАММЫ …………………………………..
ЗАКЛЮЧЕНИЕ………………………………………………………..
СПИСОК ЛИТЕРАТУРЫ…………………………………
Казанский государственный научно исследовательский технический университет им. А.Н.Туполева
Кафедра АСОИУ
Курсовая работа
по дисциплине
"Системное программное обеспечение"
Выполнила:
гр.4452
Руководитель:
Казань 2013
СОДЕРЖАНИЕ
3.1.1 Тип данных: char………………………………………..… 3.1.2 Дополнительные операции: ++,--……………………... 3.1.3 if else………………………………………………… 3.1.4 Тип комментария: \\………………………………………... 3.1.5 Тип констант: 16……………………………………………
|
3 3 3 3 4 5 6 5 5 6 12 14 15 17 21 22 23 |
Расширить язык и транслятор С0, реализовав в них следующие возможности:
Транслятор С0 переводит исходную программу с языка С0 на язык ассемблера IBM PC. Таким образом, использование языка ассемблера в качестве объектного языка делает его однопроходным и более удобным в понимании основных методов трансляции, избежав многочисленных деталей генерации машинного кода.
Транслятор написан на языке С и состоит из 18 подпрограмм, которые используют около 30 глобальных переменных.
Трансляция выражений в С0 производиться методом стека с приоритетом. Остальные конструкции языка (операторы и описания) транслируются методом рекурсивного спуска.
Входной язык С0 является подмножеством языка С и содержит данные только целочисленного типа, без массивов. Разрешаются глобальные и локальные переменные, функции с параметрами, рекурсия.
Параметры функции могут быть только входными, поэтому результат работы функции передается только в виде ее значения или присваивается глобальной переменной. Параметры не описываются.
Имеются следующие операторы: оператор-выражение, составной оператор, сокращённый условный оператор, цикл с предусловием, оператор возврата.
В выражениях допускаются:
Отсутствующие в языке С0 логические операции И и ИЛИ можно заменить * или + соответственно.
Примечания.
Грамматика языка СО.
программа ::= {описание-переменных [ описание-функции}...
описание-переменных ::= int имя [,имя]...;
описание-функции ::= имя ( [имя[,имя]...] )
{ [описание-переменных]...[
оператор ::= [выражение]; | { [оператор]... } |
if (выражение) оператор | return [выражение];
while (выражение) оператор
выражение ::= терм [{+|-|*|/|%|<|>|<=|>=|==|!=|=}
терм ::= число | имя | имя ([выражение[,выражение]...]) |
- терм | (выражение)
имя ::= буква [буква|цифра]...
число ::= цифра …
буква
::= A|B|C|D|E|F|G|H|I|J|K|L|M|N|
a|b|c|d|e|f |g|h|i|j|y|k|l|m|n|o|p|q|r|s|
цифра ::= 0|1|2|3|4|5|6|7|8|9
Эта грамматика описывает синтаксис и лексику языка СО. К лексике относятся четыре последних правила.
Для трансляции и выполнения С0-программы используется следующая последовательность команд MS DOS:
с0.exe трансляция
masm p.asm ассемблирование
tlink p.obj компоновка
p.exe [<входной_файл] [>выходной_файл] выполнение
Компилятор С0 вводит исходную программу из файла p.c0, помещая результат трансляции на языке ассемблера в файл p.asm. Затем производятся ассемблирование, компоновка (редактирование связей) и выполнение программы. Объектный и исполняемый модули транслируемой программы обычно получаются в файлах p.asm и p.exe.
Сообщения об ошибках в исходной программе также вставляются компилятором С0 в объектный код в виде строк комментария, содержащего номер (тип) ошибки и символ “^”, указывающий на текущую позицию предшествующей исходной строки в момент обнаружения ошибки. В конце объектной программы вставляется итоговое сообщение о количестве обнаруженных ошибок, дублируемое на экране.
Далее приведён перечень сообщений об ошибках (номер указывает на номер (тип) ошибки):
1. Число больше 32767
2. Слишком много имен
3. Требуется int или имя функции
4. Многократно описанное имя
5. Требуется '('
6. Требуется имя
7. Требуется ')'
8. Не удалось открыть входной или выходной файл
9. Недопустимый символ
10. Требуется ','
11. Требуется '{'
12. Требуется ';'
13. Требуется '}'
14. Имя не описано
15. Неверный ограничитель в
16. Неверный тип операнда
17. Несоответствующие типы
18. Неверный тип левого операнда пpисваивания
19. Нет имени функции
20. Неверный вызов функции
21. Деление на ноль
В процессе расширения функционала была добавлена ошибка
23. Унарная операция.
Вводим перечисление типов данных
enum typ_t {
int_t,char_t
};
Добавляем соответствующее поле в структуру таблицы имен
struct eltabim /* элемент таблицы имен: */
{ char imja[9]; /* имя (байты: 0..8 - имя и 0) */
short vidob; /* вид об'екта:1 - пеpеменная, 3 - фyнкция */
short smesch; /* смещение в области локальных данных */
typ_t typ; /* тип переменной
};
Добавляем структуру str_tip которая описывает переменную C0:
struct sz_typ {
typ_t typ;
int value;
};
Изменим тип данных sz на struct strtype:
sz_typ sz[20];
Добавляем тип лексемы:
enum tipleks { /* тип лексемы: */
osh, ident, chislo, plus, minus, umn, del, ost, ravn, neravn,
men, bol, mravn, bravn, lskob, pskob, zpt, tchzpt, prisv, flskob,
fpskob, ifsl, else, intsl, retsl, whilesl, charsl};
Изменим таблицу служебных слов и добавим типы лексем для служебных слов:
char *tabsl[10]= /* таблица служебных слов */
{"" ,"if", "int", "return", "while", "char","for","to","downto","
enum tipleks tipsl[10]={ ident,ifsl,intsl,retsl,
Добавим функцию opisper_char для описания переменных:
void opisper_char(int t) /* допустимый индекс таблицы для дублиpования имен */
{
int i;
chleks();
while (leksema == ident) {
i = pozic(kolim); /* позиция имени в таблице имен */
if (i > t) oshibka(4); /* нашли - дублиpование имен */
else {
i = vkluch(); /* включить имя в таблицу */
tabim[i].typ = char_t;
tabim[i].vidob = 1; /* вид объекта - пеpем-я */
}
chleks();
if (leksema != tchzpt) {
if (leksema != zpt) oshibka(10); /* тpебуется ','*/
if (leksema != ident) chleks();
}
}
if (leksema != tchzpt) oshibka(12); /* тpебуется ';'*/
}
В функции main
else if (leksema == charsl) { /* слово int */
opisper_char(0);
kolglb=kolim;
Далее, необходимо провести изменения, связанные с оператором присваивания для типов char и int:
else { /* компилиpовать опеpацию */
if (z1->typ == int_t && z2.typ == char_t && *t1 != 0) {
zopreg(z2,t2,"AL");
fprintf(fvih,"\tCBW\n");
fprintf(fvih,"\tPUSH\tAX\n");
t2 = 4;
z2.typ = int_t;
}
void operac(int *z1, int *t1, enum tipleks op, int z2, int t2)
else if (op==uvel || op==umen) /* ++ или -- */
{ op==uvel? strcpy(kop,"INC") : strcpy(kop,"DEC") ;
if (*t1 == 0) /*нет 1-го операнда: префиксная оп-ция */
if(t2==3 && tabim[z2].vidob==1) /*2-й оп-д - пер-я*/
{ fprintf(fvih,"\t%s\t%s\n",kop,
zopreg(z2,t2,"AX");
}
else oshibka(16); /* неверный тип операнда */
else
if(t2==0&&*t1==3&&tabim[*z1].
{ zopreg(*z1,*t1,"AX");
fprintf(fvih,"\t%s\t%s\n",kop,
}
else oshibka(16); /* неверный тип операнда */
}
enum tipleks chleks()
else
if (*usim=='+' || *usim=='-') /* + или - или ++ или -- */
{
c=*usim;
(chsim() == c) /* ++ или -- */
{
if (c == '+') leksema=uvel; /* ++ */
else leksema=umen; /* -- */
chsim(); /* чтение символа след. лексемы */
}
else
leksema=leksim[c]; /* + или - */
}
char *tabsl[6]= /* таблица служебных слов */
{ "" ,"if", "int", "return", "while", "do" };
enum tipleks tipsl[6]={ ident,ifsl, intsl, retsl, whilesl,dosl};
long int st2[28]= /* st2[i]=2**i (i=0..26) */
{1,2,4,8,16,32,64,128,256,512,
32768,65536,131072,262144,
8388608,16777216,33554432,
noper=st2[flskob]|st2[ifsl]|
st2[tchzpt]|nvir; /* мн-во начальных лексем оп-pа */
/*****************************
/* тpансляция опеpатоpа */
/*****************************
void operatr(long mlvoz) /* множ-во лексем возобн-я анализа */
else if (leksema==ifsl) /* IF - условный опеpатоp */
{
tipop=1;
chleks();
if (leksema==lskob)
{
virag(st2[pskob]|noper|mlvoz);
nmet=++kmet; /* # метки ССi */
gen_kom("","POP","AX");
gen_kom("","TEST","AX,AX");
sprintf(top,"CC_%d", nmet); gen_kom("","JNZ",top);
sprintf(top,"CC_%d",++kmet); gen_kom("","JMP",top);
sprintf(top,"CC_%d:",nmet); gen_kom(top,"","");
}
else
oshibka(5); /* тpебуется ( */
operatr(mlvoz);
sprintf(top,"CC_%d:",nmet+1); gen_kom(top,"","");
}
Изменения исходного кода компилятора: для реализации данного типа комментария достаточно внести изменения в функции chleks:
/*****************************
/* чтение лексемы */
/*****************************
enum tipleks chleks()
else /* односимвольная лексема */
{
leksema = leksim[*usim];
if (*usim == '/')
{
chsim();
if (*usim == '/')
{
do
{
chsim(); // пропускаем символы
}
while (*usim != 10 && *usim != 13);
chsim();
leksema = chleks();
}
}
else
{