SLR, LALR і LR парсери можуть бути реалізовані за допомогою однакових машин, керованих таблицею.
По суті, алгоритм синтаксичного аналізу збирає наступний маркер введення T і консультує поточний стан S (і пов'язані з ним таблиці пошуку, GOTO та скорочення), щоб вирішити, що робити:
- SHIFT: Якщо поточна таблиця говорить SHIFT на токені T, пара (S, T) висувається на стек розбору, стан змінюється відповідно до того, що в GOTO таблиці вказано для поточного маркера (наприклад, GOTO (T) ) витягується інший маркер T ', і процес повторюється
- ЗНИЖЕННЯ: Кожен стан має 0, 1 або багато можливих скорочень, які можуть статися в державі. Якщо аналізатор LR або LALR, маркер перевіряється наборами lookahead для всіх дійсних скорочень для стану. Якщо маркер відповідає множині пошуку для зменшення для граматичного правила G = R1 R2 .. Rn, відбувається зменшення та зсув стека: семантична дія для G викликається, стек вискакується n (від Rn) разів, пара ( S, G) висувається на стек, новий стан S 'встановлюється на GOTO (G), і цикл повторюється тим же символом T. Якщо аналізатор є аналізатором дзеркальних зображень, існує щонайменше одне правило зменшення для стан і тому зменшення може бути виконано наосліп, не шукаючи, яке зменшення застосовується. Користувачеві аналізатор дзеркальних речей знає, чи єзменшення чи ні; це легко визначити, чи кожен стан явно записує кількість скорочень, пов'язаних з ним, і чи потрібний цей підрахунок для версій L (AL) R на практиці.
- ПОМИЛКА: Якщо ні SHIFT, ні REDUCE неможливо, оголошується помилка синтаксису.
Отже, якщо всі вони використовують одну і ту ж техніку, який сенс?
Передбачуване значення в дзеркальному дзеркалі - це його простота в реалізації; вам не доведеться перевіряти можливі скорочення, перевіряючи набори пошуку, тому що є щонайбільше один, і це єдина життєздатна дія, якщо немає виходів SHIFT із стану. Яке зменшення застосовується, може бути прикріплено спеціально до держави, тому машини для розбору дзеркальних речей не повинні полювати на нього. На практиці L (AL) R парсери обробляють корисно більший набір мов, і це так мало додаткової роботи, щоб здійснити, що ніхто не реалізує дзеркальні матеріали, окрім як навчальних занять.
Різниця між LALR і LR пов'язана з генератором таблиць. Генератори LR-парсера відслідковують усі можливі скорочення від конкретних станів та їх точний набір пошуку; Ви закінчуєте стани, в яких кожне зменшення пов'язане з його точним набором пошуку в лівому контексті. Це має тенденцію до побудови досить великих наборів держав. Генератори LALR аналізаторів готові комбінувати стани, якщо таблиці GOTO та набори для редукційних заголовків сумісні та сумісні та не конфліктують; це створює значно меншу кількість станів, ціною не в змозі розрізнити певні послідовності символів, які LR може розрізнити. Таким чином, LR-парсери можуть розбирати більший набір мов, ніж LALR-парсери, але мають дуже великі таблиці парсерів. На практиці можна знайти граматики LALR, які досить близькі до цільових мов, щоб розмір державної машини варто оптимізувати;
Отже: усі троє користуються однаковою технікою. Дзеркальна дзеркальна плата "проста" в тому сенсі, що ви можете ігнорувати крихітний апарат, але це просто не варте клопоту. LR аналізує більш широкий набір мов, але таблиці держав, як правило, досить великі. Це залишає LALR як практичний вибір.
Сказавши все це, варто знати, що парсери GLR можуть розбирати будь-яку контекстну мову, використовуючи складніші машини, але точно ті ж таблиці (включаючи меншу версію, що використовується LALR). Це означає, що GLR суворо потужніший, ніж LR, LALR та SLR; В значній мірі, якщо ви можете написати стандартну граматику BNF, GLR буде аналізувати її. Різниця в техніці полягає в тому, що GLR готовий спробувати кілька аналізів, коли виникають конфлікти між таблицею GOTO та наборами lookahead. (Наскільки GLR робить це ефективно, це геній [не мій], але не вписується в цю посаду ТА).
Це для мене надзвичайно корисний факт. Я будую програмні аналізатори та трансформатори коду та аналізатори необхідні, але "нецікаві"; цікава робота - це те, що ви робите з проаналізованим результатом, і тому фокус робиться на виконанні роботи після розбору. Використання GLR означає, що я відносно легко можу створити робочі граматики, порівняно із злому граматики, щоб потрапити у зручну форму LALR. Це дуже важливо, коли ви намагаєтеся мати справу з неакадемічними мовами, такими як C ++ або Fortran, де вам буквально потрібні тисячі правил, щоб добре обробити всю мову, і ви не хочете витрачати своє життя на те, щоб зламати правила граматики, щоб відповідати обмеженням LALR (або навіть LR).
Як своєрідний відомий приклад, C ++ вважається надзвичайно важким для розбору ... хлопці, які роблять розбір LALR. C ++ легко аналізувати, використовуючи обладнання GLR, використовуючи в значній мірі правила, наведені в задній частині посібника C ++. (У мене є саме такий аналізатор, і він обробляє не тільки ванільний C ++, а й різноманітні діалекти постачальників. Це можливо лише на практиці, оскільки ми використовуємо парсер GLR, IMHO).
[EDIT листопада 2011 року: ми розширили наш аналізатор для обробки всіх C ++ 11. GLR зробив це набагато простіше зробити. EDIT серп. 2014: Зараз обробляються всі C ++ 17. Нічого не зламалося і не погіршилося, GLR - це все ще котячий м'яч.]