З огляду на рядок та CFG, які символи можуть слідувати за рядком (у сентенційних формах CFG)?


10

Нехай безліч термінального та безлічі нетермінальних символів деякої контекстно-вільна граматика .N GΣNG

Скажіть, у мене є рядок така, що де та , є сентенціальной формами . x a y S ( G ) x , y ( Σ N ) S ( G ) Ga(ΣN)+xayS(G)x,y(ΣN)S(G)G

Дано , я хотів би визначити набір .C = { b w a b z S ( G ) , b Σ N }GC={bwabzS(G),bΣN}

Для уточнення в цьому випадку це рядки терміналів і нетерміналів, а - довжина одна.bw,x,y,z,a,bb

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

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

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


1
Яка ваша заявка? Ви будуєте аналізатор?
Рафаель

Чи можемо ми припустити, що граматика є в будь-якій нормальній формі або вона повинна працювати для довільних?
Рафаель

@AlextenBrink - і - довільні рядки. Я просто дивлюся на фрагмент / підрядку. уху
Томас

@Raphael - Я намагаюся автоматизувати перетворення граматик L-System ... так що це не в нормальній формі. Насправді я ще раз відредагую це питання, щоб зробити його більш точним.
Томас

Я сподіваюся, що я не надто змінив питання - воно має трохи інший характер.
Томас

Відповіді:


6

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

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

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

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

Для ініціалізації, ми насіння нашого першого набору з елементом Ерелі для кожного входження (перший символ в ) в будь-якому виробництві вашої граматики. Встановлюємо задній покажчик цього елемента на -1, недійсне значення. Це важливо при нашому модифікованому завершенні. По суті, -1 означає «я не знаю, звідки було розпочато це виробництво». aа1а

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

Для кроку завершення нам залишається лише внести модифікацію для обробки -1 задніх покажчиків. Коли ми закінчили виробництво, походження якого ми не знаємо, ми потрапили в біду. Тим НЕ менше, метод , який використовується для обчислення Набори щодоLАLR(1) подальшого по Pennello і DeRemer рятує нас: то , що нам тут потрібно саме те Набори щодо подальшого . Кожен предмет у цих наборах пошуку шукає відповідне положення у граматиці, що в свою чергу відповідає можливому продовженню завершеного виробництва. L A L R ( 1 )LАLR(1)

На жаль, я дійсно не бачу іншого вибору, ніж знову відкликатись тут. Для кожної позиції в наборі пошуку, ви виконуєте етап завершення з цим положенням і продовжуєте розбір звідти. Ви робите це окремо для кожного розбору. Зауважте, що якщо ваша граматика , ваш lookahead однозначно визначить, в яку позицію ви повинні піти, тому вам не доведеться відступати.LАLR(1)

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

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

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

Комплектувач розглядає ідентифікатори окремо і завершує елемент лише у тому випадку, якщо відповідний елемент у попередньому наборі елементів має ідентифікатор, який є префіксом ідентифікатора. Для кожного можливого завершення (так для кожного елемента в наборі пошуку ) ми додаємо унікальний символ до ідентифікаторів завершених елементів.LАLR(1)

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


аа

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

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