La sfida di seguito richiede di avere familiarità con la teoria formale del parser. Se non sai quale sia la domanda, perché non sai cosa significano i termini, in molti corsi universitari vengono trattati grammatiche senza contesto e insiemi di primo / seguito.
Posso consigliare questo corso a Stanford , in particolare le dispense 08 e 09 (da pagina 7). Ho estratto anche un cheat sheet da questi volantini - consiglio a chiunque stia tentando questa sfida di leggerlo .
Scrivi un programma o una funzione che, data una grammatica libera dal contesto, trovi il seguente insieme di ogni non terminale. Informalmente, il seguente insieme di un non terminale è un insieme di terminali e $
(che significa fine dell'input) che è possibile trovare dopo quel terminale in una frase valida.
L'input è dato come una singola stringa ASCII stampabile o matrice di linee ASCII stampabili. È possibile produrre gli insiemi in qualsiasi formato ragionevole, usando $
(come output letterale o stringa all'interno di un insieme, ecc.) Per indicare la fine dell'input. Si può presumere che l'input sia sempre valido secondo il formato seguente.
La grammatica libera dal contesto è data in modo molto semplificato. Ogni linea contiene una singola produzione. Ogni produzione è un elenco di simboli separato da spazi. Un terminale è una stringa di caratteri circondata da apostrofi (ad es '**'
.). Per semplicità puoi supporre che i terminali non contengano spazi, ma sarebbe bello se il tuo programma lo consentisse. Un non terminale può essere qualsiasi stringa che non contiene spazi o $
. La produzione vuota (normalmente indicata con ε) è semplicemente una linea che contiene solo il lato sinistro non terminale. La prima riga è la produzione che definisce il simbolo iniziale.
Ad esempio, la seguente grammatica:
S → aSa | bSb | ε
Sarà dato come:
S 'a' S 'a'
S 'b' S 'b'
S
Esempi di input / output:
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', $}
Vince il codice più breve in byte.