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

Автор: Пользователь скрыл имя, 25 Февраля 2012 в 16:19, курсовая работа

Описание работы

Незважаючи на більш ніж піввікову історію обчислювальної техніки, формально роком народження теорії трансляторів можна вважати 1957, коли з'явився перший транслятор мови Фортран, створений Бекасом. До цього часу створення трансляторів було досить "творчим" процесом. Лише поява теорії формальних мов і строгих математичних моделей дозволило перейти від "творчості" до "науки".

Содержание

Вступ
1. Огляд методів та способів проектування трансляторів
1.1. Основні поняття і визначення
1.2. Узагальнена структура транслятора
1.4. Варіанти взаємодії блоків транслятора
2. Формальний опис вхідної мови програмування
2.1. Деталізований опис вхідної мови в термінах розширеної нотації Бекуса-Наура
2.2. Опис термінальних символів та ключових слів
3. Розробка транслятора вхідної мови програмування
3.1. Вибір технології програмування
3.2. Проектування таблиць транслятора та вибір структур даних
3.3. Розробка лексичного аналізатора
3.3.1. Розробка граф-схеми алгоритму
3.3.2. Опис програмної реалізації лексичного аналізатора
3.4. Розробка синтаксичного та семантичного аналізатора
3.4.1. Розробка граф-схеми алгоритму
3.4.2. Опис програмної реалізації синтаксичного та семантичного аналізатора
3.5. Розробка генератора коду
3.5.1. Розробка граф-схеми алгоритму
3.5.2. Опис програмної реалізації генератора коду
4. Опис інтерфейсу та інструкції користувача
4.1. Опис інтерфейсу
4.1.1. Головне меню та панель інструментів.
4.2. Інструкція програміста
4.2.1. Алфавіт мови
4.2.2. Коментарі
4.2.3. Тип даних
4.2.4. Розділи, використовувані при написанні програм
4.2.5. Типи операцій
4.2.6. Типи операторів
5. Відлагодження та тестування програми
5.1. Виявлення лексичних помилок
5.2. Виявлення синтаксичних помилок
5.3. Виявлення семантичних помилок
5.4. Загальна перевірка коректності роботи транслятора
Висновки
Список літератури
Додатки
А. Лістинг програми

Работа содержит 1 файл

asm_cource_k9.doc

— 1,020.00 Кб (Скачать)

зчитуються в буфер  string buffer;блок (14) і якщо вони є числом – тоді опрацьовуються як константа(блоки 18, 19), якщо зарезервованим словом тоді визначається яке саме це слово і утворюється відповідна лексема (блоки 20, 21), інакше лексема є ідентифікатором (блок 22)

-  Якщо символ не є початком лексеми, то символи до роздільника зчитуються в буфер, і додається повідомлення про помилку(блоки 15, 16).

-  Повертається створена на початку функції, і можливо модифікована під час виконання лексема (блок 24)

-  Звільняються всі використовувані ресурси. Цю функцію реалізує метод платформи .NetFramework    Dispose();

 


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

 

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

В задачу синтаксичного аналізатора входить:

1.      Знайти та виділити основні синтаксичні конструкції мови в тексті програми.

2.      Встановити тип та правильність кожної синтаксичної конструкції.

3.      Представити синтаксичні конструкції у вигляді, зручному для подальшої генерації тексту результуючої програми.

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

 

 

 


3.4.1. Розробка граф-схеми алгоритму

Для кращого розуміння дій, що виконуються транслятором наведемо граф схему алгоритму синтаксичного аналізу:


Таблиця пріоритетів для даного синтаксичного аналізатора:

 

Детальний опис блоків граф – схеми алгоритму синтаксичного та семантичного аналізу знаходиться в пункті 3.4.3
3.4.2. Опис програмної реалізації синтаксичного та семантичного аналізатора

 

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

Функція BuildTree() використовує таблицю лексем та таблицю пріорітетів а на виході отримуємо дерево граматичного розбору та сформовані аналізатором синтаксичні та семантичні помилки. Причому вершина Code_Block містить в своєму описі згенерований код асемблерної програми для кодового блоку.

