Le risposte sopra danno una definizione abbastanza buona di ciò che è. Vediamo se riesco a metterlo con le mie parole, in modo che tu abbia 23 spiegazioni invece di 20. Lo scopo di una grammatica, qualsiasi grammatica, è di capire se una particolare frase è una frase in una determinata lingua. Tuttavia, ciò a cui veramente usiamo le grammatiche e l'analisi è capire cosa significa la frase. È come il vecchio schema di una frase che potresti aver fatto o meno in classe inglese a scuola. Una frase è composta da una parte soggetto e una parte predicato, una parte soggetto ha un sostantivo e forse alcuni aggettivi, una parte predicato ha un verbo e forse un nome oggetto, con alcuni aggettivi, ecc.
Se ci fosse una grammatica per l'inglese (e non penso che ci sia, non nel senso dell'informatica), avrebbe regole della forma seguente, chiamate produzioni.
Sentence -> SubjectPart PredicatePart
SubjectPart -> Adjective Noun
eccetera...
Potresti quindi scrivere un programma e consegnarlo a qualsiasi frase, e il programma potrebbe usare la grammatica per capire quale parte della frase è ogni parola e quale relazione hanno l'una con l'altra.
Se in ogni produzione c'è solo una cosa sul lato sinistro, ciò significa che ogni volta che vedi il lato destro nella frase, ti è permesso sostituire il lato sinistro. Ad esempio, ogni volta che vedevi un sostantivo aggettivo, potresti dire "That's a SubjectPart" senza prestare attenzione a nulla al di fuori di quella frase.
Tuttavia, l'inglese (anche la descrizione semplificata dell'inglese che ho dato sopra) è sensibile al contesto. "Aggettivo sostantivo" non è sempre un soggetto, potrebbe essere un NounPhrase in un PredicatePart. Dipende dal contesto. Espandiamo un po 'la nostra grammatica pseudo-inglese:
Sentence -> SubjectPart PredicatePart
SubjectPart -> Adjective Noun
PredicatePart -> VerbPhrase ObjectNounPhrase
VerbPhrase ObjectNounPhrase -> VerbPhrase Adjective Noun
Puoi creare un "sostantivo aggettivo" in un ObjectNounPhrase solo dopo un VerbPhrase.
Fondamentalmente, se hai una produzione e puoi applicarla ogni volta che vuoi, indipendentemente da ciò che la circonda, è senza contesto.
Puoi sempre dire se una grammatica è facilmente libera dal contesto. Controlla se c'è più di un simbolo sul lato sinistro delle frecce.
Qualsiasi lingua potrebbe essere descritta da più di una grammatica. Se un po 'di grammatica per una lingua è senza contesto, la lingua è senza contesto. Per alcune lingue può essere dimostrato che non esiste una grammatica libera dal contesto. Suppongo che potrebbe esserci una grammatica senza contesto per il sottoinsieme pseudo-inglese semplificato che sto descrivendo sopra.
Per quanto riguarda il perché è importante, richiede un tipo più semplice di programma per analizzare una grammatica senza contesto. Come notato nelle altre risposte, non richiede la piena potenza di una macchina Turing per analizzare una grammatica senza contesto. Un parser LR (1) lookahead (che è una sorta di pushdown machine) per una particolare grammatica senza contesto può analizzare qualsiasi frase in quella grammatica in tempo e spazio lineari rispetto alla lunghezza della frase. Se la frase è nella lingua, il parser produrrà una struttura ad albero che identifica cosa significa ogni simbolo nella frase (o almeno quale parte gioca nella struttura). Se la frase non è nella grammatica, il parser noterà e si fermerà sul primo simbolo che è impossibile riconciliare con la grammatica e i simboli precedenti (sul primo "errore").
La cosa ancora migliore è che ci sono programmi a cui puoi dare una descrizione di una grammatica e un elenco di istruzioni su cosa fare con ogni parte (in un certo senso allegando un "significato" a ogni produzione) e il programma scriverà il parser per te. Il programma analizzerà la frase, troverà la struttura ed eseguirà le istruzioni su ciascuna parte della struttura. Questo tipo di programma è chiamato parser-generator o compilatore-compilatore.
Questo tipo di analisi del linguaggio è stato inventato per l'analisi automatica del linguaggio naturale (come l'inglese), ma risulta che questo è molto utile per l'analisi dei linguaggi informatici. Un designer linguistico può scrivere una grammatica che acquisisce la sua nuova lingua, quindi eseguirla attraverso il generatore di parser per ottenere un programma che analizza la sua lingua e, se lo desidera, traduce, interpreta, compila, esegue, ecc.
In effetti, nella maggior parte dei casi non puoi davvero farlo. Ad esempio, le parentesi bilanciate sono un linguaggio privo di contesto, ma una lingua in cui è necessario dichiarare tutte le variabili prima di utilizzarle è sensibile al contesto. Il parser fa parte del compilatore, ma per applicare questi altri requisiti è necessaria una logica aggiuntiva. Quello che devi fare è scrivere una grammatica che acquisisca la maggior parte della tua lingua possibile, eseguirla attraverso un generatore di parser, quindi scrivere un codice che imponga il resto dei requisiti (gestore della tabella dei simboli, ecc.).
Generalmente non usiamo grammatiche sensibili al contesto perché sono molto più scarsamente supportate. Non so se esiste un equivalente a un generatore di parser LR (k) per linguaggi sensibili al contesto. Sì, una macchina di Turing (o macchina a limite lineare) può analizzarne una, ma non so se esiste un algoritmo generale per trasformare una grammatica sensibile al contesto in un programma per una macchina di Turing, nel senso che un LR (1 ) Il generatore crea tabelle di analisi per una macchina pushdown. La mia ipotesi è che le tabelle che stanno alla base del parser sarebbero esponenzialmente più grandi. In ogni caso, agli studenti CS (come me, nel passato) di solito vengono insegnate grammatiche senza contesto e generatori di parser LR (1) come YACC.