Telechargé par Jeremie Lassey

PARTIE 2 - analyse syntaxique - RAPPORT

publicité
LANGAGE C-L’analyse Syntaxique
Encadré par :
-
Pr ELGHAZI Souhail
Groupe de travail :
-
Assafi Issam
Settai Yassine
Jazouli Othmane
Zouaid Omar
I.
Introduction
Dans la phase de l’analyse syntaxique, on cherche à dire si un texte source appartient à un langage
donné, c’est-à-dire s’il respecte la grammaire de langage.
L’analyse syntaxique consiste à expliciter la structure du programme sous forme d'un arbre, appelé
arbre de syntaxe, chaque nœud de cet arbre correspond à un opérateur et ses fils aux opérandes
sur lesquels il agit.
II. La grammaire du langage C-La première règle est OK, vu que c’est un seul choix.
La deuxième règle : <liste-declarations> :<liste-declarations> <declaration> | epsilon est récursive à
gauche, après élimination de la récursivité, on a deux nouvelle règles :
-
<liste-declarations> : <liste-declarations’> qui est OK
-
<liste-declarations’> : <declaration><liste-declarations’> | epsilon qui n’est pas de tout LL(1),
vu que INT appartient à Premier(<liste-declarations>’ ) et à Suivant(<liste-declarations>’ )
La solution qu’on a abordé est de reformuler l’ensemble des première règles afin de former une
grammaire déterministe.

Grammaire finale
R1) <Programme> : < int-declarateurs> < liste-fonctions’>
R2) < int-declarateurs> : int identificateur <declaration> | epsilon
R3) <declaration> : <liste-declarateurs> ; < int-dectarateurs> | <fonction> <liste-fonctions>
R4) <liste-declarateurs> : <declarateur> <liste-declarateurs’>
R5) <liste-declarateurs’> : , <declarateur> <liste-declarateurs’> | epsilon
R6) <declarateur> : [constante] <declarateur’> | epsilon
R7) <declarateur’> : [constante] | epsilon
R8) <fonction> : ( <liste-parms> ) { <liste-declarations> < liste-instructions>}
R9) <prototype> : extern <type> identificateur ( <liste-parms> ) ;
R10) <type> : void I int
R11) <liste-fonctions> : int identificateur <fonction> <liste-fonctions> | <liste-fonctions’> | epsilon
R12) <liste-fonctions’> : void identificateur <fonction> <liste-fonctions> |<prototype> <listefonctions>
<liste-parms> : <liste-parms’>
<liste-parms’> : , <parm> <liste-parms’>
<parm> : int identificateur
<liste-instructions> : <liste-instructions'>
<liste-instructions'> : < instructions ><liste-instructions’>| epsilon
<instruction> : identificateur<instruction’>| <iteration> I <selection> | <saut> | <bloc>
<instruction’> : ( <liste-expressions> ) ; | <variable’> = <expression>
<iteration> : for ( < affectation> ; <condition> ; <affectation> ) <instruction> | while( <condition> )
<instruction>
<selection> :if ( <condition> ) <instruction><selection’>
<selection’> :else<instruction> | epsilon
<saut> :return <saut’>
<saut’> : ; |<expression>;
<affecation> : <variable> = <expression>
<bloc> : { <liste-expressions>}
<appel> : identificateur ( <liste-expressions> ) ;
<variable> : identificateur <variable’>
<variable’> :[<expression>] <variable’'> |epsilon
<variable’'> :[<expression>] | epsilon
<bloc> : { <liste-instructions> }
<expression> : ( <expression> ) <expression’> | -<expression><expression’> | identificateur
<expression’’> | <constante> <expression’>
<expression’’> : <variable’> <expression’> | (<liste-expressions>) <expression’>
<expression’> : <binary-op> <expression><expression’> | episolon
<liste-expressions> : <liste-expressions’>
<liste-expressions’> : , <expression> <liste-expressions’>| epsilon
<condition> : !(<condition>) <condition’> | (<condition >) <condition’> |
<expression><binary-comp><expression><condition’>
<condition’> : <condition><binary-rel><condition’> | epsilon

