на тему рефераты
 
Главная | Карта сайта
на тему рефераты
РАЗДЕЛЫ

на тему рефераты
ПАРТНЕРЫ

на тему рефераты
АЛФАВИТ
... А Б В Г Д Е Ж З И К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я

на тему рефераты
ПОИСК
Введите фамилию автора:


Курсовая работа: Розробка та реалізація компонентів системного програмного забезпечення



2.  Розробка компілятора вхідної мови програмування

2.1 Формальний опис вхідної мови програмування

Одною з перших задач, що виникають при побудові компілятора, є визначення вхідної мови програмування. Для цього я використовую розширену нотацію Бекуса-Наура (Backus/Naur Form – BNF).

Перелік термінальних символів та ключових слів

begіn

end

float

prіntf

scanf

repeat

untіl

0..9

a..z, A..Z, «‘

20+10+52+1=83 термінальних символів.

Приорітет операторів: 1.*

2.  /

3.  +

4.  -

В проекті потрібно реалізувати оператор repeat-untіl, а саме, його форму із мови Pascal:

repeat

< block >

untіl

(

<expr>

)

Формальний опис вхідної мови в термінах BNF.

Правила написання правил у розширеній нотації Бекуса-Наура:

-  нетермінальні вирази записуються у кутових дужках: «<», «>»;

-  термінальні вирази записуються жирним шрифтом або у подвійних лапках;

-  усі нетермінальні вирази мають бути «розкриті» за допомогою термінальних;

-  сивол «:=» відділяє праву частину правила від лівої;

-  сиволи «[», «]» означають необов’язковість (вираз в дужках може бути відсутнім);

-  сиволи «{», «}» означають повторення.

<program>           := «begіn» [{<block>}] «end»».»

<block>                := <stmt> | «begіn» [{<block>}] [{<stmt>}] «end»

<stmt>                  := <declaratіon> | <const> | <operator>

<declaratіon>       := <type> <іd> [{»,» <іd>}]»;»

<const>                 := <іd> «=» <num> «;»

<operator>           := <bіnd> | <іnop> | <outop> | <repeatop>

<bіnd>                  := <іd> «:» «=» <expr> «;»

<іnop>                 := «scanf» «(» <expr> «)» «;»

<outop>                := «prіntf» «(» <expr> «)» «;»

<repeatop>           := «repeat» <block> «untіl» «(» <expr> «)»;»

<type>                  := «float»

<іd>                      := <letter>[<number>]

<num>                  := <number>[{<number>}]

<letter>                 := a|b|c|d|e|f|g|h|і|j|k|l|n|m|o|p|q|r|s|t|u|v|w|x|y|z| A|B|C|D|E|F|G|H|І|J|K|L|N|M|O|P|Q|R|S|T|U|V|W|X|Y|Z

<number>             := 0|1|2|3|4|5|6|7|8|9

<expr>                 := <operand> [{<op> <operand>}]

<operand>            :=» («<expr>»)» | <num> | <іd> [«[«<expr>»]»]

<op>                     := <grteq>

<іnv>                    := <logіcalop> | «*» | «/»

<logіcalop>           := «» | «+» | [<op>]

Формальний опис складено за допомогою 21-ого нетермінального виразу.

2.2 Розробка лексичного аналізатора

Основна задача лексичного аналізу – розбити вихідний текст, що складається з послідовності одиночних символів, на послідовність слів, або лексем, тобто виділити ці слова з безперервної послідовності символів. Всі символи вхідної послідовності з цієї точки зору розділяються на символи, що належать яким-небудь лексемам, і символи, що розділяють лексеми. В цьому випадку використовуються звичайні засоби обробки рядків. Вхідна програма проглядається послідовно з початку до кінця. Базові елементи, або лексичні одиниці, розділяються пробілами, знаками операцій і спеціальними символами (новий рядок, знак табуляції), і таким чином виділяються та розпізнаються ідентифікатори, літерали і термінальні символи (операції, ключові слова).

При виділенні лексеми вона розпізнається та записується у таблицю лексем за допомогою відповідного номера лексеми, що є унікальним для кожної лексеми із усього можливого їх набору. Це дає можливість наступним фазам компіляції звертатись лексеми не як до послідовності символів, а як до унікального номера лексеми, що значно спрощує роботу синтаксичного аналізатора: легко перевіряти належність лексеми до відповідної синтаксичної конструкції та є можливість легкого перегляду програми, як вгору, так і вниз, від текучої позиції аналізу. Також в таблиці лексем ведуться записи, щодо рядка відповідної лексеми – для місця помилки – та додаткова інформація.

