- •2 Лексичний аналіз
- •2.1. Роль лексичних аналізаторів
- •2.1.1 Завдання лексичного аналізу
- •2.1.2 Токени, шаблони, лексеми
- •2.1.3 Атрибути токенів
- •2.2. Алфавит, рядки і мови
- •2.2.1 Алфавит та рядки над алфавитом
- •2.3 Регулярні вирази
- •2.2.2 Рядки й мови
- •2.2.3 Операції над мовами
- •2.2.4 Регулярні визначення
- •2.2.5 Скорочення
- •2.2.6 Нерегулярні множини
- •2.4. Розпізнавання токенів
- •Id → letter (letter | digit)*
- •2.3.1 Діаграми переходів
- •2.3.2 Реалізація діаграми переходів
2.1.2 Токени, шаблони, лексеми
Говорячи про лексичний аналіз, ми використаємо терміни "токен", "шаблон" й "лексема" кожний у своєму власному визначенні. Приклади їхнього використання наведені на рис. 2.2. Загалом кажучи, у вхідному потоці існує набір рядків, для яких як вихід отримуємо один і той самий токен. Цей набір рядків описується правилом, іменованим шаблоном (pattern), пов'язаним з токеном. Про шаблон говорять, що він відповідає (match) певному рядку в наборі. Лексема ж являє собою послідовність символів вхідної програми, що відповідає шаблону токена. Наприклад, в інструкції Pascal
const pi = 3.1416;
підрядок pi являє собою лексему токена "ідентифікатор". Приклади інших токенів наведено на рис. 2.2.
Токен |
Приклад лексем |
неформальний опис шаблона |
const |
const |
const |
if |
if |
if |
relation |
<, <=, =, <>, >, >= |
< або <= або = або про або > або >= |
id |
pi, count, D2 |
Буква, за котрою ідуть букви або цифри |
num |
3.1416, 0, 6.02E23 |
Будь-яка числова константа |
literal |
"core dumped" |
Будь-які символи між парними лапками, за виключенням самих лапок |
Рис. 2.2. Приклади токенів
Будемо розглядати токени як термінальні символи граматики вхідної мови, для позначення яких використовувати виділення іншим шрифтом. Лексеми, що відповідають шаблонам токенів, представляють у вхідній програмі рядки символів, які розглядаються разом як лексична одиниця.
У більшості мов програмування в якості токенів виступають ключові слова, оператори, ідентифікатори, константи, рядки літералів і символи пунктуації, наприклад дужки, коми й крапки з комами. У наведеному вище прикладі, коли у вхідному потоці зустрічається послідовність символів pi, синтаксичному аналізатору повертається токен, що представляє ідентифікатор. Повернення токена найчастіше реалізується шляхом передачі цілого числа або покажчика, що відповідає системному токену.
Шаблон - правило, що описує набір лексем, які можуть представляти певний токен у вхідній програмі. Так, шаблон токена const (рис. 2.2) являє собою просто рядок const, що є ключовим словом. Шаблон токена relation - набір всіх шести операторів порівняння в Pascal. Для точного опису шаблонів складних токенів типу id (для ідентифікатора) і num (для числа) потрібно використати регулярні вирази, яким присвячений розділ 2.2.
У багатьох мовах ряд рядків є зарезервованим, тобто їхній зміст визначений і не може бути змінений користувачем. Якщо ключові слова не зарезервовані, лексичний аналізатор повинен уміти визначити, із чим він має справу - ключовим словом або ідентифікатором, уведеним користувачем.
2.1.3 Атрибути токенів
Якщо шаблону відповідає кілька лексем, лексичний аналізатор повинен забезпечити додаткову інформацію про лексеми для наступних фаз компіляції. Наприклад, шаблон num відповідає як рядку 0, так й 1, і при генерації коду надто важливо знати, який саме рядок відповідає токену.
Лексичний аналізатор зберігає інформацію про токени у пов'язаних з ними атрибутах. Токени визначають роботу синтаксичного аналізатора; атрибути – трансляцію токенів. На практиці токени звичайно мають єдиний атрибут – покажчик на запис у таблиці символів, у якій зберігається інформація про токен. Для діагностичних цілей можуть знадобитися як лексеми ідентифікаторів, так і номера рядків, у яких вони вперше з'явилися в програмі. Вся ця (й інша) інформація може зберігатися в записах у таблиці символів.
Приклад 2.1
Токени й пов'язані з ними значення атрибутів для інструкції Fortran
Е = М*C**2
записуються як послідовність пар:
<id, покажчик на запис у таблиці символів для Е>
<assign_op, >
<id, покажчик на запис у таблиці символів для М>
<mult_op, >
<id, покажчик на запис у таблиці символів для C>
<ехр_ор, >
<num, ціле значення 2>.
Помітимо, що в деяких парах немає необхідності в значенні атрибута — першого компонента цілком достатньо, щоб ідентифікувати лексему. У цьому невеликому прикладі токен num заданий атрибутом із цілим значенням. Компілятор може зберігати рядок символів, що становлять число, у таблиці символів, зробивши, таким чином, атрибут токена num покажчиком на запис у таблиці символів.
