Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 47

Тема 1: Розробка мовних

процесорів для мов


програмування високого рівня
1. Поняття мовного процесора, типи мовних
процесорів.
2. Основні фази мовного процесора, спрощена
модель компілятора.
2.1. лексичний аналіз програм на мові високого рівня
2.2. робота з таблицями (хеш-таблиці)
2.3. синтаксичний аналіз програми
2.4. генерація проміжного коду
2.5. оптимізація проміжного коду
2.6. аналіз помилок компіляції та генерація машинного
коду
2.7. взаємодія етапів компіляції, проходи компілятора.
Шаблони для ведення лекцій за презентаціям
и (підготовлені для друку)
Приклад конспектy лекцій за презентаціями
1. Поняття мовного процесора,
типи мовних процесорів
Класифікація штучних мов за
рівнем складності:
 машинна мова – це набір команд конкретного
комп’ютера, які інтерпретуються і виконуються на
апаратному рівні.
 мова асемблера (мова низького рівня) – вона в
значній мірі відображає набір команд конкретного
комп’ютера.
 директивні мови – використовуються для зв’язку
з операційною системою (наприклад, MS-DOS).
 мови високого рівня – Pascal, C. Вони мають
складну структуру і практично не залежать ні від
набору команд, ні від конкретного комп’ютера.
Програма, яка дозволяє зрозуміти директиви і речення
вхідної мови, яку використовує програміст,
називається мовним процесором.

Мовні процесори
Компілятори Транслятори Інтерпретатори
Крос-компілятори

Препроцесори

Етапи виконання програми


Початкова програма Об’єктна програма
Машина А Машина B
(компіляція) (виконання)

Об’єктна програма Результат роботи


Компілятори та інтерпретатори
C
 C++
 Pascal

 PHP
 Perl
 Python
 Ruby
2. Основні фази мовного процесора,
спрощена модель компілятора.

 препроцесор;
 лексичний аналіз;
 організація таблиць;
 синтаксичний аналіз;
 семантичний аналіз;
 генерація проміжного коду;
 оптимізація;
 генерація машинного коду.
2.1. Лексичний аналіз програм для мови
високого рівня
Лексичний аналіз - це розбиття вхідної послідовності
символів на найпростіші змістовні одиниці (лексеми).

cost := (price + tax) * 0.98


Типи лексем:
• Iдентифікатор: іden
• Дійсне число: number
• Присвоєння: assign
• Знак плюс: plus
• Знак множення: mult
• Ліва дужка: left
• Права дужка: right
<тип лексеми, значення лексеми>
<тип лексеми, вказівник в таблиці>
<тип лексеми>
cost := (price + tax) * 0.98
enum Token{ // типи лексем
іden, // Iдентифікатор
number, // Дійсне число
assign= ‘=’, // Присвоєння :=
plus= '+’, // Знак плюс
mult= ‘*’, // Знак множення
left= ‘(‘, // Ліва дужка
right= ‘)’ // Права дужка
};
Приклад лексичного аналізу для
індивідуальної роботи 1

Послідовність символів:
cost := (price + tax) * 0.98

Послідовність лексем:
<iden,р1> <assign> <left> <iden,р2> <plus> <iden,р3>
<right> <mult> <number,q1>
Виконання індивідуальної роботи №1
(фаза лексичного аналізу)
Приклад лексичного аналізу
подібний до лабораторних робіт 1, 2
Вхідний файл: asdsf aaaf asssas j 123as
a12222fkl nmnmn faaa
Маска: a*s*
Файл з лексемами: <match, asdsf> <notMatch,
aaaf> <match, asssas> <notMatch, j> < notMatch,
123as> <notMatch, a12222fkl> <notMatch,
nmnmn> <notMatch, faaa>

Код C# (лексичний аналізатор):


https://onlinegdb.com/SkKbW7sJd
Код C# (лексичний аналізатор)

<notMatch, Є> <match, можливість> <match, модуль>


<notMatch, 1> <notMatch, здати> <match, моментальн
о>
2.2. Робота з таблицями
(хеш-таблиці)
real cost, tax, price
cost := (price + tax)*0.98
Номер Ідентифікатор Значення
1 cost p1
2 tax p2
3 price p3

1) швидкий пошук інформації про ідентифікатор


