Algorithme utilisé:
$)a est l'élément courant de la chaine.
Initialement, pointeur sur premier élément de la chaine et la pile contient $ et S (S se trouve au sommet de la pile).
A chaque itération, on examine l'élément X au somment de la pile et l'élément courant de la chaine:
a==$ alors terminer avec succèsa!=$ alors on dépile X et on avance le pointeura] = {X→ y1y2…yn} alors on dépile X est on empile yn…y2y1.a] = \emptyset alors terminer avec erreurExemple: arithmétique dérécursivée G0' obtenu en supprimant la récursivité de G0:
| E → TE' |
| E' → +TE' | e |
| T → FT' |
| T' → *FT' | e |
| F → (E) | id |
| id | + | * | ( | ) | $ | |
|---|---|---|---|---|---|---|
| E | E→TE' | E→TE' | ||||
| E' | E'→+TE' | E'→e | E'→e | |||
| T | T→FT' | T→FT' | ||||
| T' | T'→e | T'→*FT' | T'→e | T'→e | ||
| F | F→id | F→(E) |
Exemple : déroulons l'algorithme avec cette table pour la chaine id + id * id :
| Pile | Chaine | Remarques |
|---|---|---|
| $ E | id + id * id $ | Démarrage |
| $ E' T | id + id * id $ | Règle E→TE' empilé |
| $ E' T' F | id + id * id $ | Règle T→FT' empilé |
| $ E' T' id | id + id * id $ | Règle F→id empilé |
| $ E' T' | + id * id $ | traitement du terminal, passage au token suivant |
| $ E' | + id * id $ | règle T' → e |
| $ E' T + | + id * id $ | règle E' → +TE' empilé |
| $ E' T | id * id $ | traitement du terminal +, passage au token suivant |
| $ E' T' F | id * id $ | règle T' → FT' |
| $ E' T' id | id * id $ | règle F→id |
| $ E' T' | * id $ | traitement du terminal id, passage au token suivant |
| $ E' T' F * | * id $ | règle T'→*FT' |
| $ E' T' F | id $ | règle F→ id |
| $ E' T' id | id $ | traitement du terminal *, passage au token suivant |
| $ E' T' | $ | règle T' → e |
| $ E' | $ | règle E' → e |
| $ | $ | terminer avec succès |
La table d'analyse peut être remplie en utilisant deux fonctions associées à la grammaire: FIRST et FOLLOW.
Alors, on définit:
Plus formellement, pour une grammaire \left(\Sigma, V, R, S\right) où \Sigma est l'ensemble des terminaux, V l'ensemble des non-terminaux, R les règles et S l'axiome (les axiomes?)
Pour construire la table d'analyse avec FIRST et FOLLOW, l'idée est que pour toute règle de grammaire A \rightarrow \alpha, si \alpha\in FIRST(A) alors on va utiliser cette règle pour développer A par \alpha quand le token courant dans la chaine est \alpha. Une complication arrive lorsque \alpha = \epsilon ou bien \alpha \Rightarrow^* \epsilon; dans ce cas, on doit également développer A par \alpha si le token courant dans la chaine est un élément de FOLLOW(A).
| FIRST(F) | ={ | (, id | } |
| FIRST(T') | ={ | *, e | } |
| FIRST(T)=FIRST(F) | ={ | (, id | } |
| FIRST(E') | ={ | +, e | } |
| FIRST(E)=FIRST(T) | ={ | (, id | } |
Pour calculer FOLLOW
$ dans FOLLOW(S)Exemple :
| id | + | * | ( | ) | $ | |
| E | E→TE' | E→TE' | ||||
| E' | E'→+TE' | E'→ | E'→ | |||
| T | T→FT' | T→FT' | ||||
| T' | T'→ | T→*FT' | T'→ | T'→ | ||
| F | F→id | F→(E) |
il faudrait vérifier cette table, je ne suis pas certain de l'avoir bien notée.
N.B. Si chaque case de la table contient au plus une règle on dit la grammaire non-ambiguë. Elle est dite LL(1). Explication:
Si une case de la table contient plusieurs règles la grammaire est ambiguë : il y a plusieurs arbres de syntaxe possibles pour certaines production de la grammaire.