Що означає "без контексту" в терміні "без контекстної граматики"?


55

З огляду на кількість матеріалу, який намагається пояснити, що таке без контексту граматика (CFG), я вважаю, що дивно, що дуже мало (у моїй вибірці менше 1 на 20) дають пояснення, чому такі граматики називаються "контекстними, безкоштовно ". І, на мій погляд, нікому це не вдається.

Моє запитання: чому без контексту граматики називаються контекстними? Що таке "контекст"? У мене була інтуїція, що контекст може бути іншими мовними конструкціями, що оточують структуру, що аналізується в даний час, але, здається, це не так. Хтось може дати точне пояснення?


4
шукайте "найприємніший синтаксичний розбір" для C ++, який навчить вас, чому зручність у контексті зручна
храповик виродка

6
Я думав, що знаю, що таке без контексту граматика, поки я просто не прочитав деякі визначення Гугла. Тепер мені б хотілося, щоб у мене був етч-а-ескіз і м'яка ковдра ... можливо, я просто вийду назовні ... +1 для гарного питання. Чекаємо на кілька зрозумілих відповідей!
BrianH

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

1
Дивіться вікі-сторінки про безтекстову граматику та ієрархію Хомського . На практиці розбір мови програмування має деякий контекст, який часто обробляється "поза" "без контекстуального" (LR або LL) розбору, наприклад, за допомогою якоїсь таблиці символів, атрибутів чи середовища
Basile Starynkevitch

1
Тут є посилання XKCD: xkcd.com/1090
CaptainCodeman

Відповіді:


61

Це означає, що всі його виробничі правила мають єдину нетермінальну ліву частину.

Наприклад, ця граматика, яка розпізнає рядки відповідних дужок ("()", "() ()", "(()) ()", ...) не є контекстною:

S → SS
S → (S)
S → ()

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

Тепер розглянемо цю іншу граматику, яка розпізнає рядки форми {a ^ nb ^ nc ^ n: n> = 1} (наприклад, "abc", "aabbcc", "aaabbbccc"):

S  → abc
S  → aSBc
cB → WB
WB → WX
WX → BX
BX → Bc
bB → bb

Якщо Bперед нетермінальним символом передує термінальний / буквальний символ c, ви перезаписуєте цей термін, WBале якщо йому передує b, ви переходите на bbнього. Імовірно, на це натякає контекстно-залежна граматика.

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

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

Для контекстно-чутливої ​​мови КПК недостатньо. Вам знадобиться лінійно обмежений автомат , подібний до машини Тьюрінга, стрічка якої не обмежена (хоча кількість доступної стрічки пропорційна входу). Зауважте, що це досить добре описує комп’ютери - ми любимо вважати їх як машини Тьюрінга, але в реальному світі ви не можете довільно захопити більше середньої програми RAM. Якщо вам не очевидно, наскільки LBA є більш потужним, ніж КПК, LBA може імітувати КПК, використовуючи частину стрічки як стек, але він також може використовувати стрічку іншими способами.

(Якщо вам цікаво, що може розпізнати Кінцева державна машина, відповідь - це регулярні вирази. Але не регулярні вирази на стероїдах із групами захоплення та оглядом / випередженням, які ви бачите на програмних мовах; я маю на увазі ті, які ви можете створити з операторами , як [abc], |, *, +і ?. Ви можете бачити , що abbbzвідповідає регулярному виразу , ab*zпросто зберігаючи поточну позицію в рядку і регулярний вираз, не потрібно стек.)


14
Дуже приємне пояснення. Хоча стрічка машини Тюрінга не повинна бути нескінченною, а лише необмеженою. На будь-якому кінці може бути фабрика стрічок, яка, коли машина натикається на неї, просто робить більше стрічки. Таким чином, у будь-який момент часу це кінцево.
Майк Данлаве

2
@MikeDunlavey Дякую за роз’яснення, виправив його.
Doval

10
Але фабриці стрічки знадобляться нескінченні матеріали для виготовлення стрічок або нескінченні матеріали для виготовлення стрічок, або ... [переповнення стека]
flamingpenguin

8
@Mehrdad: Ви можете змоделювати будь-яку кількість стеків за допомогою двох стеків: тримайте всі стеки один над одним на одному стеку, і коли вам потрібно буде отримати доступ до деякого стека вниз, вискочіть верхні стеки і натисніть їх на другий стек. Це доводить, що n> 2 стеки не є більш потужними, ніж 2 стеки. Тепер, чи 2 стеки потужніші за 1 стек, я не знаю. Моя інтуїція говорить "ні", але це може залежати від того, які саме примітки є стеком.
Йорг W Міттаг

