Смекни!
smekni.com

Розробка компілятора з вхідної мови програмування (стр. 4 из 5)

Рисунок 5 Місце семантичного аналізатора в моделі компілятора.

Програма перевірки типів перевіряє, щоб тип конструкції відповідав очікуваному в даному контексті. Наприклад, вбудований арифметичний оператор mod в Pascal вимагає цілих операндів, тому програма перевірки типів повинна перевірити, щоб операнди mod в початковій програмі — цілого типу. Так само програма перевірки типів повинна переконатися, що операція розіменування застосовується до покажчика, індексація виконується з масивом, що визначена користувачем функція.

3.4 Розробка оптимізатора коду

компілятор програмування оболонка операційна

Оптимізація програмного коду - це модифікація програм, виконувана оптимізуючим компілятором або інтерпретатором з метою поліпшення їхніх характеристик, таких як продуктивності або компактності, - без зміни функціональності.

Оптимізація - не обов'язковий, але важливий етап компіляції. У принципі, вона може відбуватися під час трансляції програми, але, як правило, оптимізацію програми виділяють як окремий етап функціонування компіляторів. Компонувальники також можуть виконувати частина оптимізацій, таких як видалення невикористовуваних підпрограм або перевпорядкування підпрограм.

Розрізняють низько- і високорівневу оптимізацію. Низкорівнева оптимізація перетворює програму на рівні елементарних команд, наприклад, інструкцій процесорів архітектури x86. Високорівнева оптимізація здійснюється на рівні структурних елементів програми, таких як розгалуження й цикли.

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

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

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

Математично, проблема генерації оптимального коду є нерозв’язною. На практиці ми вимушені користуватись евристичними технологіями, які дають хороший, але не обов’язково оптимальний код. Вибір евристики дуже важливий, оскільки детально розроблений алгоритм розробки генератора коду може давати код, що працю в декілька раз швидше, ніж код отриманий недостатньо продуманим алгоритмом.

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

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

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

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

Отримання на виході генератора коду програми на мові асемблера трохи полегшує процес генерації коду; в результаті ми можемо створювати символьні інструкції і використовувати можливості макросів асемблера. Плата за цю простоту – додатковий крок в обробці мови програмування асемблер після генерації коду.


4 Відладка та тестування компілятора

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

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

'Error 13: Невідомий символ: BegAn '

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

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

Результат тестування в додатку Б.

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

Повідомлення про синтаксичну помилку виводиться, коли синтаксичний аналізатор знаходить ланцюжок лексем, що не відповідає граматиці заданої мови. Для перевірки компілятора на виявлення синтаксичних помилок пропустимо в тексті програми роздільник «;».

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

Error15: Пропущено ; пiсля операцii writeln'

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

Результат тестування в додатку Б.

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

Повідомлення про семантичну помилку виводиться семантичним аналізатором, коли у виразі не співпадають типи використовуваних змінних. Для перевірки компілятора на виявлення семантичних помилок внесемо в текст програми вираз з використанням змінних різних типів. Результат тестування в додатку Б.

'Error 18: Пропущено змінну: b'

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

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

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

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

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

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

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

Загальна перевірка полягає у здатності розробленого компілятора виконувати свої функції. Компілятор повинен транслювати програму у проміжне представлення на мові асемблер та створювати об’єктний і виконуваний файли за допомогою файлів tasm.exe та tlink.exe. Результат тестування в додатку Б.


Висновок

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

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

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

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

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

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

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

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

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

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

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

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

Список використаної літератури

1. Бек Л.С. Введение в системное програмирование. – М.:Мир, 1988.

2. Касаткин М.В. Касаткина Т.Я. Професиональное програмирование на языке С.В 3т. – М. Мир, 1989.//т.3. Системное програмирование.

3. Кузьмин А.Я. Лексический анализ. – М.:ВШ.,1985.

4. Фролов А.В. Проэктирование компиляторов. –М.: Мир,1989.

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

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

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

8. Абель П. Ассемблер для IBM PC, 1991.

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


Додатки

Додаток A

A B C D
13 1 (byte) ^ NOT while-do

program TFirst;

uses App,dialogs,drivers,menus,objects,stddlg,views,validate;

type TMyApp=object(TApplication)

procedure InitStatusLine; virtual;

procedure InitMenuBar; virtual;

procedure NewWindow; virtual;

procedure HandleEvent(var Event:TEvent);virtual;

procedure NewDialog;virtual;

{procedure Init;virtual;}

end;

DialogData=record

{CheckBoxData:Word;

RadioButtonData:word;}

InputLineData:string[128];

end;

MyStruct=record

b:integer;

b1:integer;

c:string[32];

end;

PM13Window=^TM13Window;

TM13Window=object(TWindow)

constructor Init(Bounds:TRect;

WinTitle:string;WindowNo:Word);

procedure MakeInterior(Bounds:TRect);

end;

var M13DialogData:DialogData;

s1:string;

const

MaxLines=2000;

var LineCount:integer;

Lines:array [0..MaxLines-1]of PString;

type

PInterior=^TInterior;

TInterior=object(Tscroller)

constructor Init(var Bounds:TRect;AHScrollBar,

AVScrollBar:PScrollBar);

procedure Draw;virtual;

end;

const cmNewWin=199;cmFileOpen=200;WinCount:Integer=0;cmCompile=201;

procedure TMyApp.InitStatusLine;

var r:TRect;

begin