Чому неоднозначні граматики погані?


30

Я розумію, що якщо існує 2 і більше лівих або правих дериваційних дерев, то граматика неоднозначна, але я не в змозі зрозуміти, чому це так погано, що всі хочуть його позбутися.


1
Пов’язані, але не тотожні: softwareengineering.stackexchange.com/q/343872/206652 (відмова від відповідальності: я написав прийняту відповідь)
marstato


1
Дійсно, однозначна форма краще для практичного використання, однозначна форма використання меншої кількості виробничих правил будує менше дерево у високій (отже, ефективний компілятор - потребує менше часу для розбору). Більшість інструментів забезпечують можливість вирішення неоднозначностей явно поза граматикою.
Grijesh Chauhan

3
"всі хочуть її позбутися". Ну, це просто неправда. У комерційно релевантних мовах прийнято бачити двозначність, коли мови розвиваються. Наприклад, C ++ навмисно додав неоднозначності std::vector<std::vector<int>>в 2011 році, який раніше вимагав пробілу між ними >>. Ключове розуміння полягає в тому, що ці мови мають набагато більше користувачів, ніж постачальники, тому виправлення незначного роздратування для користувачів виправдовує велику роботу виконавців.
MSalters

Відповіді:


52

Розглянемо наступну граматику для арифметичних виразів:

XX+XXXXXX/Xvarconst
Розглянемо такий вираз:
abc
Яке його значення? Ось два можливі дерева розбору:

(X - X) - X введіть тут опис зображення

Згідно з ліворуч, ми повинні тлумачити abc як (а-б)-c , що є звичайним тлумаченням. Відповідно до одного праворуч, ми повинні інтерпретувати його як а-(б-c)=а-б+c , що, ймовірно , не те , що було задумано.

Складаючи програму, ми хочемо, щоб інтерпретація синтаксису була однозначною. Найпростіший спосіб забезпечити це - використання однозначної граматики. Якщо граматика неоднозначна, ми можемо надати правила розриву зв’язків, як пріоритет оператора та асоціативність. Ці правила можна рівномірно виразити, зробивши граматику однозначною особливим чином.


Розбір дерев, створених за допомогою генератора синтаксичного дерева .


12
@HIRAKMONDAL Те, що синтаксис є неоднозначним, не є реальним питанням. проблема полягає в тому, що два різних дерева розбору мають різну поведінку. Якщо у вашій мові є неоднозначна граматика, але всі дерева розбору для виразу є семантично еквівалентними, то це не буде проблемою (наприклад, візьміть приклад Yuval і розгляньте випадок, коли ваш єдиний оператор +).
Бакуріу

14
@Bakuriu Те, що ви сказали, є правдою, але "семантично рівнозначне" - це високий порядок. Наприклад, арифметика з плаваючою комою насправді не асоціативна (тому два дерева "+" не були б рівнозначними). Крім того, навіть якщо відповідь вийшла однаково, невизначений порядок оцінювання має велике значення в мовах, де вирази можуть мати побічні ефекти. Отже, те, що ви сказали, є технічно правдивим, але на практиці було б дуже незвично, щоб неоднозначність граматики не мала ніяких наслідків для використання цієї граматики.
Річард Раст

Деякі мови в даний час перевіряють на ціле переповнення в доповненнях, тому навіть a + b + c для цілих чисел залежить від порядку оцінки.
gnasher729

3
Ще гірше, що в деяких випадках граматика не дає жодного способу досягти альтернативного значення. Я бачив це на мовах запитів, де вибір граматики втечі (наприклад, подвійний спеціальний символ, щоб уникнути цього) робить певні запити неможливими.
Зупиніть шкодити Моніці

12