Функція BuildTree() працює за таким алгоритмом:

               перевіряємо, чи перші три лексеми – <Program><Ident><Semicolon>, якщо ні, то виводимо повідомлення про помилку;(блок 2)

               перевіряємо, чи наступна лексема – «Var», якщо ні, то формується помилка про неправильну організацію програми, очікувалось «Var»;

(блок 3) якщо наступна лексема «Var», то перевіряємо опис даних, який закінчується лексемою ‘;’. В блоці опису даних перевіряємо, чи правильно розставлені лексеми – ‘,’; чи правильно відбувається присвоєння. Якщо виявлені якісь помилки, то формуємо відповідні повідомлення; Інакше отримуємо таблицю ідентифікаторів.

               Переходимо до аналізу блоку коду. Ініціалізуємо три стеки:

In – містить всі вхідні лексеми.

Out – містить спочатку <EOF>

Index – стек для збереження кількості перенесених елементів після відкриваючого пріоритету.(блок 4)

Перевіряємо пріоритет Out.Top() i In.Top(): (блок 5)

0)  Опрацьовуємо помилку (блок 7, 8)

1)  В стек індексів заносимо 1, переносимо з In в Out (блок 9, 10)

2)  Збільшуємо значення в вершиині стеку індексів, переносимо з In в Out  (блок 11, 12)

3)  Згортаємо елементи які є в стеку Out (кількість знаходиться в вершині Index) З стеку індексів вилучаємо останній елемент. Згорнутий результат заштовхуємо в In (блок 13, 14)

4)  Згортаємо присвоєння за допомогою функції ConvertToPostfix(), яка одночасно і генерує код для виразу.  (блок 15, 16)

5)  Перевіряємо правильність циклу For, якщо немає помилок – генеруємо код для початку циклу, інакше повертаємо помилку.

(блок 17, 18)

6) Згортаємо цикл For з наступним після нього блоком. (блок 19, 20)

7) Перевіряємо правильність запису оператора вводу чи виводу, якщо все правильно, то генеруємо код для виклику функції crt_printf або crt_scanf (блок 21, 22)

8) Перевіряємо правильність оператора If, якщо немає помилок – генеруємо код для перевірки умови , інакше повертаємо помилку.

(блок  23, 24)

9) Згортаємо оператор If з наступним після нього блоком.

      Якщо не було знайдено жодної помилки, функція повертає вершину дерева граматичного розбору,  в інакшому випадку повідомлення про помилки. (блок 25, 26)
3.5. Розробка генератора коду

 

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

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

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

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

 


3.5.1. Розробка граф-схеми алгоритму

 

Для кращого розуміння дій, що виконуються транслятором наведемо граф схему алгоритму генератора коду:

 

3.5.2. Опис програмної реалізації генератора коду

 

Для генератора коду використовується функцію Run().

Функція Run () виконує генерацію коду у вихідний асемблерний файл.

Функція Run () працює за таким алгоритмом:

      друкує макроси в асемблерний файл;(блок 2)

      друкує заголовок асемблерної програми в асемблерний файл; (блок 3)

      друкує блок даних в асемблерний файл відповідно до змінних і констант;

(блок 4)

      друкує сегмент коду в асемблерний файл; (блок 5)

      друкує кінець програми в асемблерний файл; (блок 6)

4. Опис інтерфейсу та інструкції користувача

 

4.1. Опис інтерфейсу

 