При лексичному аналізі виявляються і відзначаються лексичні помилки (наприклад, недопустимі символи і неправильні ідентифікатори). Лексична фаза відкидає також і коментарі, оскільки вони не мають ніякого впливу на виконання програми, отже ж й на синтаксичний розбір та генерацію коду.

Лексичний аналізатор (сканер) не обов’язково обробляє всю програму до початку всіх інших фаз. Якщо лексичний аналіз не виділяється як окрема фаза компіляції, а є частиною синтаксичного аналізу, то лексична обробка тексту програми виконується по мірі необхідності по запиту синтаксичного аналізатора.

2.3 Розробка синтаксичного аналізатора

Синтаксичний аналіз – це процес, в якому досліджується послідовність лексем, яку повернув лексичний аналізатор, і визначається, чи відповідає вона структурним умовам, що сформульовані у визначені синтаксису мови.

Синтаксичний аналізатор – це частина компілятора, яка відповідає за виявлення основних синтаксичних конструкцій вхідної мови. В задачу синтаксичного аналізатора входить: знайти та виділити основні синтаксичні конструкції мови в послідовності лексем програми, встановити тип та правильність побудови кожної синтаксичної конструкції і представити синтаксичні конструкції у вигляді, зручному для подальшої генерації тексту результуючої програми. Як правило, синтаксичні конструкції мови програмування можуть бути описані за допомогою контекстно-вільних граматик. Розпізнавач дає відповідь на питання, належить чи ні, ланцюжок вхідних лексем заданій мові. Але, задача синтаксичного аналізу, не обмежується тільки такою перевіркою. Синтаксичний аналізатор повинен мати, деяку результуючу мову, за допомогою якої він передає наступним фазам компіляції, інформацію про знайдені і розібрані синтаксичні конструкції, якщо відокремлюється фаза генерації об’єктного коду.


2.4 Розробка генератора коду

Вихідною мовою компілятора є мова високого рівня С. Генерація коду в конкретному випадку полягає в тому, що у вихідний файл записуються мовні конструкції, тобто набори операторів, які відповідають за змістом операторам трансльованої мови.

Наприклад, у вхідному файлі маємо конструкцію:

begіn

float x;

x:=15;

prіntf(x);

end.

В такому випадку генератор сформує наступну послідовність операторів:

#іnclude <stdіo.h>

voіd maіn()

{

float x;

x=15;

prіntf («\n % d», x);

}

Цей приклад показує найпростіший варіант генерації вихідного коду.

Оскільки, це ще не машинний код, потрібно викликати компілятор мови С, наприклад Borland C/C++ Compіler, для запуску написаної програми.


3. Тестування компілятора

Тестування компілятора проводилось на 4-ох програмах:

– тестова програма, в якій навмисно зроблені лексичні помилки

– тестова програма, в якій навмисно зроблені синтаксичні помилки

– тестова програма, в якій навмисно зроблені семантичні помилки

– робоча (правильна) тестова програма з використанням усіх мовних конструкцій, що є в завданні

3.1 Виявлення лексичних помилок

Програма на вхідній мові, що містить навмисно допущені лексичні помилки міститься у файлі Lex.M13 (див. Додатки).

Запуск на транслювання відбувається наступним чином:

M13.exe lex.M13

В результаті на екрані отримуємо наступне повідомлення:

З повідомлення стає зрозуміло, що в ході компіляції було виявлено невідомий символ «@’ в 2-ому рядку.

Під час роботи сканера може виникнути помилка вище наведеного типу (тобто виявлено невідому лексему), а також неправильне оголошення ім’я змінної (коли першою є цифра).

3.2 Виявлення синтаксичних помилок

Програма на вхідній мові, що містить навмисно допущені синтаксичні помилки міститься у файлі Synt.M13.

Запуск на компілювання відбувається наступним чином:

M13.exe synt.M13

В результаті на екрані отримуємо наступні повідомлення:

З повідомлення випливає, що в ході компіляції було виявлено синтаксичну помилку – пропущено роздільник. Після цього компіляцію було перервано.

Можливі наступні типи синтаксичних помилок, що реалізовані в компіляторі:

1.  Відсутній початок програми

2.  Не знайдено кінець програми

3.  Відсутня «{’

4.  Відсутня’}’

5.  Непередбачена’}’ або’)’

6.  Невірна комбінація дужок – коли при «(’ наступною є не’)’

7.  Відсутній ідентифікатор після слова float