На відміну від інших існуючих відповідей [ 1 , 2 ], справді існує поле застосування, де корисні неоднозначні граматики . У галузі обробки природних мов (NLP), коли ви хочете розібрати природну мову (NL) з формальними граматиками, у вас з’явилася проблема, що NL по своїй суті неоднозначно на різних рівнях [адаптовано від Koh18, гол. 6.4]:

  • Синтаксична амбігія:

    Петро переслідував чоловіка в червоній спортивній машині

    Пітер чи чоловік у червоній спортивній машині?

  • Семантична амбіція:

    Пітер пішов до банку

    Банк, на якому слід сидіти, або банк для зняття грошей?

  • Прагматична амбіція:

    Двоє чоловіків несли дві сумки

    Вони носили сумки разом чи кожен чоловік носив по дві сумки?

Різні підходи до НЛП по-різному стосуються обробки в цілому та зокрема цих амбіцій. Наприклад, ваш трубопровід може виглядати наступним чином:

  1. Розбирайте NL з неоднозначною граматикою
  2. Для кожного результату AST: запустити генерацію моделі, щоб генерувати неоднозначні смислові значення та виключати неможливі синтаксичні неоднозначності з кроку 1
  3. Для кожної отриманої моделі: збережіть її у своєму кеші.

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

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

Якщо ви хочете забруднити руки, коли парсери зможуть виводити декілька виводів для неоднозначної граматики, погляньте на Граматичну рамку . Також [Koh18, гол. 5] містить вступ до нього, де відображається щось подібне до мого конвеєра вище. Зауважте, що оскільки [Koh18] є конспектами лекцій, замітки можуть бути не такими легко зрозуміти самостійно без лекцій.


Список літератури

[Koh18]: Майкл Кольхазе. "Логічна обробка природних мов. Зимовий семестр 2018/19. Конспекти лекцій." URL: https://kwarc.info/teaching/LBS/notes.pdf . URL-адреса опису курсу: https://kwarc.info/courses/lbs/ (німецькою мовою)

[Кох18, гол. 5]: Див. Розділ 5, "Реалізація фрагментів: граматичні та логічні рамки", в [Koh18]

[Кох18, гол. 6.4] Див. Главу 6.4, "Обчислювальна роль неоднозначностей", в [Koh18]


Дякую тонну .. У мене були такі самі сумніви, і ви його очистили .. :)
HIRAK MONDAL

1
Не кажучи вже про проблеми з буйволами буйволів Буйвол Буффало Буйвол Буффало ... для відповідної кількості буйволів
Хаген фон Ейтцен

Ви пишете "навпаки", але я би назвав це іншою стороною монети з того, що я відповів. Розбір природних мов з їх неоднозначними граматиками настільки важкий, що традиційні аналізатори не можуть цього зробити!
Девіслор

1
@ComFreek Я повинен бути більш точним тут. Короткий погляд на GF (спасибі за посилання!) Показує, що він читає без контексту граматики з трьома розширеннями (наприклад, дозволяючи скорочення) і повертає список усіх можливих виводів. Алгоритми для цього існували вже з 50-х років. Однак, якщо ви можете працювати з загальноприйнятими CFG, це означає, що ваш найгірший термін виконання вибухне, і на практиці навіть при використанні загального аналізатора, такого як GLL, інженери-программісти намагаються використовувати підмножину CFG, наприклад граматики LL, які можуть аналізувати ефективніше.
Девіслор

1
@ComFreek Отже, справа не в тому, що комп'ютери не можуть працювати з CFG (хоча природні мови насправді не є контекстними, а фактично корисний машинний переклад використовує зовсім інші методи). Це те, що якщо ви вимагаєте від свого парсера розглянути неоднозначність, це виключає певні ярлики, які зробили б його більш ефективним.
Девіслор

10

Навіть якщо є чітко визначений спосіб поводження з неоднозначністю (неоднозначні вирази, наприклад, синтаксичні помилки), ці граматики все ще створюють проблеми. Щойно ви вводите неоднозначність у граматику, аналізатор вже не може бути впевнений, що перша відповідність, яку він отримує, є остаточною. Необхідно продовжувати намагатися всі інші способи розбору твердження, щоб виключити неоднозначність. Ви також не маєте справу з чимось простим, як, наприклад, LL (1) мова, тому не можете використовувати простий, маленький, швидкий парсер. У вашій граматиці є символи, які можна прочитати різними способами, тому вам потрібно бути готовим до того, щоб багато чого відхилити.

