Знайдіть наступні набори


14

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

Я можу порекомендувати цей курс по Стенфорду , зокрема роздатковий матеріал 08 та 09 (зі сторінки 7). Я також видобув шпаргалку з цих роздаткових матеріалів - я рекомендую кожному, хто спробує цю проблему, прочитати її .


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

Вхід подається у вигляді одного друкованого рядка ASCII або масиву друкованих рядків ASCII. Ви можете виводити набори в будь-якому розумному форматі, використовуючи $(як буквальний вихід, або рядок всередині набору тощо) для позначення кінця введення. Ви можете припустити, що вхід завжди дійсний відповідно до наведеного нижче формату.

Контекстна вільна граматика подається дуже спрощеним чином. Кожен рядок містить одну продукцію. Кожне виробництво - це розділений пробілом список символів. Термінал - це рядок символів, оточений апострофами (наприклад '**'). Для простоти ви можете припустити, що термінали не містять пробілів, але було б добре, якщо ваша програма це дозволяє. Нетермінальним може бути будь-який рядок, що не містить пробілів або $. Порожня продукція (як правило, позначається ε) - це просто лінія, що містить лише нетермінальний лівий бік. Перший рядок - це виробництво, що визначає стартовий символ.

Як приклад, наступна граматика:

S → aSa | bSb | ε

Показується як:

S 'a' S 'a'
S 'b' S 'b'
S

Приклад входів / виходів:

In:
S 'a' S 'a'
S 'b' S 'b'
S

Out:
S {'a', 'b', $}

In:
S A B C
A 'a'
A C 'b'
A
B C
B 'd' A
B
C 'e'
C 'f' 

Out:
S {$}
A {'d', 'e', 'f'}
B {'e', 'f'}
C {'b', 'e', 'f', $}

In:
Start Alice Bob
Alice Charlie 'a'
Alice
Bob Bob 'a' Alice Charlie
Bob '!!!'
Charlie 'b'
Charlie

Out:
Start {$}
Alice {'a', '!!!', 'b', $}
Bob {'a', $}
Charlie {'a', $}

Виграє найкоротший код у байтах.


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

1
Це повертає деякі спогади з " Конструкції компілятора " в університеті, де нам довелося вирішити безліч подібних завдань.
вставтекористувач

Відповіді:


3

Perl, 257 байт

Включає +4 для -0p

Дайте граматику на STDIN (без пробілів. Обов'язково видаліть зайвий пробіл у другому прикладі). Припускає, що нетермінальні імена містять лише букви, цифри та _. Використовує #замість того, $щоб вказати кінець введення. Може обробляти літерали, що містять пробіли

perl -M5.010 follow.pl
E T e
e '+' T e
e
T F t
t '*' F t
t
F '(' E ')'
F 'id'
^D

Виводить наступні набори як список non-terminal literalу не конкретному порядку. Для наведеного вище прикладу виводиться:

F ')'
F #
t ')'
t #
T ')'
T #
F '+'
t '+'
T '+'
F '*'
e ')'
e #
E ')'
E #

follow.pl:

#!/usr/bin/perl -0n
s/'.*?'/~$&/eg;s% (?=(\w.*\n))%$_.=">$1"%reg;/\s/;$_.=">$` #\n";s%^((\w+)\K ?\S*).*%$s{$1}++||"\$a.=s/ $2\\b/$&/rg"%eemgr,s%^(\w+ ).*?(\w+)$%"\$a.=s/>$1/>$2 /rg"%eermg,$_.=$a,s%>.*\xd8\K .*%%g,s%.+\n%$&x!/\n$&/g%eg until$$_++;s/\xd8.*?\xd8/~$&/eg;say/>(\w+ \W\S*\n)/g

Працює як показано на малюнку, але замінити \xd8і \nїх буквального версії , щоб отримати заявлену рахунок.

Це повинно бути можливо покращити, оскільки перетворення firstнаборів у followмножини наразі дуже незручне.

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