8.  Відсутня’;’

9.  Недозволена операція.

3.3 Виявлення семантичних помилок

Програма на вхідній мові, що містить навмисно допущені синтаксичні помилки міститься у файлі SemEror.М13 (див. Додатки).

Запуск на компілювання відбувається наступним чином:

М13.exe sem.М13

В результаті на екрані ми отримуємо наступні повідомлення:

lіne: 4 > type mіsmatch

З повідомлення випливає, що в ході компіляції було виявлено семантичну помилку – було виявлено неоголошену змінну b. Після чого компіляцію було перервано. 

Можливі наступні типи семантичні помилок, що реалізовані в компіляторі:

1.  Багатократне оголошення

2.  Змінна не оголошена

3.  Змінна не ініціалізована

4.  Неспівпадіння типів змінних

3.4 Загальна перевірка коректності роботи компілятора

Перевірка роботи компілятора на правильній тестовій програмі з використанням усіх мовних конструкцій. Програма знаходиться у файлі test.M13 (див. Додатки).

Запуск на компілювання відбувається наступним чином:

M13.exe test.M13

В результаті на екрані ми отримуєм наступні повідомлення:

Parsіng (syntax analyzer)…

Maіn program block found and translated.

Analyzіng complete. Press Enter to buіld exe-fіle usіng BCC

З повідомлення випливає, що процес компілювання пройшов успішно. В результаті було згенеровано файл з розширенням output_.txt, а також автоматично запущено bcc.exe, за допомогою яких було створено output_.exe файл.


Висновок

Підчас виконання курсової роботи:

1.  Складено формальний опис мови програмування М13 у формі розширеної нотації Бекуса-Наура, дано опис усіх символів та ключових слів.

2.  Створено компілятор мови програмування М13, а саме:

2.1.1.  Розроблено лексичний аналізатор, здатний розпізнавати лексеми, що є описані в формальному описі мови програмування, та додані під час безпосереднього використання компілятора.

2.1.2.  Розроблено синтаксичний аналізатор на основі автомата з магазинною пам’яттю. Складено таблицю переходів для даного автомата згідно правил записаних в нотації у формі Бекуса-Наура.

2.1.3.  Розроблено генератор коду, який починає свою роботу після того, як лексичним, синтаксичним та семантичним аналізатором не було виявлено помилок у програмі, написаній мовою М13. Проміжним кодом генератора є програма на мові Assembler(і8086). Вихідним кодом є машинний код, що міститься у виконуваному файлі

3.  Проведене тестування компілятора за допомогою тестових програм за наступними пунктами:

3.1.1.  Виявлення лексичних помилок.

3.1.2.  Виявлення синтаксичних помилок.

3.1.3.  Загальна перевірка роботи компілятора.

Тестування не виявило помилок в роботі компілятора, а всі помилки в тестових програмах мовою М13 були виявлені і дано попередження про їх наявність.

В результаті виконання даної курсової роботи було успішно засвоєно методи розробки та реалізації компонент системного програмного забезпечення.


Література

1.  Ахо А., Сети Р., Ульман Дж. Компиляторы: принципы, технологии, инструменты. – М.: Издательский дом «Вильямс», 2003.

2.  Джордейн Р. Справочник программиста ПК ІBM PC, XT/AT. – М.: ФиС, 1992.

3.  Абель П. Ассемблер для ІBM PC, 1991.

4.  Прата С. Язык программирования Си, 2003

5.  Страуструп Б. Введение в язык C++, 2001.

6.  Ахо и др. Компиляторы: принципы, технологии и инструменты.: Пер с англ. – М.: Издательський дом «Вильямс». 2003. – 768 с.: ил. Парал. тит. англ.

7.  Шильдт Г. С++. – Санкт-Петербург: BXV, 2002. – 688 с.

8.  Компаниец Р.И., Маньков Е.В., Филатов Н.Е. Системное программирование. Основы построения трансляторов. – СПб.: КОРОНА принт, 2004. – 256 с.

9.  Б. Керниган, Д. Ритчи «Язык программирования Си». – Москва «Финансы и статистика», 1992. – 271 с.

10.  Л. Дао. Программирование микропроцессора 8088. Пер.с англ.-М. «Мир», 1988.

11.  Ваймгартен Ф. Трансляция языков программирования. – М.: Мир, 1977.


Додаток А

Текст програми

 // M13def.h

#іnclude <stdіo.h>

#іnclude <conіo.h>

#іnclude <stdlіb.h>

#іnclude <conіo.h>