Після запуску програми на екрані з`являється головне вікно програми (рис. 4.1).

 

 

Рис. 4.1. Головне вікно програми.

 

Головне вікно програми містить головне меню (розміщене у верхній частині головного вікна), вікно вводу тексту (розміщене у центральній частині головного вікна), вікно виводу повідомлень (розміщене у нижній частині головного вікна).

 

 

 


4.1.1. Головне меню та панель інструментів.

 

Головне меню складається з таких елементів: File, Edit, Сompile, Output (рис. 4.2).

 

 

Рис. 4.2. Головне меню.

 

Меню File містить стандартні команди для роботи з файлом проекту, а також команду виходу з програми (Exit). За допомогою цих команд можна створити новий проект (New), відкрити (Open) чи зберегти (Save, Save As) файл проекту (рис. 4.3).

 

 

Рис. 4.3. Меню File.

 

Меню Compile містить команду запуску програми (Run) (Рис. 4.4).

 

Рис. 4.4. Меню Compile.


За допомогою команд меню Edit можна вирізати (Cut), копіювати (Copy) виділену частину тексту, вставляти текст із буфера (Paste) , Відміняти одну дію (Undo), повертати одну дію (Redo) та видаляти весь текст (Clear) (рис. 4.5).

 

 

Рис. 4.5. Меню Edit.

 

Панель інструментів служить для розташування кнопок інструментів. На ній містяться кнопки деяких зазначених команд.

 


4.2. Інструкція програміста

 

4.2.1. Алфавіт мови

 

Мови програмування, як і розмовні мають власний алфавіт – набір допустимих символів. Алфавіт даної мови складається з наступних символів:

      букви латинського алфавіту, як малі, так і великі (тобто A - Z, a - z);

      цифри (0 - 9);

      спеціальні символи: ( ) , ; " - + = ! & | * /

Зауваження: символи, що не входять в алфавіт даної мови все-таки можуть зустрічатися в програмі, але тільки в коментарях і рядках.

Слова поділяються на ключові слова і ідентифікатори. Ідентифікатори – це назва (ім’я), яку користувач надає об’єктам, наприклад, змінним та ін.. Зарезервовані ідентифікатори називаються ключовими словами. Вони використовуються для написання команд. Змінити призначення ключового слова в програмі не можна. Основні ключові слова даної мови:

Program, Var, Start, Finish, Integer, For, DownTo, Do, If, Input, Output, Mul, Div, Mod, Le, Ge.

4.2.2. Коментарі

Коментар – це фрагмент тексту програми, який слугує для пояснення призначення програми чи окремих команд і не впливає на виконання команд. Його записують так: /* текст коментарю */.

Зауваження: у даній мові використовуються тільки блокові коментарі.

 

4.2.3. Тип даних

1. Цілий тип.

Для подання цілих чисел у даній мові існує тип даних Integer. Це знаковий тип, тобто числа типу Integer можуть приймати як від’ємні, так і додатні значення, а також можуть рівнятися нулю. Діапазон можливих значень цілих чисел: від -32768 до 32767.

Для цілих чисел визначені стандартні арифметичні операції додавання (+), віднімання (-), множення (Mul), ділення (Div), остача від ділення (Mod). Результатом цих операцій також є ціле число.

Для цілих чисел також визначені операції порівняння: рівне (==), нерівне (!=), більше - рівне (Ge), менше – рівне (Le).

Зауваження: у даній мові використовуються тільки цілі числа.

 

3. Символьний тип.

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

Зауваження: символьний тип використовується тільки в операторі виводу.

 

 

4.2.4. Розділи, використовувані при написанні програм

Загальна структура програми має вигляд:

 

Program ім’я;

Var

тіло розділу опису даних;

Start

тіло розділу коду;

Finish

 

Program – заголовок програми

Var – початок розділу опису даних

Start – початок тіла розділу коду

Finish – кінець тіла розділу коду.

 

Розділ опису даних (змінних).

Дані, значення яких необхідно ввести з клавіатури або які під час виконання програми можуть набувати різних значень, називаються змінними. Їх оголошують так:

 

< тип змінних 1 > < список змінних 1 >;

..........

< тип змінних N > < список змінних N >;

 

Елементи списків записуються через кому. Наприклад : Integer _A,_C;

 

Розділ коду.

Розділ коду, який повинен бути у кожній програмі, починається словом Start, а закінчується – End.

У тілі розділу коду містяться команди, які один від одного відокремлюються символом “;”(крапка з комою).

Информация о работе Розробка системних програмних модулів та компонент систем програмування