У деяких обмежених областях ви можете уникнути, довівши, що всі можливі способи розбору виразу еквівалентні (наприклад, тому що вони представляють асоціативну операцію). (a + b) + c = a + (b + c).


9

Це IF a THEN IF b THEN x ELSE yозначає

IF a THEN
    IF b THEN
        x
    ELSE
        y

або

IF a THEN
    IF b THEN x
ELSE
    y

? AKA висить ще проблема .


1
Це хороший приклад, що показує, що навіть неоднозначна граматика (як у Java, C, C ++, ...) дозволяє із людської точки зору очевидні (!) Неоднозначності. Незважаючи на те, що ми формально і обчислювально чудово, зараз ми отримаємо більше проблеми розвитку UX / помилок.
ComFreek

5

Візьмемо, наприклад, найбільш роздратований аналіз на C ++:

bar foo(foobar());

Це функція декларації fooтипу bar(foobar())(параметр - це покажчик функції, що повертається a foobar), або декларація змінної fooтипу intта ініціалізована ініціалізацією за замовчуванням foobar?

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

коли ви отримуєте такий неоднозначний вираз, у компілятора є 2 варіанти

  1. припустимо, що вираз є певним виведенням, і додайте граматиці деякий розбірник, щоб дозволити виразити іншу деривацію.

  2. помилка і вимагає розрізнення в будь-якому випадку

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

Якщо ця неоднозначність залишається невизначеною, можливо, два різних компілятори за замовчуванням для різних виводів для цього неоднозначного виразу. Веде до того, що код є непереносним з незрозумілих причин. Це спонукає людей вважати, що це помилка в одному з компіляторів, хоча насправді це помилка в мовній специфікації.


5

Я думаю, що питання містить припущення, яке в кращому випадку є правильним лише на кордоні.

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

Наприклад, якщо ви подивитеся на граматики, складені з yacc (або подібними, такими як зубр або byacc), ви побачите, що при їх компілюванні досить багато створюють попередження про "N конфліктів зміщення / зменшення". Коли yacc стикається зі зміною / зменшенням конфлікту, це сигналізує про неоднозначність у граматиці.

Однак конфлікт із зміною / зменшенням, як правило, є досить незначною проблемою. Генератор аналізатора вирішить конфлікт на користь "зрушення", а не зменшення. Граматика цілком чудова, якщо це те, що ти хочеш (і, здається, на практиці це виходить ідеально).

Конфлікт "зсув / зменшення" зазвичай виникає у випадку в цьому загальному порядку (використовуючи обмеження для нетерміналів та малі регістри для терміналів):

A -> B | c
B -> a | c

Коли ми стикаємося з a c, виникає неоднозначність: чи слід розбирати cбезпосередньо як an A, чи слід розбирати його як a B, що, в свою чергу, є A? У такому випадку, yacc і подібні будуть вибирати простіший / коротший маршрут і аналізувати напрям cбезпосередньо як A, а не йти маршрутом c-> B-> A. Це може бути неправильним, але якщо так, це, ймовірно, означає, що у вашій граматиці є дійсно проста помилка, і ви не повинні взагалі допускати cваріант як можливість A.

Тепер, навпаки, у нас може бути щось подібне:

A -> B | C
B -> a | c
C -> b | c

Тепер, коли ми стикаємося, у cнас виникає конфлікт між тим, чи слід ставитися до цього cяк до Bабо як C. Набагато менше шансів, що стратегія автоматичного вирішення конфлікту вибере те, що ми насправді хочемо. Жодне з них не є "зрушенням" - і те, і інше - "скорочення", тому це "зменшення / зменшення конфлікту" (яке ті, хто звик до yacc, і таких, як правило, визнають набагато більшою проблемою, ніж конфлікт зміни / зменшення).

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


чоловіче, хотілося б, щоб я мав це чудове пояснення конфліктів зменшення зрушень 5 місяців тому! ^^; +1
HotelCalifornia
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.