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

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
КН
Кафедра:
Кафедра ЕОМ

Інформація про роботу

Рік:
2024
Тип роботи:
Інші
Предмет:
Системне програмування

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти і науки, молоді та спорту України Національний університет "Львівська Політехніка" Кафедра ЕОМ / Пояснювальна записка до курсової роботи з предмету: "Системне програмування" на тему:"Розробка системних програмних модулів та компонент систем програмування. Розробка транслятора з вхідної мови програмування" Анотація Завданням, яке виконується в даному курсовому проекті є розробка транслятора вхідної мови програмування k10. Транслятор розроблений за допомогою мови програмування С++ та C#, на основі програмного продукту “Visual Studio 2012”, в якому використовується стандартний набір користувацького інтерфейсу на основі компонентів пакету “.Net Framework 4.0”, який значно спрощує процес тестування, відлагодження та редагування програми. У пояснювальній записці подано опис кожного етапу написання транслятора, структурні схеми, які дають змогу краще зрозуміти призначення кожного етапу, та взаємозв’язок між ними. Для перевірки на коректність комплексу виконаних робіт наводяться тестові програми, які демонструють основні можливості даної мови програмування. Зміст Завдання --------------------------------------------------------------------------------------4 Вступ ------------------------------------------------------------------------------------------5 1.Огляд методів та способів проектування трансляторів --------------------------6 2. Формальний опис вхідної мови програмування ----------------------------------11 2.1. Деталізований опис вхідної мови на термінах розширеної нотації мови Опису Бекуса-Наура---------------------------------------------------------------------11 2.2. Опис термінальних символів та ключових слів ------------------------------12 3. Розробка транслятора вхідної мови---------------------------------------------------14 3.1. Вибір технології програмування--------------------------------------------------14 3.2. Проектування таблиць транслятора ---------------------------------------------15 3.3. Розробка лексичного аналізатора ------------------------------------------------16 3.3.1.Розробка граф-схеми аналізатора---------------------------------------------16 3.3.2.Опис програми реалізації лексичного аналізатора -----------------------17 3.3.3.Опис програми реалізації лексичного аналізатора -----------------------18 3.4.Розробка синтаксичного та семантичного аналізатора-----------------------19 3.4.1 Розробка граф-схеми алгоритму-----------------------------------------------19 3.4.2. Опис п-ми реалізації синтаксичного та семантичного аналізатора----21 3.5.Розробка генератору коду-------------------------------------------------------------21 3.5.1. Розробка граф-схеми генератора------------------------------------------------21 3.5.2. Опис програми реалізації генератора коду ----------------------------------22 4.Опис інтерфейсу та інструкції для користувача-------------------------------------24 5.Відлагодження та тестування програми-----------------------------------------------25 5.1. Виявлення лексичних помилок----------------------------------------------------25 5.2. Виявлення синтаксичних помилок------------------------------------------------26 5.3. Виявлення семантичних помилок-------------------------------------------------26 5.4. Загальна перевірка роботи коректності транслятора--------------------------26 Висновок---------------------------------------------------------------------------------------27 Список літератури----------------------------------------------------------------------------28 Додаток А--------------------------------------------------------------------------------------29 Додаток Б---------------------------------------------------------------------------------------29 Додаток B--------------------------------------------------------------------------------------30 Завдання на курсову роботу Цільова мова транслятора асемблер (iх86). Для отримання виконавчого файлу на виході розробленого транслятора скористатися програмами tasm і tlink. Мова розробки транслятора: ANSI C або C++. Реалізувати оболонку або інтерфейс з командного рядка. На вхід розробленого транслятора має подаватися текстовий файл, написаний на заданій мові програмування. На виході розробленого транслятора мають створюватись чотири файли: файл з повідомленнями про помилки (або про їх відсутність); файл на мові асемблера; об’єктний файл; виконавчий файл. Назва вхідної мови програмування утворюється від першої букви у прізвищі студента та останніх двох цифр номера його варіанту. Саме таке розширення повинні мати текстові файли, написані на цій мові програмування. Для мого варіанту це буде .k10 Деталізований опис вхідної мови тип даних: знакове ціле (integer16) регістр ключових слів: Low перший символ low; регістр ідентифікаторів: Low-Up6 перший символ low; арифметичні операції: add;sub;*;/;% операції порівняння =; <>; >; < логічні операції: not; and; or; оператор присвоєння: ::= блок тіла програми: program start var…; finish коментар: !!... оператор циклу: for-to-do(ПАСКАЛЬ) оператори вводу/виводу: scan/print Вступ Незважаючи на більш ніж піввікову історію обчислювальної техніки, формально роком народження теорії трансляторів можна вважати 1957, коли з’явився перший транслятор мови Фортан, створений Бекасом. До цього часу створення трансляторів було досить ‘творчим’ процесом. Лише поява теорії формальних мов і строгих математичних моделей дозволило перейти від ‘творчості’ до ‘науки’. Саме завдяки цьому стала можливим поява сотень нових мов програмування. Більше того, формальна теорія трансляторів дала новий стимул розвитку математичної лінгвістики і методам штучного інтелекту, пов’язаних із природними і штучними мовами. Основу теорії трансляторів становить теорія формальних мов – досить складними, насиченими термінами, визначеннями, математичними моделями і іншими формалізмами розділ математики. Отже, транслятори є невід’ємною частиною будь-якої обчислювальної системи – без них нам довелося б усе програмувати на автокоді або навіть у машинних командах. Тому транслятори стали важливою практичною областю наукових досліджень, пов’язаних з обчислювальними машинами. Огляд методів та способів проектування трансляторів Транслятор - обслуговуюча програма, що перетворює вхідну програму, надану вхідною мовою програмування, у робочу програму, представлену об'єктною мовою. Наведене визначення відноситься до всіх різновидів транслюють програм. Однак у кожної з таких програм можуть бути свої особливості щодо організації процесу трансляції. В даний час транслятори поділяються на три основні групи: асемблери, компілятори та інтерпретатори. Асемблер - системна обслуговуюча програма, що перетворює символічні конструкції в команди машинної мови. Специфічною рисою асемблерів є те, що вони здійснюють дослівну трансляцію однієї символічної команди в одну машинну. Таким чином, мова асемблера (ще називається автокодом) призначена для полегшення сприйняття системи команд комп'ютера і прискорення програмування в цій системі команд. Компілятор - це обслуговуюча програма, що виконує трансляцію на машинну мову програми, записаною вхідною мовою програмування. Також як і асемблер, компілятор забезпечує перетворення програми з однієї мови на іншу (найчастіше, у мову конкретного комп'ютера). Разом з тим, команди вхідної мови значно відрізняються по організації і потужності від команд машинної мови. Існують мови, у яких одна команда вхідного мови транслюється в 7-10 машинних команд. Однак є і такі мови, у яких кожній команді може відповідати 100 і більше машинних команд (наприклад, Пролог). Крім того, у вхідних мовах досить часто використовується строга типізація даних, здійснювана через їхній попередній опис. Інтерпретатор - програма або пристрій, що здійснює по-операторну трансляцію і виконання вхідної програми. На відміну від компілятора, інтерпретатор не породжує на виході програму на машинній мові. Розпізнавши команду вхідної мови, він одразу виконує її. Як у компіляторах, так і в інтерпретаторах використовуються однакові методи аналізу вхідного тексту програми. Але інтерпретатор дозволяє почати обробку даних після написання навіть однієї команди. Це робить процес розробки і налагодження програм більш гнучким. Крім того, відсутність вихідного машинного коду дозволяє не "засмічувати" зовнішні пристрої додатковими файлами, а сам інтерпретатор можна досить легко адаптувати до будь-яких машинних архітектур, розробивши його тільки один раз на широко розповсюдженній мові програмування. Емулятор - програма або програмно-технічний засіб, що забезпечує можливість без перепрограмування виконувати на даній ЕОМ програму, що використовує коди чи способи виконання операцій, відмінні від даної ЕОМ. Емулятор схожий на інтерпретатор тим, що безпосередньо виконує програму, написану на деякій мові. Однак, частіше за все, це машинна мова або проміжний код. І той і інший представляють команди в двійковому коді, які можуть виконуватися одразу після розпізнавання коду операцій. На відміну від текстових програм, не потрібно розпізнавати структуру програми, виділяти операнди. Кодувач - програма або програмний пристрій, що переводить програми, написані машинною мовою однієї ЕОМ до програм на машинній мові іншої ЕОМ. Якщо емулятор є менш інтелектуальним аналогом інтерпретатора, то кодувач виступає в тій же якості по відношенню до компілятора. Точно так вихідний (і зазвичай двійковий) машинний код або проміжне уявлення перетворюються в інший аналогічний код по одній команді і без будь-якого загального аналізу структури вихідної програми. Кодувачі бувають корисні при переносі програм з одних комп’ютерних архітектур на інші. Вони можуть також використовуватися для відновлення тексту програми на мові високого рівня з наявного бінарного коду. Макропроцесори - програма, що забезпечує заміну однієї послідовності символів іншою. Це різновид компілятора. Він здійснює генерацію вхідного тексту шляхом обробки спеціальних вставок, які розташовуються у вихідному тексті. Ці вставки оформлюються спеціальним способом і належать конструкції мови, яка називається макромовою. Макропроцесори підвищують ефективність програмування без зміни синтаксису і семантики мови. Синтаксис - сукупність правил деякої мови, що визначають формування її елементів. Інакше кажучи, це сукупність правил семантично-значущих послідовностей символів в даній мові. Синтаксис задається за допомогою правил, які описують поняття деякої мови. Прикладами понять є: змінна, вираз, оператор, процедура. Семантика - правила та умови, що визначають співвідношення між елементами мови та їх смисловими значеннями, а також інтерпретацію змістовного значення синтаксичних конструкцій мови. Об'єкти мови програмування не тільки розміщуються в тексті у відповідності з певною ієрархією, а й додатково пов'язані між собою. Всі мови програмування мають ряд загальних характеристик і параметрів. Ця одноманітність і визначає схожі для всіх мов принципи організації трансляторів. Мови програмування призначені для полегшення програмування. Тому їхні оператори та структури даних більш потужні, ніж в машинних мовах. Для підвищення наочності програм замість числових кодів використовуються символічні або графічні представлення конструкцій мови, більш зручні для їх сприйняття людиною. Для будь-якої мови визначається: набір символів, які можна використовувати для запису правильних програм (алфавіт), основні елементи. Набір правильних програм (синтаксис). "Сенс" кожної правильної програми (семантика). Незалежно від специфіки мови будь-який транслятор можна вважати функціональним перетворювачем F, що забезпечує однозначне відображення X в Y, де X - програма мовою оригіналу, Y - програма на вихідній мові. З огляду на схожість компілятора й інтерпретатора, розглянемо фази, що існують в компіляторі. У них виділяються: Фаза лексичного аналізу. Фаза синтаксичного аналізу, що складається з: а) розпізнавання синтаксичної структури; б) семантичного аналізу, в процесі якого здійснюється робота з таблицями, породження проміжного семантичного представлення або об'єктної моделі мови. Фаза генерації коду, що здійснює: а) семантичний аналіз компонентів проміжного представлення або об'єктної моделі мови; б) переклад проміжного представлення або об'єктної моделі в об'єктний код. Поряд з основними фазами процесу трансляції можливі також додаткові фази: Фаза дослідження та оптимізації проміжного представлення, що складається з: а) аналізу коректності проміжного представлення; б)оптимізації проміжного представлення. Фаза оптимізації об’єктного коду. Структура компілятора, яка враховує існуючі в ньому фази, представлена на рис. 1.1: / Рис. 1.1 - Структура компілятора Він складається з лексичного аналізатора, синтаксичного аналізатора, генератора коду, аналізатора помилок. В інтерпретаторі замість генератора коду використовується емулятор, до якого, крім елементів проміжного представлення, передаються вихідні дані. Формальний опис вхідної мови програмування Деталізований опис вхідної мови в термінах розширеної нотації Бекуса-Наура Однією з перших задач, що виникають при побудові компілятора, є визначення вхідної мови програмування. Для цього використовують різні способи формального опису, серед яких я застосував розширену нотацію Бекуса-Наура. <програма> ::= program <назва> start var {<змінні> integer16}; <блок коду> finish  < назва> ::= <буква> {< символ>}  <змінні> ::= <змінна>|(<змінна> {, <змінна>})  <змінна> ::= <м_буква><в_буква><в_буква><в_буква><в_буква><в_буква>><в_буква>  <м_буква> ::= a|b|c|d|e|f|g|h|i|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|I|J|K|L|N|M|O|P|Q|R|S|T|U|V|W|X|Y|Z  <цифра> ::= 0|1|2|3|4|5|6|7|8|9  <символ> ::= +|-|*|/|\|`|”|.|,|;|:|!|(|)|#|?|<цифра>|<ціле>  <буква> ::=<в_буква>|<м_буква>  <ціле> ::= [+|-]<цифра>{<цифра>}  <operator> ::= <equation >| <int> | <out >| <cicle>|<operator_block>  <equation> ::= <ident><is><expression>  <expression> ::= [(] <operand> [)] [{ [)]<operation>[(]<operand> [)] }]  <operand> ::= <ident>|<const> |<ident>  <operation> ::= <arifmetic>|<logic>  <arifmetic> ::=<arifmetic>add<harifmetic>|<arifmetic>sub<harifmetic>|<harifmetic>  <harifmetic> ::=<harifmetic>*<farifmetic>|<harifmetic>/<farifmetic>|< harifmetic>%<farifmetic>| <farifmetic>  <farifmetic> ::=<operand>|(<arifmetic>)  <logic> ::=<egual>[||<egual>]|<logic_b>  logic_b> ::=<logic_b>and<logic_h>|<logic_h>  <logic_h> ::= not< logic_h>| <logic_bh>  <logic_bh> ::=(<logic>)|<egual>  <egual> ::= (< operand ><eg_op><operand>)  <eg_op> ::= =, <>,>=,<=  <cycle> ::= for <змінна> to <цифра>|<змінна> do < operator_block >  <in> ::= scan (<ident>);  <out> ::= print (<ident>);  <operator_block> ::= start < operator > | [{< operator>}] finish  Опис термінальних символів та ключових слів program – початок тексту програми, наступним описується імя програми; var - блок опису змінних і початок блоку start – початок тіла програми(циклу) finish – кінець тіла програми (циклу); print– оператор виводу (змінних і рядкових констант) scan – оператор вводу змінних; ::= оператор присвоєння; for -to -do –циклу add – операція додавання sub – операція віднімання * – операція множення / – операція ділення % – операція знаходження залишку від ділення; = – операція перевірки на рівність; <> – перевірка на нерівність; <= – перевірка чи менше-рівне; >= – перевірка чи більше/рівно; not – операція логічного заперечення; and– кон’юнкція; or – диз’юнкція; integer16–тип даних; ,– розділювач між деклараціями змінних; ; – ознака кінця оператора; (– відкриваюча дужка; ) – закриваюча дужка; Як термінальні символи використовуються також усі арабські цифри (0–9), латинські букви (a-z, A-Z), символи табуляції, символ переходу на нову стрічку, пробіл. 3. Розробка транслятора вхідної мови Створення трансляторів є одною з невід’ємних частин системного програмного забезпечення. Транслятор розроблений в даній курсовій роботі працює за схемою поданою в додатку Б. Він включає в себе три головні фази: лексичний аналіз синтаксичний аналіз генерація коду Також тут реалізоване збереження проміжних результатів роботи: списку лексем, ідентифікаторів, міток, проміжного представлення мови. При виявлені помилок вони також додатково зберігаються в файл. 3.1 Вибір технології програмування Для ефективної роботи створюваної програми важливу роль відіграє попереднє складення алгоритму роботи програми, алгоритму написання програми і вибір технології програмування, а саме використання яких структур, типів даних чи алгоритмів дасть нам виграш у кількості коду, його якості і ефективності чи в розумінні. Тому робимо аналіз нашої програми. Для роботи з виразами (перетворення їх в постфіксну форму) нам знадобиться структура стек. Тому на основі знань, здобутих в курсі основ програмування реалізовуємо стек, а також необхідні функції для роботи з ним: Init (ініціалізація стеку), Push (закинути значення до стеку), Pop (витягнути значення зі стеку), IsEmpty (перевірка на стек порожній), IsFull (перевірка чи стек повний). Для полегшення роботи з класами лексем використовуємо тип enum для перерахування всіх можливих типів і полегшення наступного опрацювання лексем. Для полегшення обробки лексем також використовуємо структуру Lexem для зберігання номера рядка та номера позиції лексеми в рядку, імені лексеми, вказівника на номер ідентифікатора в таблиці ідентифікаторів (якщо лексема є ідентифікатором), та класу лексеми. Для полегшення обробки ідентифікаторів використовуємо структуру Ident для зберігання імені ідентифікатора, його типу та значення. Також використовуємо структуру L для зберігання робочих даних програми – таблиці лексем, таблиці ідентифікаторів, таблиці помилок, буфера для виразу в постфіксній формі, а також назв вхідного файлу, файлу з таблицею лексем, файлу з помилками та вихідного файлу. Крім того, доцільним є розбиття вихідного коду на процедури, оскільки великі частини коду часто повторюються. Для цього, наприклад, створені асемблерні процедури INPUT (процедура вводу), OUTPUT (процедура виводу), MOD_ (процедура остачі від ділення), AND_ (процедура логічної операції «і»), OR_ (процедура логічної операції «або»), NOT_ (процедура логічної операції «не»), EQ_ (процедура операції порівняння «дорівнює»), GE_ (процедура операції порівняння «більше»), LE_ (процедура операції порівняння «менше»). Використання даних структур повинно спростити написання коду програми і полегшити її розуміння і читабельність, тому, на мою думку, технологія програмування вибрана вірно. 3.2 Проектування таблиць транслятора та вибір структур даних Використання таблиць значно полегшує створення трансляторів, тому у даному випадку використовуються кілька таблиць: typedef struct L { Lexema LexArray[1000]; int length; Identifier IdTable[50]; int idnum; int PFExpr[200]; }Data; 1) Таблиця лексем з елементами, які мають таку структуру: typedef struct Lexem { char name[50]; int value; LexemType type; int line; }Lexema; 2) Таблиця ідентифікаторів з елементами типу Identificator та додатковою цілочисельною змінною цілочисельного типу в якій зберігається кількість визначених змінних. Структура елементів така: typedef struct Ident { char name[50]; int value; }Identifier; 3.3 Розробка лексичного аналізатора Лексичний аналізатор є першою фазою компілятора. Основна задача лексичного аналізу – розбити вихідний текст, що складається з послідовності одиночних символів, на послідовність слів, або лексем, тобто виділити ці слова з безперервної послідовності символів для передачі в синтаксичний аналізатор. Всі символи вхідної послідовності розділяються на символи, що належать яким-небудь лексемам, і символи, що розділяють лексеми. 3.3.1 Розробка граф-схеми алгоритму Алгоритм лексичного аналізу базується на використанні засобів регулярних виразів. При цьому за допомогою регулярних виразів задаються правила виділення лексем, ідентифікаторів, міток з подальшим утворенням таблиці лексем і ідентифікаторів. Процес задання правил виділення лексем є достатньо простим і надзвичайно гнучким. Розбір виконується взалежності від правила виділення лексеми, заданого регулярним виразом, при чому ними можна виділити не лише базові одиниці мови, але й коментарі, пробільні символи і навіть лексичні помилки. / Рис. 1. Алгоритм лексичного аналізу. 3.3.2 Опис програми реалізації лексичного аналізатора Для виділення лексем використовуються правила задані регулярними виразами. Вхідна програма проглядається послідовно з початку. Початок тексту аналізується на відповідність певному регулярному виразові (блоки 5, 6, 7, 8, 9). При співпадінні виділена лексема записується при необхідності в таблицю лексем, змінних, стрічок чи генерується помилка і видаляється з початку тексту (блоки 10-18). Так повторюється доки вхідний текст не стане порожнім (блок 3). При виділенні лексеми вона розпізнається та записується у таблицю лексем за допомогою відповідного номера лексеми, що є унікальним для кожної лексеми із усього можливого їх набору. Це дає можливість наступним фазам компiляції звертатись до лексеми не як до послідовності символів, а як до унікального номера лексеми, що значно спрощує роботу синтаксичного аналізатора: легко перевіряти належність лексеми до відповідної синтаксичної конструкції та є можливість легкого перегляду програми, як вгору, так і вниз, від текучої позиції аналізу. Також в таблиці лексем ведуться записи, щодо місця розташування відповідної лексеми у вхідному тексті (для локалізації місця помилки) та інша додаткова інформація. При лексичному аналізі виявляються i відзначаються лексичні помилки (наприклад, недопустимі символи i неправильні iдентифiкатори). Лексична фаза відкидає також i коментарі, пробільні символи оскільки вони не мають ніякого впливу на виконання програми, отже ж й на синтаксичний розбір та генерацію коду. 3.3.3 Таблиця пріоритетів операцій Пріоритет виконання математичних та логічних операцій, які підтримує мова, реалізована в даній курсовій роботі, такий же, як і в мові програмування “C”. 1 ( ) Дужки  2 - унарний мінус  3 ^ Степінь  4 * / множення, ділення  5 + - Додавання, віднімання  6 <> Більше, менше  7 !=== дорівнює, не дорівнює  8 || логічне “або”  9 && логічне “І”  10 = Присвоєння   3.4 Розробка синтаксичного та семантичного аналізатора Першим етапом синтаксичного аналізу є синтаксичний розбір. На етапі його виконання підтверджується то, що вхідний ланцюжок лексем є програмою, а окремі лексеми складають синтаксично правильні програмні об'єкти. Розбір призначений для перевірки того, чи ланцюжок відповідає певному правилу з сукупності правил визначеної граматикою. Синтаксичний розбір виконується методом рекурсивного спуску. Якщо на будь-якому рівні ланцюжок не відповідає ніякому правилу,то ми дістанемо помилку. Основним завданням семантичного аналізатора є перевірка типів, ініціалізації змінних. Сама програма перевірки типів базується на інформації про синтаксичні конструкції мови, представлення типів і правилах присвоєння типів конструкціям мови. 3.4.1 Розробка граф-схеми алгоритму Алгоритм синтаксичного аналізу використовує низхідний метод розбору. Для кожної конструкції мови розроблена певна процедура, яка і робить перевірку чи відповідає ланцюжок лексем певному правилу граматики. Також дані процедури формують проміжне представлення мовних конструкції для генератора коду. Спочатку перевіряється заголовок програми і розділ оголошення змінних, далі йде перевірка головного блоку і вкладених блоків. При неможливості співставити ланцюжок лексем певному правилу граматики генерується помилка.  Рис.2. Алгоритм синтаксичного аналізу. 3.4.2 Опис програми реалізації синтаксичного та семантичного аналізатора Для аналізу синтаксичний аналізатор отримує на вхід послідовність лексем сформовану лексичним аналізатором. Спочатку перевіряється заголовок програми (блок 2): початок головного блоку, розділ оголошення змінних, після цього відбувається перевірка коректності команд розміщених в головному блоці і вкладених блоках. Для кожної команди передбачена окрема процедура. Команди розпізнаються по черговій лексемі, відбувається зчитування ланцюжка лексем до крапки з комою. Прочитаний ланцюжок (блоки 3 - 18) передається на перевірку певній процедурі аналізу (блоки 7, 10, 14), яка проводить аналіз і при успішному завершенні формує проміжне представлення команди для генератора коду(блоки 15, 16, 17). Проміжним представленням програми є списки лексем які представляють конкретні вирази, оператори. Вирази представлені зворотнім польським записом. При знаходженні помилки в список помилок додається відповідний запис з інформацією про тип помилки і місце її локалізації в коді програми (блоки 11, 12, 13, 16). Список помилок є глобальним і доступним в будь-якому місці програми. 3.5 Розробка генератора коду Генерація коду – це перетворення вхідної програми на деякій мові в еквівалентну програму на мові асемблер або у машинні коди. Проте, зважаючи на неможливість здійснити оцінку смислу вхідної програми загалом та існуючі обмеження мов програмування на етапі генерації коду ми ніколи не отримаємо на 100% еквівалентну програму мовою асемблер. Генерація і оптимізація коду є завершальним етапом роботи компілятора чи транслятора. Вона виконується після виконання операцій лексичного, синтаксичного і семантичного аналізу, ідентифікації імен змінних і функцій, розподілу адресного простору для функцій і змінних. 3.5.1 Розробка граф-схеми алгоритму Генерація коду є поетапним процесом, який відбувається на основі закінчених мовних конструкцій вхідної програми. Генератор вибирає закінчену синтаксичну конструкцію з тексту вхідної програми породжує для неї фрагмент результуючого коду і розміщує його в тексті результуючої програми. Далі береться наступна конструкція. Так відбуваться доти, доки не буде розібрана вся програма.  Рис. 3. Алгоритм генератора коду. 3.5.2 Опис програми реалізації генератора коду Генерація коду відбувається поетапно. Генератор коду аналізує проміжне представлення (списки лексем) сформовані синтаксичним аналізом і генерує для них відповідний асемблерний код. Спочатку генератор коду аналізує список ідентифікаторів і формує їхнє оголошення в сегменті даних (блоки 4, 6, 8). Далі відбувається подібна генерація машинного коду для списку стрічок (блоки 3, 5, 7). Після цього генератор формує заголовок машинного коду (блок 9). Далі зчитуються списки з проміжним представленням команд і формуються еквівалентні машинні інструкції (блоки 11, 13, 15). Далі в готовий асемблерний текст додаються сформовані машинні команди і код необхідних процедур (блоки 10, 12). Результати зберігаються у вихідний файл (блок 14). Вихідна програма на машинній мові організована у вигляді готових процедур, кожна з яких відповідає за ввід/вивід результатів роботи, конкретну обчислювальну арифметичну чи логічну операцію, вивід повідомлення про помилки. Для обчислень використовується програмний стек, який представлений ділянкою пам’яті і зміщенням (вершина стеку). Даний метод має наступні переваги: розмір стеку достатньо великий щоб уникнути помилок переповнення, як у випадку зі стеком математичного співпроцесора; проста реалізація обчислень за допомогою готових процедур; можливість виявлення помилок на етапі виконання: ділення на нуль; помилка ініціалізації змінної; помилка переповнення; помилка введення. 4. Опис інтерфейсу та інструкції користувачу Програма транслятор має інтерфейс показаний на Рис. 4. що складається з Меню яке включає в себе три пункти: open,save,close . А також сама програма має ше три кнопки: upDate – оновлює вкладки (Lexem, Errors, output) новою інформацією compile – запускає компіляцію програми Run – запускає кінцеву exe програму / Рис. 4. Середовище розробки мови d10. Поле Lexem – показує таблицю лексем (рис. 5) Поле Errors – показує помилки програми (рис. 6) Поле output – показує кінцеву .asm програму (рис. 7) / Рис. 5 Поле таблиці лексем / Рис. 6 Поле інформації про помилки / Рис. 7 Поле відображення лістингу кінцевої .asm програми 5.Відлагодження та тестування програми Відлагодження та тестування транслятора проводиться з використанням кількох вхідних програм з навмисне введеними помилками та з коректною програмою для загальної перевірки роботи транслятора. 5.1. Виявлення лексичних помилок. Виявлення лексичних помилок відбувається на стадії лексичного аналізу. При розборі вхідної програми на окремі лексеми лексичний аналізатор перевіряє чи відповідає отримана лексема лексиці заданої мови програмування. У випадку неспівпадіння лексемі присвоюеться тип “неопізнаної лексеми”. Повідомлення про такі помилки можна побачити лише після виконання процедури перевірки таблиці лексем. Приклад виявлення: (Додаток А). 5.2. Виявлення синтаксичних помилок. Виявлення синтаксичних помилок відбувається на стадії перевірки програми на коректність окремо від синтаксичного аналізу. При цьому перевіряється окремо кожне твердження яке може бути або виразом, або оператором (циклу, вводу, виводу), або оголошенням, та перевіряється структура програми в цілому. Приклад виявлення: (Додаток А). 5.3. Виявлення семантичних помилок. Суттю виявлення семантичних помилок є перевірка числових констант на відповідність типу integer16 тобто знаковому цілому числу з відповідним діапазоном значень. Приклад виявлення: (Додаток Б). 5.4.Загальна перевірка коректності роботи транслятора. Загальна перевірка полягає в транслюванні завідомо коректної вхідної програми з використаням всіх можливостей мови в асемблерний код та перевірці на правильність виконання програми попередньо зкомпільованої та злінкованої за допомогою tasm та tlink. Приклад виявлення: (Додаток Б). Висновки В процесі виконання курсової роботи було складено формальний опис мови програмування k10, в термінах розширеної нотації Бекуса-Наура, виділено усі термінальні символи та ключові слова. Створено транслятор мови програмування k10, а саме: розроблено лексичний аналізатор, який виявляє лексичні помилки , та на виході дає таблицю лексем таблицю ідентифікаторів, з якими потім працює синтаксично-семантичний аналізатор . Розроблено синтаксичний та семантичний аналізатор, який виявляє синтаксичні та семантичні помилки на етапі аналізу та виконання, та на виході будує проміжне представлення, яке потім використовує генератор коду . Розроблено генератор коду, який генерує код, записаної нами програми на заданій мові програмування , у програму на мові асемблера . На виході ми отримуємо файл на мові асемблера , з якого ми отримаємо виконавчий файл, за допомогою TASM та TLINK. Проведене тестування транслятора на тестових програмах за наступними пунктами: На виявлення лексичних помилок. На виявлення синтаксичних помилок. Загальна перевірка роботи компілятора. Тестування виявило деякі помилки в роботі транслятора , які були успішно усунуті. В результаті виконання даної курсової роботи було успішно засвоєно методи розробки та реалізації компонент системного програмування. Список літератури Хантер Р. Проектирование и конструирование компиляторов. – М.: Финансы и статистика, 1984. – 232 с. Ахо А., Ульман Дж. Теория синтаксического анализа, перевода и компиляции. – М.: Мир, 1978. – т.1, 612 с. Грис Д. Конструирование компиляторов для цифровых вычислительных машин. - М.: Мир. 1975. - 554 с. Шильдт Г. С#. – Санкт-Петербург: BXV, 2007. – 688 с. http://ru.wikipedia.org/wiki/Регулярные_выражения http://msdn.microsoft.com/en-us/library/az24scfc.aspx ДОДАТОК А. Приклад програми із лексичними та синтаксичними помилками та текст файлу з повідомленням про помилки. program name; start var tMP,pES integer16; tMP::=1; pES::=5; sUMA::=0; for tMP to pES do start sUMA::=sUMA add tMP; finish print(sUMA); Файл Errors.txt: Error output file. Next errors found: line 3: 'End' expected! line 12: 'End' expected! line 5: Unknown identifier!(sUMA) line 9: Unknown identifier!(sUMA) line 9: Unknown identifier!(sUMA) line 11: Unknown identifier!(sUMA) ДОДАТОК Б. Приклад програми із семантичними помилками та текст файлу з повідомленнями про помилки. #program NAME; variable S,K,WF,A,AS,C,B,SWER ;integer16_t; start K::=7; input(A); output(A); stop Файл Errors.txt: Error output file. Next errors found: 1 line 2: 'start' expected! 2 line 2: 'var' expected! line 1: ';' expected! line 12: Too much 'End'! line 2: Unknown identifier!(tMP) line 2: Unknown identifier!(pES) line 2: Unknown identifier!(sUMA) line 2: Unknown identifier!(integer) line 3: Unknown identifier!(tMP) line 4: Unknown identifier!(pES) line 5: Unknown identifier!(sUMA) line 9: Unknown identifier!(sUMA) line 9: Unknown identifier!(sUMA) line 9: Unknown identifier!(tMP) line 11: Unknown identifier!(sUMA) ДОДАТОК В. Приклад коректної програми та результат її виконання. program name; start var tMP,pES,sUMA integer16; tMP::=1; pES::=5; sUMA::=0; for tMP to pES do start sUMA::=sUMA add tMP; finish print(sUMA); finish Файл Errors.txt Error output file. Next errors found: No errors found. Файл Lexem.txt Output lexem file. Results of the lexical analyze: next lexems found: Name Type Value Line 1 program Start_of_Program 0 1 2 name unknown 1 1 3 ; EndGroup 1 4 start Start 0 2 5 var Variable 0 2 6 tMP identifier 1 2 7 , komma 0 2 8 pES identifier 1 2 9 , komma 0 2 10 sUMA identifier 1 2 11 integer16
Антиботан аватар за замовчуванням

06.12.2014 17:12-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!