Justifications/Explications
Règle 1 :
<Programme> : < int-declarateurs> < liste-fonctions’>
La règle 1 est bonne car il ne présente qu’un seul choix.
Règle 2 :
< int-declarateurs> : int identificateur <declaration> | epsilon
On a premier(int identificateur <declaration>) ∩ { epsilon } = ∅ .
D’autre part, int identificateur <declaration> est non annulable avec premier(< int-declarateurs>) =
{int, epsilon} et suivant(< int-declarateurs>) = {void, extern}
d’où premier(< int-declarateurs>) ∩ suivant(< int-declarateurs>) = ∅.
Alors la règle 2 est bonne.
Règle 3 :
On a premier(<liste-declarateurs>) = { ‘[‘ , ‘,’ } et premier(<fonction>)= { ‘(‘ } et donc premier(<listedeclarateurs>) ∩ premier(<fonction>)∅.
Et comme les deux sont non annulables alors le règle 3 est bonne.
Règle 4:
<liste-declarateurs> : <declarateur> <liste-declarateurs’>
La règle 4 est bonne car il représente qu’un seul choix.
Règle 5:
<liste-declarateurs’> : , <declarateur> <liste-declarateurs’> | epsilon
On l’intersection des premiers des deux sous-règles de <liste-declarateurs’> est l’ensemble vide ; et
comme une seule est non annulable, on a :
Premier(<liste-declarateurs’>) = {‘,’, epsilon} et
suivant(<liste-declarateurs’>) = {void, extern} d’où l’intersection est l’ensemble vide.
Alors la règle 5 est bonne.
Règle 6:
On l’intersection des premiers des deux sous-règles de <liste-declarateurs’> est l’ensemble vide ; et
comme une seule est non annulable, on a :
Premier(<declarateur>) = {‘[’, epsilon} et
suivant(<declarateur>) = {void, extern, ‘,’} d’où l’intersection est l’ensemble vide.
Alors règle 6 est bonne.
Règle 7:
On l’intersection des premiers des deux sous-règles de <liste-declarateurs’> est l’ensemble vide ; et
comme une seule est non annulable, on a :
Premier(<declarateur’>) = {‘[’, epsilon} et
suivant(<declarateur’>) = suivant(<declarateur>) = {void, extern, ‘,’} d’où l’intersection est
l’ensemble vide. Alors règle 7 est bonne.
Règle 8:
<fonction> : ( <liste-parms> ) { <liste-declarations> < liste-instructions>}
La règle 8 est bonne car il ne présente qu’un seul choix.
Règle 9:
<prototype> : extern <type> identificateur ( <liste-parms> ) ;
La règle 9 est bonne car il ne présente qu’un seul choix.
Règle 10:
<type> : void I int
La règle 10 est bonne car il présente deux choix différents et non annulables.
Règle 11:
<liste-fonctions> : int identificateur <fonction> <liste-fonctions> | <liste-fonctions’> | epsilon
Premier(<liste-fonctions’>) = {void, extern} l’intersection avec {int} et {epsilon} est l’ensemble
vide.
Premier(<liste-fonctions>) = {int, void, extern} et suivant (<liste-fonctions>) = {$}, donc
l’intersection est vide ce qui signifie que la règle 11 est bonne.
Règle 12:
<liste-fonctions’> : void identificateur <fonction> <liste-fonctions> |<prototype> <listefonctions>
On a premier(<protocole>) = {extern} l’intersection avec {void} est vide.
Et comme les deux sont non annulables alors la règle 12 est bonne.
(On utilise maintenant le numérotage des règles de la grammaire proposée sur l’énonncé )
Règle 9 :
<liste-parms> : <liste-parms> , <parm> | epsilon
X : Récursivité à gauche.
Elimination de la récursivité à gauche :
R091. <liste-parms> : <liste-parms’> / OK : Un seul choix
R092. <liste-parms’> : , <parm> <liste-parms’> | epsilon /OK
Règle 10 :
<parm> : int identificateur
Ok : Un seul choix
Règle 11 :
<liste-instructions> : <liste-instructions>< instructions > | epsilon
X : Récursivité à gauche.
Elimination de la récursivité à gauche :
R111.<liste-instructions> : <liste-instructions'>
Ok : Un seul choix
R112.<liste-instructions'> : < instructions ><liste-instructions’>| epsilon
Premier(< instructions ><liste-instructions’>)=
{for,while,if,return,{,identificateur}
et Premier(epsilon ) = { epsilon } sont disjoints.
La deuxième production est annulable et :
Premier(<liste-instructions’>)={for,while,if,return,{,identificateur, epsilon}
et Suivant(<liste-instructions’>)={ } }
sont disjoints. /OK
Règle 12 :
<instruction> : <iteration> I <selection> | <saut> | <affectation> ; | <bloc> I <appel>
Premier(appel)∩ Premier(affectation) = {identificateur}
Factorisation à gauche :
R121. <instruction> : identificateur<instruction’>| <iteration> I <selection> | <saut> |
<bloc>
Les premiers des productions sont respectivement : {identificateur} , {for,while} , {if} ,
{return} et { { } sont tous disjoints
Toutes les productions sont non annulables. /OK
R122. <instruction’> : ( <liste-expressions> ) ; | <variable’> = <expression>
Les premiers respectifs sont { ( } et {epsilon, [ } ils sont disjoint.
Les deux productions sont non annulables . /OK
Règle 13 :
<iteration> : for ( < affectation> ; <condition> ; <affectation> ) <instruction> | while( <condition>
) <instruction>
Les premiers successifs sont {for} et {while}, ils sont disjoints.
Les deux productions sont non annulables. /Ok
Règle 14 :
<selection> :if ( <condition> ) <instruction> | if ( <condition> ) <instruction>else<instruction>
X : Récursivité à gauche.
Factorisation à gauche :
R141. <selection> :if ( <condition> ) <instruction><selection’> Un seul choix /OK
R142. <selection’> :else<instruction> | epsilon
Les premiers successifs sont {else} et {epsilon} sont disjoints.
Premier(<selection’>)={else,epsilon}
et suivant(<selection’>)={ } } sont disjoints. /OK
Règle 15 :
<saut> : return ; | return <expression>;
X : Factorisation à gauche.
Factorisation à gauche :
R151. <saut> :return <saut’> Un seul choix /OK
R152. <saut’> : ; |<expression>;
Les premiers successifs sont {;} et { ( , - , identidicateur,
0,1,..,9} sont disjoints
Aucune des productions n'est annulable /OK
Règle 16 :
<affecation> : <variable> = <expression> un seul choix /OK
Règle 17 :
<bloc> : { <liste-expressions>} un seul choix /OK
Règle 18 :
<appel> : identificateur ( <liste-expressions> ) ; un seul choix /OK
Règle 19 :
<variable> : identificateur | identificateur [<expression>]
|identificateur[<expression>][<expression>]
Factorisation à gauche :
R191. <variable> identificateur <variable’> un seul choix /OK
R192. <variable'> : [<expression>] | [<expression>][<expression>] |epsilon
Factorisation à gauche :
R193. <variable’> :[<expression>] <variable’'> |epsilon
Les premiers respectifs sont { [ } et {epsilon} sont disjoints.
Premier(<variable'> )= { epsilon , [}
et Suivant(<variable'> )= {=, ) , , , & , | , +, -, * , / , < , > , ; ] } sont disjoints /OK
R194. <variable’'> :[<expression>] | epsilon
Les premiers respectifs sont { [ } et {epsilon} sont disjoints.
Premier(<variable''> )={ epsilon , [}
et Suivant(<variable''> )= {=, ) , , , & , | , +, -, * , / , < , > , ; ] } sont disjoints /OK
Règle 20 :
<expression> : ( < expression > ) | <expression> <binary-op> <expression>|- <expression> |
<variable> | <constante> | identificateur (<liste-expressions>)
X : Recursivité à gauche.
Elimination de la récursivité à gauche :
R201. <expression> : ( <expression> ) <expression’> | -<expression><expression’> |
<Identificateur><variable’> <expression’> | identificateur (<liste-expressions>) <expression’>
| <constante> <expression’> OK
R2011 : <expression> : ( <expression> ) <expression’> | identificateur <expression’’> /OK
R2012 : <expression’’> : <variable> <expression’> | (<liste-expressions>) <expression’> /OK
Les premiers des deux membres disjoints et ils sont non annulables
R202. <expression’> : <binary-op> <expression><expression’> | episolon /OK
Un membre annulable, on a Premier(<expression’>) = { <binary-op>,epsiolon }
Alors que Suivant(<expression’> )= { ; , ] }
Les deux sont disjoints !
Règle 21 :
<liste-expressions> : <liste-expressions>,<expression> | epsilon
X : Recursivité à gauche.
Elimination de la récursivité à gauche :
R211. <liste-expressions> : <liste-expressions’> /OK
R212. <liste-expressions’> : , <expression> <liste-expressions’>| epsilon /OK
Car on a un membre annulable.
et Premier(<liste-expressions’> ) = {, , epsilon}
Suivant (<liste-expressions’> )={ <binary-op>,)}
Règle 22 :
<condition> : !(<condition>) | <condition><binary-rel><condition> | (<condition >) |
<expression><binary-comp><expression>
Elimination de la récursivité à gauche :
R221. <condition> : !(<condition>) <condition’> | (<condition >) <condition’> |
<expression><binary-comp><expression><condition’> OK
Les premiers disjoincts et non annulables
R222. <condition’> : <condition><binary-rel><condition’> | epsilon OK
Un member annullable, alors :
- Premier(<condition’>)={!,(,identificateur,constante}
- Suivant(<condition’>)={<binary-rel>,),;}
Les deux sont disjoints !
Téléchargement