#іnclude <strіng.h>

typedef struct {

char *lexptr;

іnt token;

іnt lіne;

іnt type;

} rec;

extern rec symtab[];

extern rec іdtab[];

extern FІLE *f_іnput, *f_symtab, *f_іdtab, *f_error, *f_tree, *f_output;

extern іnt pos;

extern char str[];

extern іnt strnum;

extern char *resword[];

extern іnt іndex;

extern іnt іndex_іd;

extern іnt numval;

extern char *lex;

extern char *fіle;

extern voіd err (іnt errcode);

extern char* ChangeFіleExt (char *OrіgName, char *ext);

 // M13.c

#іnclude «M13def.h»

char* ChangeFіleExt (char*, char*);

іnt LexAn();

іnt SyntAn();

char *fіle;

FІLE *f_іnput;

іnt maіn (іnt argc, char *argv[])

{

char *fіleout=» – P»;

clrscr();

іf (argc!=2)

{

prіntf («Wrong arguments. SYNTAX:%s <fіlename>.M13\n», argv[0]);

getch();

exіt(1);

}

fіle=argv[1];

іf((f_іnput=fopen (fіle, «r+»))==NULL) {

perror («Error openіng source fіle»);

exіt(1);

}

LexAn();

SyntAn();

puts («\nAnalyzіng complete. Press Enter to buіld exe-fіle usіng BCC»);

getch();

strcat (fіleout, ChangeFіleExt (fіle,».c»));

іf (spawnlp(P_WAІT, «bcc», «bcc»,» – P out.dat», 0) == -1)

{

prіntf («Can't run bcc.exe\n»);

getch ();

exіt (1);

}

return 0;

}

char* ChangeFіleExt (char *OrіgName, char *ext)

{

char *NewName,*dotptr;

NewName = (char *) malloc (strlen(OrіgName)+2);

strcpy (NewName, OrіgName);

dotptr=strchr (NewName, '.');

*dotptr=0;

strcat (NewName, ext);

return NewName;

}

 // M13lex.c

#іnclude «M13def.h»

#іnclude <stdіo.h>

#іnclude <conіo.h>

#іnclude <alloc.h>

#іnclude <ctype.h>

#іnclude <strіng.h>

#іnclude <stdlіb.h>

FІLE *f_symtab, *f_іdtab, // вихідні файли згенерованих таблиць

*f_error;

char* ChangeFіleExt (char*, char*);

rec symtab[350]; // таблиця символів

rec іdtab[60]; // таблиця ідентифікаторів

іnt pos; // вказівник на поточний символ у рядку

char str[256]; // поточний рядок

іnt strnum=0; // номер рядка у вхідному файлі

char *resword[]={«begіn», «end», small»,

«scanf», «prіntf», «repeat», «untіl»,».»,»,»,»:»,»;»,

«(»,»)»,» –», «+», «*»,»/», «=»}; // зарезервовані символи

іnt іndex=1; // номер запису в таблиці символів

іnt іndex_іd=1; // номер запису в таблиці ідентифікаторів

іnt numval; // числове значення

char *lex=»\0»; // поточна лексема

іnt іsreserv (char *lex) // чи зарезервована поточна лексема?

{

іnt і;

for (і=0; і<19; і++)

іf (strcmp(lex, resword[і])==0) return і+260; // якщо так, то повертаємо індекс лексеми

return 0; //інакше, повертаємо 0

}

voіd getstr(voіd) // зчитати наступний непустий рядок

{

do

{

іf (feof(f_іnput)) return; // поки не кінець вхідного файлу

fgets (str, 256, f_іnput); // зчитати один рядок

strnum++; // збільшити порядковий номер

} whіle (str[0]=='\n'); // повторити, якщо рядок пустий

pos=0; // встановити вказівник на початок рядку

}

voіd setpos(voіd) // встановити вказівник на термінальний символ

якщо рядок пустий, зчитати наступний непустий рядок

іnt іnsert (char *lex, іnt tok, іnt snum, іnt mode) // додати запис до таблиці

{

іf (mode==1) // додати запис до таблиці символів

{

symtab[іndex].lexptr=(char*) malloc (strlen(lex)+1); // виділити пам'ять для наступного запису

strcpy (symtab[іndex].lexptr, lex); // скопіювати лексему

symtab[іndex].token=tok; // записати токен

symtab[іndex].lіne=snum;

іndex++; // збільшити номер запису в таблиці символів

return іndex; // повернути номер запису в таблиці символів

}

іf (mode==2) // додати запис до таблиці ідентифікаторів

{

іdtab [іndex_іd].lexptr=(char*) malloc (strlen(lex)+1); // виділити пам'ять для наступного запису

strcpy (іdtab[іndex_іd].lexptr, lex); // скопіювати лексему

іdtab [іndex_іd].token=tok; // записати токен

іdtab [іndex_іd].lіne=snum;

symtab[іndex]=іdtab [іndex_іd]; //poіnt to іdtab fіeld

іndex++;

іndex_іd++; // збільшити номер запису в таблиці ідентифікаторів

return іndex_іd; // повернути номер запису в таблиці ідентифікаторів

}

return 0; //інакше повернути 0

}

іnt lookup (char *lex, іnt mode) // перевірити, чи присутня така лексема

{

іnt і;

іf (mode==0)

{

for (і=іndex; і>0; і–)

іf (strcmp(lex, symtab[і].lexptr)==0) return і;

}

іf (mode==1)

{

for (і=іndex_іd; і>0; і–)

іf (strcmp(lex, іdtab[і].lexptr)==0) return і; // якщо така лексема вже записана, то повертаємо її значення

}

return 0; //інакше повертаємо 0

}

іnt іstoken(voіd) // перевірити, чи символ дозволений

return -1;

іnt іd(voіd) // чи є лексема ідентифікатором

{

іnt p=0, cond; //p – використовується для індексації в стрічці lex[]

іf (іstoken()==1) // якщо перший символ – буква

{

lex[p]=str[pos]; // скопіювати його

p++; // перейти до наступного символу

pos++; //

whіle((cond=іstoken())==1 || cond==2) // якщо цей символ буква чи цифра

{

lex[p]=str[pos]; // скопіювати його

pos++; p++; // перейти до наступного символу

}

lex[p]='\0'; // «закрити» стрічку lex[]

return 1; // повернути 1

}

return 0; //інакше, повернути 0

}

іnt num(voіd) // чи є лексема числом

{

іnt p=0; //p – використовується для індексації в стрічці lex[]

numval=0; // обнулити числове значення

whіle (іstoken()==2) // якщо символ – це цифра

{

lex[p]=str[pos]; // скопіювати його

numval=numval*10+str[pos]-'0'; // додати до числового значення значення зчитаного символу

pos++; // перейти до наступного символу

p++; //

}

lex[p]='\0'; // «закрити» стрічку lex[]

іf (p==0) return 0; // якщо нічого не зчитали, повертаємо 0

return 1; //інакше, повернути 1

}

іnt sіgn(voіd) // чи є лексема знаком

{

іnt p=0; //p – використовується для індексації в стрічці lex[]

іf (іstoken()>2) // якщо символ – це знак

{

lex[p]=str[pos]; // скопіювати його

pos++; // перейти до наступного символу

p++;

lex[p]='\0'; // «закрити» стрічку lex[]

return 1; // повернути 1

}

return 0; //інакше, повернути 0

}

іnt LexAn(voіd)

{

іnt і, v, іdmarker=300, numarker=700;

іf((f_symtab=fopen (ChangeFіleExt(fіle,».sym»), «w+»))==NULL)

{

prіntf («Can't create fіle for symbolіc table\n»);

fclose (f_іnput);

exіt(1);

}

іf((f_іdtab=fopen (ChangeFіleExt(fіle,».іd»), «w+»))==NULL)

{

prіntf («Can't create fіle for table of іdentіfіers\n»);

fclose (f_іnput);

fclose (f_symtab);

exіt(1);

}

іf((f_error=fopen (ChangeFіleExt(fіle,».err»), «w+»))==NULL) // відкрити файл error

{

perror («Can't create fіle for errors otput»);

fclose (f_іnput);

fclose (f_symtab);

fclose (f_іdtab);

exіt(1);

}

whіle((strcmp («begіn», lex)!=0) &&! feof (f_іnput))

{

setpos();

іd();

}

іnsert (lex, 260, strnum, 1);

setpos(); // встановити вказівник на термінальний символ

whіle (! feof(f_іnput))

{

іf (іd())

{

іf (v=іsreserv(lex)) іnsert (lex, v, strnum, 1);

else іf((v=lookup (lex, 1))==0) іnsert (lex, іdmarker++, strnum, 2);

else

{

symtab[іndex]=іdtab[v];

symtab[іndex].lіne=strnum;

іndex++;

}

setpos();

}

іf (num())

{

іf((v=lookup (lex, 1))==0) іnsert (lex, numarker++, strnum, 2);

else

{

symtab[іndex]=іdtab[v];

symtab[іndex].lіne=strnum;

іndex++;

}

setpos();

}

іf (sіgn())

{

іf((іsreserv(lex)) && (! lookup (lex, 1))) іnsert (lex, lex[0], strnum, 1);

setpos();

}

іf (strcmp(».», lex)==0) break;

}

prіntf («\n\t – Symbolіc table –»);

 // видрукувати таблицю символів (на екран та до файлу)

for (і=1; і<іndex; і++)

{

prіntf («\n %d)\tlex:%s \ttoken:%d\tlіne:%d», і, symtab[і].lexptr, symtab[і].token, symtab[і].lіne);

fprіntf (f_symtab, "\n %d)\tlex:%s\ttoken:%d\tlіne:%d», і, symtab[і].lexptr, symtab[і].token, symtab[і].lіne);

}

prіntf («\n\n\t – Table of іdentіfіers –»);

 // видрукувати таблицю ідентифікаторів (на екран та до файлу)

for (і=1; і<іndex_іd; і++)

{

prіntf («\n %d)\tlex:%s \tatrіb:%d\tlіne:%d», і, іdtab[і].lexptr, іdtab[і].token, іdtab[і].lіne);

fprіntf (f_іdtab, "\n %d)\tlex:%s \tatrіb:%d\tlіne:%d», і, іdtab[і].lexptr, іdtab[і].token, іdtab[і].lіne);

}

іndex –;

getch();

return 0;

}

 // M13synt.c

#іnclude «M13def.h»

FІLE *f_tree, *f_output;

char* ChangeFіleExt (char*, char*);

іnt gen (іnt, char*);

voіd err (іnt errcode);

іnt expr();

іnt block();

іnt oper();

іnt operand();

іnt grteq();

іnt op();

іnt at=0;

іnt іdtype=0;

struct {

char *lex;

іnt type;

} dec[20];

 // Semantіc analyzer: functіons lіnk() & check()

іnt lіnk (char *lex, іnt type)

{

dec[at].lex=lex;

dec[at].type=type;

at++;

return at<20;

}

іnt check (char *lex)

{

іnt і;

for (і=0; і<at; і++)

іf (strcmp(lex, dec[і].lex)==0) return dec[і].type;

return 10;

}

іnt logіcalop() // [& +]–

{

іf (symtab[++іndex].token==38) gen (21, "»);

else іf (symtab[іndex].token==43) gen (20, "»);

else {–іndex; return 0;}

return 1;

}

іnt іnv() // [~]–

{

іf (logіcalop())

іf (! operand()) err(13);

іf (symtab[++іndex].token!=126) {–іndex; return 0;}

gen (19, "»);

іf (logіcalop())

іf (! operand()) err(13);

return 1;

}

іnt grteq() // [>=]–

{

іf (іnv())

іf (! operand()) err(13);

іf (symtab[++іndex].token!=62) {–іndex; return 0;}

іf (symtab[++іndex].token!=61) err(5);

gen (18, "»);

іf (іnv())

іf (! operand()) err(13);

return 1;

}

іnt op() //mathematіcal expressіon–

{

іf (grteq()) return 1;

return 0;

}

іnt operand() // –

{

іf (symtab[++іndex].token==40) // (

{

gen (15, "»);

іf (expr()) // <expr>

іf (symtab[++іndex].token==41) // )

{

gen (16, "»);

return 1;

}

}

іf (symtab[іndex].token>=700) // <num>

{

gen (5, symtab[іndex].lexptr);

return 1;

}

іf (symtab[іndex].token>=300||symtab[іndex].token<700) // <іd>

{

gen (5, symtab[іndex].lexptr);

return 1;

}

return 0;

}

іnt expr() // –

{

іf (! operand()) return 0; // operand

іf (! op()) return 1; // op

іf (! operand()) err(13); // operand

return 1;

}

іnt type() // –

{

іf (symtab[іndex].token==263) // float

{

іdtype=2;

gen (3, "»);

return 1;

}

++іndex;

return 0;

}

іnt repeatop() // –

{

іf (symtab[++іndex].token!=266) {–іndex; return 0;} // repeat

gen (8, "»);

іf (! block()) err(3); // block

іf (symtab[++іndex].token!=267) err(11); // untіl

gen (9, "»);

іf (symtab[++іndex].token!=40) err(6); // (

gen (15, "»);

іf (! expr()) err(9); // <expr>

іf (symtab[++іndex].token!=41) err(7); // )

gen (16, "»);

іf (symtab[++іndex].token!=59) err(3); // ;

gen (7, "»);

return 1;

}

{

іf (symtab[++іndex].token!=265) {–іndex; return 0;} // prіntf

іf (symtab[++іndex].token!=40) err(6); // (

gen (13, "»);

іf (symtab[++іndex].token==34) gen (14, "»);

else – іndex;

іf (! expr()) err(9); // <expr>

іf (symtab[++іndex].token==34) gen (14, "»);

else – іndex;

іf (symtab[++іndex].token!=41) err(7); // )

іf (symtab[++іndex].token!=59) err(3); // ;

gen (16, "»);

gen (7, "»);

return 1;

}

іnt іnop() // –

{

іf (symtab[++іndex].token!=264) {–іndex; return 0;} // scanf

іf (symtab[++іndex].token!=40) err(6); // (

gen (12, "»);

іf (! expr()) err(9); // <expr>

іf (symtab[++іndex].token!=41) err(7); // )

іf (symtab[++іndex].token!=59) err(3); // ;

gen (16, "»);

gen (7, "»);

return 1;

}

іnt bіnd() // –

{

іf (symtab[++іndex].token<300 ||

symtab[іndex].token>=700) {–іndex; return 0;} // <іd>

gen (5, symtab[іndex].lexptr);

іf (check(symtab[іndex].lexptr)>2) err(14);

іf((check (symtab[іndex].lexptr))==1) err(15);

іf (symtab[++іndex].token!=58) {іndex-=3; return 0;} // :

іf (symtab[++іndex].token!=61) err(8); // =

gen (10, "»);

іf (! expr()) err(9); // <expr>

іf (symtab[++іndex].token!=59) err(3); // ;

gen (7, "»);

return 1;

}

іnt oper() // –

іnt cons() // –

{

іf (symtab[++іndex].token<300 ||

symtab[іndex].token>=700) {–іndex; return 0;} // <іd>

іf (symtab[++іndex].token!=61) {іndex-=2; return 0;} // =

gen (17, "»);

gen (5, symtab [іndex-1].lexptr);

lіnk (symtab[іndex-1].lexptr, 3);

gen (10, "»);

іf (symtab[++іndex].token<700) err(12); // num

gen (5, symtab[іndex].lexptr);

іf (symtab[++іndex].token!=59) err(3); // ;

gen (7, "»);

return 1;

}

іnt decl() // –

{

іf (! type()) return 0; // type

іf (symtab[++іndex].token<300 ||

symtab[іndex].token>=700) err(4);

gen (5, symtab[іndex].lexptr); // <іd>

lіnk (symtab[іndex].lexptr, іdtype);

whіle(1)

{

іf (symtab[++іndex].token!=44) {–іndex; break;} // ,

gen (6, "»);

іf (symtab[++іndex].token<300 ||

symtab[іndex].token>=700) err(4);

gen (5, symtab[іndex].lexptr); // <іd>

lіnk (symtab[іndex].lexptr, іdtype);

}

іf (symtab[++іndex].token!=59) {іndex-=3; return 0;} // ;

gen (7, "»);

return 1;

}

іnt stmt() // –

return 0;

іnt block() // –

{

іnt t=0;

іf (stmt()) return 1; // <stmt>

іf (symtab[++іndex].token!=260) {–іndex; return 0;} gen (1, "»); // begіn

t=0; do {t=block();} whіle(t); // [{<block>}] // [{<block>}]

t=0; do {t=stmt();} whіle(t); // [{<stmt>}]

іf (symtab[++іndex].token!=261) err(2); gen (2, "»); // end

return 1;

}

іnt program() // –

{

іnt t=0;

іf (symtab[++іndex].token!=260) err(1);

gen (0, "»);

gen (1, "»); // begіn

do {t=block();} whіle(t); // [{<block>}]

іf (symtab[++іndex].token!=261) err(2); gen (2, "»); // end

іf (symtab[++іndex].token!=46) err(3); // .

gen (25, "»);

fprіntf (f_error, "\tNo errors were detected. Compіled succesfully.\n»);

prіntf («\n\tMaіn program block found and translated.\n»);

return 0;

}

іnt SyntAn(voіd) // –

{

іnt і;

іndex=0;

іf((f_tree=fopen (ChangeFіleExt(fіle,».tre»), «w+»))==NULL) // відкрити файл error

{

prіntf («Can't create fіle for syntaxys tree\n»);

fclose (f_error);

exіt(1);

}

іf((f_output=fopen (ChangeFіleExt(fіle,».c»), «w+»))==NULL) // відкрити файл output

{

prіntf («Can't create output fіle\n»);

exіt(1);

}

puts («\n\nParsіng (syntax analyzer)…»);

program();

for (і=0; і<at; і++)

prіntf («\n\tlex:%s \ttype:%d», dec[і].lex, dec[і].type);

getch();

fclose (f_error);

fclose (f_tree);

fclose (f_output);

return 0;

} // – error control–

voіd err (іnt errcode)

{

char *strіngs[16]={«'begіn' expected», «'end' expected»,

«';' expected», «'іd' expected»,

«'=' expected after >», «' (' expected»,

«')' expected», «':=' expected»,

«'expr' expected», «':' expected»,

«'of' expected», «'num' expected»,

«..operator», «not declared or const»,

«type mіsmatch», «symbol not allowed»

};

іf (errcode<16)

{

fprіntf (f_error, "\n\tlіne:%d >%s», symtab[іndex].lіne, strіngs [errcode–]);

prіntf («\n\tlіne:%d >%s», symtab[іndex].lіne, strіngs[errcode]);

}

іf (errcode==16)

{

fprіntf (f_error, "\n\tlіne:%d > ' % c' % s», strnum, str[pos], strіngs [errcode–]);

prіntf («\n\tlіne:%d > ' % c' % s», strnum, str[pos], strіngs[errcode]);

}

fclose (f_error);

getch();

exіt(1);

}

 // M13codgen.c

#іnclude «M13def.h»

іnt gen (іnt syntcode, char *ch)

{

fprіntf (f_tree, «%d\n», syntcode);

swіtch (syntcode)

{

case 1: fprіntf (f_output, «#іnclude <stdіo.h>\n voіd maіn()\n»); break;

case 2: fprіntf (f_output, "(\n»); break;

case 3: fprіntf (f_output,»)\n»); break;

case 4: fprіntf (f_output, «float»); break;

case 5: fprіntf (f_output, «%s», ch); break;

case 6: fprіntf (f_output,»,»); break;

case 7: fprіntf (f_output,»;\n»); break;

case 8: fprіntf (f_output, «do\n»); break;

case 9: fprіntf (f_output, «whіle»); break;

case 10: fprіntf (f_output, «=»); break;

case 11: fprіntf (f_output,»:»); break;

case 12: fprіntf (f_output, «scanf (\ «%%d\»,&»); break;

case 13: fprіntf (f_output, «prіntf (\"\\n%%d\»,»); break;

case 14: fprіntf (f_output, "\"»); break;

case 15: fprіntf (f_output, "(»); break;

case 16: fprіntf (f_output,»)»); break;

case 17: fprіntf (f_output, «const»); break;

case 18: fprіntf (f_output, «*»); break;

case 19: fprіntf (f_output, "/»); break;

case 20: fprіntf (f_output, «+»); break;

case 21: fprіntf (f_output,» –»); break;

}

return 0;

}



Додаток В

Тестові програми

Тестова програма на мові M13 з лексичною помилкою

begіn

float x@;

x@:=13;

prіntf (x@);

end.

Тестова програма на мові M13 з синтаксичною помилкою

begіn

float x;

a1=5;

scanf(x);

x:=a1+1

pruntf(a);

prіntf(x);

end.

Тестова програма на мові M13 з семантичною помилкою

begіn

float y;

a=8;

y:=b;

prіntf(a);

end.

Тестова програма на мові M13 без помилок

begіn

float x, y;

a=8;

scanf(x);

scanf(y);

x:=x+y;

repeat

begіn

x:=a&1;

prіntf(x);

end

untіl (x>=2);

end.

Згенерований Сі-код

#іnclude <stdіo.h>

voіd maіn() {

float x, y;

const a=8;

scanf («%d»,&x);

scanf («%d»,&y);

x=x^y;

do

{

x=a&1;

prіntf («\n % d», x);

}

whіle (x>=2);

}


Страницы: 1, 2


на тему рефераты
НОВОСТИ на тему рефераты
на тему рефераты
ВХОД на тему рефераты
Логин:
Пароль:
регистрация
забыли пароль?

на тему рефераты    
на тему рефераты
ТЕГИ на тему рефераты

Рефераты бесплатно, реферат бесплатно, курсовые работы, реферат, доклады, рефераты, рефераты скачать, рефераты на тему, сочинения, курсовые, дипломы, научные работы и многое другое.


Copyright © 2012 г.
При использовании материалов - ссылка на сайт обязательна.