2) швидке додавання ідентифікаторів у таблицю
Таблиці розміщення
(хеш-таблиці)
Традиційна Kласифікацією
класифікація Ахо,
Хопкрофта,
Ульмана
хешування з відкрите
ланцюжками хешування
(зі списками) (багатовимірне)
хешування з закрите
відкритою хешування
адресацією (одновимірне)
Схеми хешування
Хешування з ланцюжками
(зі списками)
Приклад хешування
зі списками
19, 6, 27, 22, 16, 11
Хешування з відкритою
адресацією (одновимірне)

Схема пам’яті
h(α): h0(α), h1(α), . . , h m (α)
Приклад одновимірного
хешування
cost, tax і price
h0(α)=СОDЕ(α) mod 6
hi(α)=(СОDЕ(α)+i+2) mod 6), i=1,…,5

CODE (cost)=3+15+19+20=57
h0(cost)= CODE(cost) mod 6= 57 mod 6 =3
CODE(a)=1 CODE(p)=16
CODE (tax)= 20+1+24=45
CODE(c)=3 CODE(r)=18
h0(tax)= CODE(tax) mod 6 = 45 mod 6 = 3
CODE(e)=5 CODE(s)=19 h1(tax)= 48 mod 6 = 0
CODE(i)=9 CODE(t)=20 CODE (price)=16+18+9+3+5=51
h0(price)= CODE (price) mod 6 = 51 mod 6 = 3
CODE(o)=15 CODE(x)=24 h1(price)= 54 mod 6 =0
h2(price)= 55 mod 6 =1
Виконання індивідуальної роботи №1
(робота з таблицями)

Оператор: cost:=(tax+price)*0.98
Розмір таблиці: n=6
Первинна хеш-функція:
h0(α)=Code(α) % n
Вторинні хеш-функції:
hi(α)=(Code(α)+i+2) % n,
i=1,...,n-1
Адреса у локальній мережі:
Програмна група Apm \Math_02 \Zavd_Lab \SystProg \Проекти \Хеш таблиці
Функції розміщення
// Адитивний метод
// Ділення typedef
typedef int HashIndexType; unsigned char
const int HashTableSize=7; HashIndexType; //8 bit
const int HashTableSize=256;
HashIndexType Hash(int Key) HashIndexType Hash(char *str)
{ {
return Key % HashTableSize; HashIndexType h = 0;
} while (*str) h+= *str++;
return h;
}
Методи вирішення
конфліктів
Побудова вторинних функцій
h1,...,hm
hj(α)  hi(α) для всіх i j, m = n-1.
 hi(α) = (h0(α) + i) mod n, (1)
 hi(α) = (h0(α) + ri) mod n, (2)
 h (α) = (i(h0(α) +1)) mod n, (3)
i
 h (α) = (h (α) + ai2+bi) mod n, (4)
i 0
i=1,2,…,n-1
2.3. Синтаксичний аналіз програми
Послідовність символів: Послідовність кроків:
cost := (price + tax)*0.98 1) <ід, р2> <+> <ід, р3>
2) крок1 <*> <дч, q1>
3) <ід, р1> <пр> крок2
Послідовність лексем:
<ід, р1> <пр> <(> <ід, р2> <+> <ід, р3> <)> <*> <дч, q1>

< >

< >
Пріоритети операцій
0 – “:=”
1 – “+”
2 – “*”
“(” – збільшує пріоритет операції на 3
“)” – зменшує пріоритет операції на 3
cost:=(price+tax*5)*0.98+k*7.2
cost:=(price+tax)*0.98 0 4 5 2 1 2
0 4 2 Послідовність операцій:
*
Послідовність операцій: +
+ *
* *
:= +
:=
Рівні вершин
cost := (price + tax) * 0.98


0, якщо n немає нащадків
l n   
 max l ni   1, ni  нащадки вершини n
 1i k
Виконання індивідуальної роботи №1
(синтаксичний аналіз)
2.4. Генерація проміжного коду
Дерево у компактному вигляді для
числового виразу:
((3-(5+9))/(2*3))

Проміжний код з 4 регістрами для дерева:


 Add R0 5 9
 Sub R1 3 R0
 Mpy R2 2 3
 Div R3 R1 R2
Генерація проміжного коду з
одним регістром (суматором)
Введемо позначення:
R(m) – містиме комірки m.
=m – числове значення m.

Команда Значення
Load m R(m)суматор
Add m суматор + R(m)суматор
Mpy m суматор * R(m)суматор
Store m суматор  R(m)
Load =m m  суматор
Add =m суматор + m  суматор
Mpy =m суматор * m суматор
2.4. Генерація проміжного коду

