Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
курсова2.doc
Скачиваний:
7
Добавлен:
11.07.2019
Размер:
214.02 Кб
Скачать

Лексичні аналізатори (сканери). Принципи побудови сканерів

Призначення лексичного аналізатора

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

Лексема (лексична одиниця мови) - це структурна одиниця мови, кото ¬ рая складається з елементарних символів мови і не містить в своєму складі дру ¬ гих структурних одиниць мови.

Лексемами мов природного спілкування є слова1.Лексемами мов програмування є ідентифікатори, константи, ключові слова язи ¬ ка, знаки операцій і т. п. Склад можливих лексем кожного конкретного мови програмування визначається синтаксисом цієї мови.Лексичний аналізатор (або сканер) - це частина компілятора, яка читає вихідну програму і виділяє в її тексті лексеми вхідної мови.На вхід лексичного аналізатора надходить текст вихідної програми, а вихідна ін ¬ формація передається для подальшої обробки компілятором на етапі син ¬ таксіческого аналізу та розбору.

У мовах природного спілкування лексикою називається словниковий запас мови.Лексіче ¬ ський склад мови вивчається лексикологией і фразеологією, а значення лексем (слів мови) - Марію. У мовах програмування словниковий запас, звичайно, не настільки цікавий і спеціальною наукою не вивчається.

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

□ застосування лексичного аналізатора спрощує роботу з текстом вихідної програми на етапі синтаксичного і скорочує обсяг обрабат ¬ ваному інформації, так як лексичний аналізатор структурує посту ¬ вступників на вхід вихідний текст програми і відкидає всю незначущих інформацію;

□ для виділення в тексті та розбору лексем можливо застосовувати просту, ефек ¬ фективно і теоретично добре опрацьовану техніку аналізу, в то вре ¬ мя як на етапі синтаксичного аналізу конструкцій вихідного мови вико ¬ користуються досить складні алгоритми розбору;

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

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

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

УВАГА

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

Не слід плутати таблицю лексем і таблицю ідентифікаторів - це дві принци ¬ піальной різні таблиці, оброблювані лексичним аналізатором.

лексема (ідентифікатор або константа) може зустрічатися в таблиці иденти ¬ фікаторов тільки один раз.Також можна відзначити, що лексеми в таблиці лек ¬ сем обов'язково розташовуються в тому ж порядку, як і у вихідній програмі (порядок лексем в ній не змінюється), а в таблиці ідентифікаторів лексеми рас ¬ покладаються в будь-якому порядку так,щоб забезпечити зручність пошуку (методи ор ¬ ганізації таблиць ідентифікаторів розглянуті в попередньому розділі).Як приклад можна розглянути певний фрагмент вихідного коду мовою Pascal і відповідну йому таблицю лексем, представлену в табл. 3.1:

begin

for I: = 1 to N do fg: = fg * 0.5

Таблица 3.1. Лексемы программы

Лексема

Тип лексемы

Значение

begin

Ключевое слово

XI

for

Ключевое слово

Х2

i

Идентификатор

i: 1

:-

Знак присваивания

SI

1

Целочисленная константа

1

to

Ключевое слово

ХЗ

N

Идентификатор

N:2

do

Ключевое слово

Х4

fg

Идентификатор

fg:3

:-

Знак присваивания

SI

fg

Идентификатор

fg:3

*

Знак арифметической операции

Al

0.5

Вещественная константа

0.5

Поле «Значення» в табл. 3.1 увазі якесь кодове значення, яке буде поміщено в підсумкову таблицю лексем в результаті роботи лексичного аналізатора. Звичайно, значення, які записані в прикладі, є умовні ¬ ми. Конкретні коди вибираються розробниками при реалізації компілятора.Важливо відзначити також, що встановлюється зв'язка таблиці лексем з таблицею ідентифікаторів (у прикладі це відображено деяким індексом, наступним по ¬ сле ідентифікатора за знаком:, а в реальному компіляторі визначається його реа ¬ лизацией).

Принципи побудови лексичних аналізаторів

Лексичний аналізатор має справу з такими об'єктами, як різного роду константи і ідентифікатори (до останніх належать і ключові слова). Мова констант і ідентифікаторів є регулярним - тобто може бути описаний за допомогою регулярних граматик.Розпізнавачем для регулярних мов є кінцеві автомати. Отже, основою для реалізації лексіче ¬ ських аналізаторів служать регулярні граматики і кінцеві автомати.Існують правила, за допомогою яких для будь-якої регулярної граматики може бути побудований кінцевий автомат, що розпізнає ланцюжка мови, задано ¬ го цієї граматикою (ці правила розглянуті далі в цьому розділі).Кінцевий автомат для кожної вхідного ланцюжка мови дає відповідь на питання про те, належить чи ні ланцюжок мови, заданому автоматом. Проте в загальному випадку завдання лексичного аналізатора трохи ширше, ніж просто перевірка ланцюжка символів лексеми на відповідність вхідного мови.Крім цього, він повинен виконати наступні дії:

□ визначити межі лексем, які в тексті вихідної програми явно не вказані;

□ виконати дії для збереження інформації про виявлену лексеме (або видати повідомлення про помилку, якщо лексема невірна).

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

Визначення меж лексем

Виділення кордонів лексем є нетривіальним завданням. Адже в тексті результат ¬ ної програми лексеми не обмежені жодними спеціальними символами.Якщо говорити в термінах лексичного аналізатора, то визначення меж лек ¬ сем - це виділення тих рядків у загальному потоці вхідних символів, для яких треба виконувати розпізнавання.

Ілюстрацією випадку, коли визначення меж лексеми викликає певні складності, може бути приклад оператора програми на мові FORTRAN: по фрагменту вихідного коду DO 10 січня = 1 неможливо визначити тип оператора мови (а відповідно, і межі лексем). У разі DO 10 Січень = 1.15 це присвое ¬ ня речової змінної D010I значення константи 1.15 (прогалини в мові FORNTAN ігноруються), а в разі DO 10 січня = 1.15 - це цикл з перерахуванням від 1 до 15 по целочисленной змінної I до позначки 10.

Інший ілюстрацією може служити оператор мови С, має вигляд: к =

= Т +++++ J,.Існує тільки одна єдино вірна трактування цього операто-

ра: к = 1 + + + + + j, - (якщо явно пояснити її за допомогою дужок, то дана конструк-

ція має вигляд: к - + (+ + J);). Проте знайти її лексичний аналізатор мо-

жет, лише переглянувши весь оператор до кінця і перебравши всі варіанти, причому

невірні варіанти можуть бути виявлені тільки на етапі семантичного ана-

лізу (наприклад, варіант k = + j: є синтаксично правильним,

але семантикою мови С не допускаються). Звичайно, щоб ця конструкція була

в принципі припустима, що входять до неї операнди k, ч і j повинні бути описані

і повинні допускати виконання операцій мови + + і +.

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

□ послідовний;

□ параллельний1.

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

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