10
@ JörgWMittag: два стеки так само хороші, як і стрічка. Рукодільно: використовуйте одну пачку як ліву частину стрічки, а іншу - як праву частину, залежно від вашого поточного положення. Отже, 2-КПК - це машина Тюрінга. Для примітивів вам просто потрібно мати можливість виводити значення з однієї стеки та натискати на іншу, саме так ви рухаєтесь по стрічці.
Стів Джессоп

20

Інші відповіді досить довгі, навіть якщо точні та правильні. Це коротка версія.

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

Розглянемо наступні правила (малі регістри - термінали, великі регістри - нетермінали):

A -> a
AB -> a

У першому правилі ви можете замінити A незалежно від того, що з’являється навколо нього (контекст). У другому правилі ви не можете замінити, Aякщо це не дотримується B. Хоча в цьому випадку обидва нетермінали будуть замінені, важливим моментом є те, що нетермінали, що оточують Aсправу. Ніхто не може замінити BAз a, або Bз a: тільки Aза яким слід Bтому , що порядок, контекст з нетерміналом має важливе значення. Це означає, що контекст нетермінальних питань у другому правилі робить його контекстно-чутливим, тоді як перше правило є без контексту.


Це дійсно гарне пояснення, хоча я не кваліфікований, щоб поручити його точність або повноту. Це все є?
рик

1
Комп'ютерні граматики є частиною ієрархії Хомського . Ця стаття - гарне місце для початку. Крім того, ця тема повинна бути частиною будь-якої програми бакалавра з інформатики. Принаймні, університети повинні викладати регулярні та без контексту граматики, оскільки вони складають переважну більшість мов, на які ми, програмісти, стикаємось.

@Snowman: Дуже криптовалюта. Було б краще, якщо ви скажете, що "ви не можете вийти aз, ABякщо Aне супроводжується Bзамість того, щоб сказати" ви не можете замінити A", що може бути неможливим, оскільки насправді ви замінюєте ABне це?
Justin

@justin правильно. Я оновив свою відповідь, щоб бути більш зрозумілим щодо цього.

@Snowman: Ви маєте на увазі заміну Aчи ABдруге правило (залежне від контексту)? Я думаю, ви все ще намагаєтесь замінити, Aяк сказано у своїй відповіді.
Джастін

7

Щоб краще зрозуміти відмінність та термінологію, корисно порівнювати безконтекстну мову, як a n b n, та контекстно-чутливу, як a n b n c n . (Позначення: a, b і c - це буквалі тут, і показник n означає повторення буквального n разів, n > 0, скажімо.) Наприклад, aabbcабо aabbbccнемає в останній мові, тоді як aabbccє.