а) б) в)

Введемо позначення:
C n  – частина проміжного коду, що відповідає вершині .
l n  – рівень вершини .

0, якщо n не немає
має нащадків
l n   
 max l ni   1, ni  нащадки вершини n
 1i k
Визначимо код , для кожного типу вершини:

1)  Якщо n – лист, який відповідає ідентифікатору,


то С(n) – це ім’я змінної, яке відповідає
ідентифікатору (наприклад, cost).
 Якщо n – лист, який відповідає дійсному числу,
то С(n) – дійсне число (наприклад, =0.98).
 Якщо n – лист, який відповідає лексемам
<+>, <*>, <пр>, то їм не відповідає ніякий код.

2) Якщо n – вершина типу а), m1, m2, m3 –


нащадки, тоді код цієї вершини :

C n   Load C m3
Store C m1
3) Якщо n – вершина типу б), m1, m2, m3 –
нащадки, то вершині відповідає такий
код:
C n   C m3
Store $l n 
Load C m1
Add $l n 

4) Якщо n – вершина типу в), m1, m2, m3 –


нащадки, тоді код цієї вершини :
C n   C m3
Store $l n 
Load C m1
* Mpy $l n 
Побудова проміжного коду
cost := (price + tax)*0.98
C n   Load C m3
Store C m1

C n   C m3
Store $l n 
Load C m1
Add $l n 

C n   C m3
Store $l n 
* Load C m1
Mpy $l n 
cost := (price + tax)*0.98

C n1 : tax; Store $1; Load price; Add $1


C n 2  :  0.98; Store $2; Load C n1; Mpy $2
C n 3 : Load C n 2 ; Store Cost
Проміжний код
Виконання проміжного коду
Виконання проміжного коду
Т
Е
С
Т
У
В
А
Н
Н
Я
Можливі помилки
Load C(m2);Store $4;Load 2.7; Add $4;

???
(зайві пробіли, не той рівень вершин,
не той порядок завантаження)

C(m2); Store $3; Load =2.7; Add $3 ❌

=2.7; Store $4; Load C(m2); Add $4 ❌

C(m2);Store $4;Load =2.7;Add $4


2.5. Оптимізація проміжного коду
Load a   Load b

1) Add b   Add a операція «+» є комутативною в тому
випадку, коли на Add b не передавалось управління.

Load a   Load b
 2) Mpy b 
 операція «*» є комутативною .
Mpy a

Store a
 3) Load a можна вилучити при умові, що
надалі комірка a не буде використовуватись або буде
заповнена безпосередньо перед використанням.
Load a
 4) Store b можна вилучити при умові, що за нею
слідує інший оператор Load і немає переходу до Store b.
Наступні входження b замінюються на a до того
моменту, поки знову не з’явиться оператор Store b.
2.5. Оптимізація проміжного коду

cost := (price + tax)*0.98

Load  0.98 Load  0.98


Store $2  Store $2  Load  0.98
 
Load tax  Load tax  Store $2  Load tax 
 1.  3. 
Store $1  Store $1  Load tax  4. Add price 
   
Load price  Load $1  Add price  Mpy  0.98
Add $1  Add price  Mpy $2  Store co st 
  
Mpy $2  Mpy $2  Store co st 
Store co st  Store co st 
2.6. Аналіз помилок компіляції та
генерація машинного коду

Помилки можуть бути різних типів, наприклад:

 помилки, при яких вхідні символи не утворюють


лексему;
 помилки, при яких вхідну програму можна розбити
на лексеми, але послідовність лексем не
задовольняє синтаксичні правила мови;
 програма має правильну синтаксичну структуру, але
неможливо згенерувати код (таке буває, наприклад,
коли змінна не має опису).

Керування таблицями та обробка помилок


використовуються на всіх фазах компіляції.
Генерація машинного коду
(асемблювання)
 Асемблювання – це заключний етап, на
якому проміжний код перетворюється в
машинний код.
 При генерації машинного коду
розв’язуються такі задачі:
 розміщення даних у пам’яті;
 вибір способу доступу до них;
 вибір регістрів для обчислення.
Одна з можливих моделей компілятора
2.7.Взаємодія етапів компіляції,
проходи компілятора

(1) – початкова програма.


(2) – послідовність лексем.
(3) – проміжний код.
Тема 2
(4) – машинний код.

You might also like