Analisi sintattica (linguaggi formali)

Da testwiki.
Vai alla navigazione Vai alla ricerca

Template:S

Template:Risorsa

In questa lezione introdurremo gli analizzatori di sintassi o parser, cioè gli algoritmi che analizzano una stringa e generano il suo albero di sintassi secondo un dato linguaggio. Se la stringa non appartiene al linguaggio il parser deve accorgersene e segnalare l'evento.

Parser

Più formalmente, data una grammatica G un analizzatore di sintassi o parser deve leggere una stringa sorgente x e:

  • se xL(G): accettare la stringa e produrre un albero di sintassi o una derivazione;
  • se xL(G): rifiutare la stringa e segnalare l'errore.
  • se x è una proposizione ambigua della grammatica G, il parser deve segnalare il problema (alcuni parser generano tutti i possibili alberi di sintassi, altri segnalano solo un errore)

Questo componente è solitamente il primo step dell'esecuzione di un compilatore dopo lo scanner.

Distinguiamo principalmente due approcci alla scrittura di un algoritmo di parsing:

  • Bottom-Up: costruisce l'albero per riduzioni a partire dalle foglie fino alla radice (derivazioni a sinistra);
  • Top-Down: costruisce l'albero per espansioni a partire dalla radice fino alle foglie (derivazioni a destra);

Grammatiche come reti di automi a stati finiti

Quando le grammatiche libere dal contesto rappresentano algoritmi di parsing, risulta molto utile trasformarle in reti di automi a stati finiti o rete di macchine a stati finiti(termine generalmente usato in inglese net of finite machines); questo porta a numerosi vantaggi che verranno presentati più avanti nella lezione.

Definiamo ora in maniera sufficientemente formale le reti di automi a stati finiti, aggiungendo anche altre definizioni necessarie:

  • come solito, sia Σ l'alfabeto terminale, V il non-terminale e SV l'assioma della grammatica G;
  • per ogni terminale esiste una regola Aα e α è una RE sull'alfabeto ΣV; indichiamo il linguaggio generato da queste RE con i simboli RS,RA,... rispettivamente dalla RE della regola di S, di A e così via...
  • i simboli MS,MA,... rappresentano le macchine a stati finiti che accettano i linguaggi rispettivamente RS,RA,...
  • per evitare confusione, ogni macchina possiede stati con nomi diversi. In particolare alla macchina MS saranno assegnati gli stati 0S,1S,..., alla macchina MA gli stati 0A,1A,... e così via, in modo da mantenere gli stati tra le macchine ben disgiunti;
  • definiamo inoltre R(MX,q) il linguaggio generato dalla macchina MX se lo stato iniziale è imposto essere un certo stato q; ovviamente se lo stato è il consueto stato iniziale risulta R(MX,q0)=RX;
  • l'insieme di tutte le macchine MS,MA,... è detto rete di macchine a stati finiti e si indica con M.

Viste le regole qui sopra deifnite, il linguaggio generato dalla rete di macchine a stati finiti è lo stesso della grammatica L(M)=L(G).

Visto che i linguaggi R(MX,q) (e anche RX) potrebbe contenere simboli non terminali, definiamo il linguaggio terminale generato da una macchina della rete a partire da un certo stato:

L(MX,q)= { yΣ* | ηR(MX,q)η * y }

Si noti che essendo S l'assioma:

L(MS,q0,S)=L(M)=L(G)

Esempio

Data la seguente grammatica:

S  E ';'(E ';')*
E  V'='C
C  [+|] ('1'|'2'|'3'|...)+
V  ('a'|'b'|'c'|...)2('a'|'b'|'c'|...)*

Possiamo costruire la relativa rete:

Bottom-up LR (k)

Top-down LL (k)

In questa sezione presentiamo l'algoritmo di parsing top-down LL (K)[1]. Il "parametro" k indica la lunghezza in caratteri di quanto l'algoritmo può "guardare avanti" (questo concetto sarà ripreso più avanti).

Analisi sintattica di grammatiche non deterministiche - Metodo Early

Note

  1. LL è acronimo di Left-to-right e Leftmost.