Expressions préfixées



next up previous contents index
Next: Analyse ascendante Up: Analyse LL Previous: Analyse LL

Expressions préfixées

Nous considérons la grammaire de ces expressions:

, , l'axiome est , les règles sont données par:

Pour un mot de , il est immédiat de déterminer tel que

En effet, si est de longueur , ou bien et le résultat de l'analyse syntaxique se limite à , ou bien n'appartient pas au langage engendré par la grammaire.

Si est de longueur supérieure à , il suffit de connaître les deux premières lettres de pour pouvoir retrouver . Si ces deux premières lettres sont , c'est la règle qui a été appliquée, si ces deux lettres sont alors c'est la règle . Tout autre début de règle conduit à un message d'erreur.

Ce qui vient d'être dit pour retrouver en utilisant les deux premières lettres de se généralise sans difficulté à la détermination du mot de la dérivation à partir de . On décompose d'abord et en:

et on procède en fonction des deux premières lettres de .

Cet algorithme reprend les grandes lignes de la descente récursive avec une différence importante: la boucle while qui consistait à appliquer chacune des règles de la grammaire est remplacée par un examen de certaines lettres du mot à analyser, examen qui permet de conclure sans retour arrière. On passe ainsi d'une complexité exponentielle à un algorithme en . En effet, une manière efficace de procéder consiste à utiliser une pile pour gérer le mot qui vient de la décomposition . La consultation de la valeur en tête de la pile et sa comparaison avec la lettre courante de permet de décider de la règle à appliquer. L'application d'une règle consiste alors à supprimer la tête de la pile (membre gauche de la règle) et à y ajouter le mot formant le membre droit en commençant par la dernière lettre.

Nous avons appliqué cette technique pour construire l'arbre de syntaxe abstraite associé à une expression préfixée. Dans ce qui suit, le mot à analyser est une variable globale de même que la variable entière pos qui indique la position à laquelle on se trouve dans ce mot.

 

function ArbSyntPref: Arbre;
    var a, b, c: Arbre;
        x: char;

    begin
    if f[pos] = 'a' then 
        begin
        a := NouvelArbre('a', nil, nil);
        pos := pos + 1;
        end
    else if (f[pos] = '(') and (f[pos+1] in {'+', '*'}) then
        begin
        x := f[pos + 1];
        pos := pos + 2;
        b := ArbSyntPref;
        c := ArbSyntPref;
        a := NouvelArbre(x, b, c);
        if f[pos] = ')' then pos := pos + 1
             else Erreur(pos);
        end
    else 
        Erreur(pos);
    ArbSyntPref := a
    end;

L'algorithme d'analyse syntaxique donné ici peut s'étendre à toute grammaire dans laquelle pour chaque couple de règles et , les mots qui dérivent de et n'ont pas des facteurs gauches égaux de longueur arbitraire. Ou de manière plus précise, il existe un entier tel que tout facteur gauche de longueur appartenant à d'un mot qui dérive de est différent de celui de tout mot qui dérive de . On dit alors que la grammaire est et on peut alors démontrer:

En fait, cet algorithme est surtout utile pour . Nous donnons ici ses grandes lignes sous forme d'un programme Pascal qui utilise une fonction Predicteur calculée au préalable. Pour un élément de et un mot de longueur , cette fonction indique le numéro de l'unique règle telle que se dérive en un mot commençant par ou qui indique Omega si aucune telle règle n'existe. Dans l'algorithme qui suit, on utilise une pile comme variable globale. Elle contient la partie du mot qui doit engendrer ce qui reste à lire dans . Nous en donnons ici une forme abrégée.

 

 
function Analyse(f: Mot; pos: integer): boolean;
    var i: integer;

    begin
    pos := 1;
    while Pvaleur(p) = f[pos] do
        begin
        Psupprimer(p);
        pos := pos + 1;
        end;
    if Pvide(p) and f[pos] = '$' then
        Analyse := true
    else
        begin
        y := Pvaleur(p);
        if not Auxiliaire(y) then
           Analyse := false 
        else 
           begin
           i := Predicteur (y, pos, pos+k-1);
           if i <> Omega then
                begin
                writeln (y, '->', regle[y,i]);
                Pinserer(regle[y,i], p);
                Analyse := Analyse (f, pos);
                end
            else
                Analyse := false;
                    
    end;



next up previous contents index
Next: Analyse ascendante Up: Analyse LL Previous: Analyse LL