Акцептант для безконтекстної мови a n b n може взяти контракт на пару aі bнезалежно від того, що навколо неї (тобто незалежно від контексту, в якому з'являється ab), і він буде функціонувати правильно, приймаючи лише рядки в мові та відхиляючи будь-що інше, тобто граматика є S -> aSb | ab. Зауважте, що на лівій стороні виробів немає клем . (Існує два правила виробництва, але ми їх просто пишемо компактно.) Акцептор може в основному приймати місцеве, без контекстного рішення.

Навпаки, ви не можете зробити щось подібне для контекстно-чутливої ​​мови a n b n c n , тому що для останнього ви повинні якось запам’ятати контекст, в якому ви знаходилися, тобто скільки скорочень ab ви зробите, щоб їх співставити зі скороченнями до н.е. Граматика для останньої мови є

S -> abc | aBSc
Ba -> aB
Bb -> bb

Зауважте, що в останніх двох правилах зліва ви маєте і термінали, і нетермінали. Термінали зліва - це контекст, в якому нетермінали можна розширити.


Основна записка щодо термінології "контракт" проти "розширення" тощо. Хоча формальні граматики [формально, так] генеративні, спосіб їх реальної реалізації в парсерах насправді є редукціоністським, тобто ви звертаєтесь все до нетермінальних, в основному застосовуючи правила "в зворотному порядку", тому навіть перша граматика, наведена вище, не є практичною в програмі (це дасть вам знаменитий конфлікт зменшення зрушення, оскільки ви не можете вирішити, яке правило застосувати), але вищевказані два граматики достатньо для того, щоб проілюструвати відмінність між контекстом і контекстом. Питання про неоднозначність у безконтекстних граматиках є досить складним, і це насправді не тема цього питання, тому я не збираюсь тут більше говорити, тим більше, що, як виявляється, у Вікіпедії є гідна стаття про це. На відміну від його статей про без контексту, а особливо про контекстно-залежну мову, є @ @ $ $!


5

Наведені вище відповіді дають досить хороше визначення того, що це таке. Подивимось, чи можу я сказати це своїми словами, щоб у вас було 23 пояснення замість 20. Вся мета граматики, будь-яка граматика, - з’ясувати, чи певне речення є реченням на даній мові. Однак, для чого ми насправді використовуємо граматики та синтаксичний аналіз, - це з'ясувати, що означає речення. Це як старе діаграмування речення, яке ви, можливо, не робили ще в класі англійської мови ще в школі. Речення складається з предметної частини та присудкової частини, підметна частина має іменник і, можливо, деякі прикметники, присудна частина має дієслово і, можливо, предметний іменник, ще з деякими прикметниками тощо.

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

Sentence -> SubjectPart PredicatePart
SubjectPart -> Adjective Noun

тощо ...

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

Якщо в кожному виробництві є лише одне з лівого боку, то це означає, що щоразу, коли ви бачите праву сторону в реченні, вам дозволяється підставляти ліву частину. Наприклад, кожного разу, коли ви бачили прикметниковий іменник, ви можете сказати "That is SubjectPart", не звертаючи уваги на що-небудь поза цією фразою.

Однак англійська мова (навіть спрощений опис англійської мови, яку я дала вище), є залежною від контексту. "Іменник-прикметник" не завжди є SubjectPart, це може бути NounPhrase в PredicatePart. Це залежить від контексту. Давайте трохи розширимо нашу псевдо-англійську граматику:

Sentence -> SubjectPart PredicatePart
SubjectPart -> Adjective Noun
PredicatePart -> VerbPhrase ObjectNounPhrase
VerbPhrase ObjectNounPhrase -> VerbPhrase Adjective Noun

Ви можете зробити "прикметниковий іменник" в ObjectNounPhrase лише в тому випадку, якщо він приходить одразу після VerbPhrase.

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

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

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

Що стосується того, чому це важливо, для розбору контексту без граматики потрібна більш проста програма. Як зазначається в інших відповідях, для розбору контексту без граматики не потрібна вся потужність машини Тьюрінга. Аналізатор LR (1) пошуку (який є своєрідною машиною віджимання) для певної без контекстної граматики може аналізувати будь-яке речення в цій граматиці в часі та просторі, лінійних до довжини речення. Якщо речення є мовою, аналізатор створить дерево структури, що визначає, що означає кожен символ у реченні (або принаймні, яку роль він відіграє у структурі). Якщо речення відсутнє в граматиці, аналізатор помітить і зупиниться на першому символі, який неможливо узгодити з граматикою та попередніми символами (на першій "помилці").

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

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

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

Зазвичай ми не використовуємо контекстно-залежні граматики, оскільки вони значно слабкіше підтримуються. Я не знаю, чи існує еквівалент LR (k) аналізатор аналізатора для контекстно-чутливих мов. Так, машина Тьюрінга (або лінійно прив'язана машина) може проаналізувати її, але я не знаю, чи існує загальний алгоритм перетворення контекстно-чутливої ​​граматики в програму для машини Тьюрінга в сенсі, що LR (1 ) генератор робить розбір таблиць для машини, що висувається. Я здогадуюсь, що таблиці, які лежать в основі аналізатора, були б експоненціально більшими. У будь-якому випадку, студентів з КС (як я, у той же час), як правило, викладають без контексту граматики та генератори парсерів LR (1), такі як YACC.


-1

Граматики без контексту не враховують жодного контексту для виробничих правил. Контекст - це або термінали, або нетермінали.

Отже: Граматики без контексту мають лише один нетермінальний лівий бік правил виробництва.


3
Що це додає до існуючих відповідей? Крім того, виробниче правило з двома або більше нетерміналами з лівого боку також не є контекстним.

Я думаю, що наведені відповіді дуже довгі. Якщо ви додасте TL; DR, я б видалив цю.
Мартін Тома

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