Cours 6 : Partie avant d’un compilateur

Partie avant d’un compilateur

%3 AL Analyse lexicale (Lex) : expr. rat. AS Analyse syntaxique (Yacc) : gramm. alg. AL->AS 𝛴^* ASem Analyse sémantique : optimisation/interprétation/prod. de code AS->ASem Abres de syntaxe Programme Programme (alphabet UTF8/ASCII) Programme->AL

On veut générer des analyseurs syntaxiques qui sont des automates à pile déterministes pour une exécution en temps linéaire.

  • Lex : générateur d’analyseurs lexicaux
  • Yacc : générateurs d’analyseurs syntaxiques ⟶ donne un AST

Construction d’un automate à pile à partir d’une grammaire

  • q,A𝜀q,𝛼R pour A𝛼P (guess)
  • q,aaq,𝜀 pour a𝛴 (check)

Cet automate est déterministe ssi AN, il existe au plus une règle A𝛼P

i.e la classe LL(0) de langages associés est :

  • soit les singletons sur 𝛴
  • soit le vide

NB : problème : on ne peut donc reconnaître qu’un programme au plus, il nous faut donc étendre un peu la définition

Automate à k-fenêtres :

q,zu,aq,𝛾

  • u𝛴k,a𝛴𝜀,q,qQ,z𝛤,𝛾𝛤
  • NB : on peut, sans perte de généralité, supposer u𝛴k quitte à compléter avec des EOF à la fin du fichier
  • u est notre fenêtre de lecture (de k lettres) ⟶ on ne touche pas à u (à part sa première lettre), a le symbole couramment lu (première lettre de u) _____

Sémantique :

q,𝛾z,uwaq,𝛾𝛾,w si (q,z,u,a,q,𝛾)𝛿 tq uw=aw

On accepte dans une configuration (q,𝜀,^k)$ :

N(𝒜){w𝛴(q0,z0,w$k)𝒜w(q,𝜀,$k) pour qQ}

Syntaxe :

𝒜=(Q,𝛤,𝛴,𝛿,q0,z0)

mais 𝛿Q×𝛤×𝛴k×(𝛴{𝜀})×Q×𝛤 fini


Déterministe si q,z,uQ×𝛤×𝛴k :

  • soit il existe une seule transitions q,zu,𝜀q,𝛾
  • soit il n’y en a pas et alors a𝛴, il existe au plus une transition q,zu,aq,𝛾

Soit un automate à pile à k fenêtres. On peut construire un automate équivalent (avec N(𝒜)^k = L(𝒜’))quideplusestdét.si𝒜$ l’est.

Preuve :

𝒜Q,𝛤,𝛴,𝛿,q0,z0,F
  • QQ×𝛴k{qf}
  • F{qf}
  • 𝛤=𝛤{}
  • 𝛿{((q,u),z,a,(q,ua),z)qQ,z𝛤,|u|<k,a𝛴}{((q,u),z,𝜀,(q,u),𝛾)(q,z,u,a,q,𝛾)𝛿,u=au,|u|=k}{((q,$k),,𝜀,qf,𝜀)qQ}

Réciproque :

Premiers et suivants

Premk(𝛼){k:wpréfixe maximal de longueur k de w𝛼lmGw}

Pour AN :

Suivk(A){Premk(𝛾)SlmGuA𝛾}={k:vpréfixe de longueur k de vSG𝜃Av}

Ex :

Premk(A)=A𝛼PPremk(𝛼)Prem(𝛼𝛽)={k:wwwPremk(𝛼),wPremk(𝛽)}Premk(a𝛴)={a si k>0𝜀 sinonPremk(𝜀)={𝜀} Suivk(A)=B𝛼A𝛽B{k:wwwPremk(𝛽),wSuivk(B)}{𝜀A=S}

Ex :

SE$EE+TTTTFFF(E)i
N Prem_1 Suiv_1
E (, i $, ), +
T (, i *, $, ), +
F (, i *, $, ), +
La k-fenêtre de A𝛼 est :
LAk(A𝛼)Premk(𝛼Suivk(A))

Grammaire alg. G fortement LL(k) :

si A𝛼1A𝛼2P, LAk(A𝛼1)LAk(A𝛼2)=

Th : Si G est fortement LL(k) alors son automate guess/check à k-fenêtres est déterministe.

Ex :

Dans l’exemple précédent, la grammaire n’est pas fortement LL(1) :

LA1(EE+T)={(,i}LA1(ET)={(,i}

Comment changer la grammaire pour que ce soit le cas ?

SE$ETEE𝜀+TETFTT𝜀FTF(E)i
N Prem_1 Suiv_1
E (, i $, )
E’ 𝜀, + $, )
T (, i +, ), $
T’ 𝜀, * +, ), $
F (, i *, +, ), $

Maintenant :

LA1(E𝜀)={$,)}LA1(E+TE)={+}LA1(T𝜀)={+,),$}LA1(TFT)={}

Analyseur récursif descendant

Exemple :

fonction E : 𝛴ww suffixe de w

w = T(w)
return E'(w)

fonction T : 𝛴ww suffixe de w

w = F(w)
return T'(w)

fonction F : 𝛴ww suffixe de w

if w == (w':
  w = E(w')
  if w == )w':
    return w'

if w == iw':
  return w'

fonction E : 𝛴ww suffixe de w

if w == 𝜀 or w == )w':
  return w
  if w == +w':
    w = T(w')
    return E'(w)

Une grammaire est LL(k) :

si SlmGuA𝛿 et A𝛼1A𝛼2P :

Premk(𝛼1𝛿)Premk(𝛼2𝛿)=

Prop : Si G est fortement LL(k), alors elle est LL(k)

L’inverse est faux : il existe des grammaires LL(2) qui ne sont fortement LL(k) pour aucun k.

Prop : Si G est LL(1) alors elle est fortement LL(1)

Prop : Si G est LL(k), alors elle n’est pas ambiguë

Prop : Si G est LL(k), alors elle n’est pas récursive à gauche

Hiérarchies LL(k)

Langages algébriques

Langages non ambigus

Langages déterministes

LL(k) = fortement LL(k)

LL(1) = fortement LL(1)

Langages rationnels

LL(0) (singleton ou vide)


Grammaires :

%11 GA Grammaires algébriques GNA Grammaires non ambiguës GA->GNA LD Grammaires déterministes GNA->LD LLk LL(k) LD->LLk fLLk fortement LL(k) LLk->fLLk LLk1 LL(k-1) LLk->LLk1 fLLk1 fortement LL(k-1) fLLk->fLLk1 LL1 LL(1) = fortement LL(1) fLLk1->LL1 LLk1->fLLk1 LLk1->LL1 LL0 LL(0) : au plus une règle par non terminal LL1->LL0

Prop : Soit G LL(k). On peut construire une grammaire équivalente fortement LL(k).

Leave a comment