SlideShare une entreprise Scribd logo
1  sur  18
Télécharger pour lire hors ligne
 



NF11	
  -­‐	
  Génération	
  d'analyseur	
  lexical	
  et	
  
syntaxique	
  
Fayçal	
  Laatef	
  &	
  Friscira	
  Elsa	
  	
  
Groupe	
  p014	
  
	
  
	
  

Objectifs	
  
       •      Créer	
  une	
  grammaire	
  du	
  langage	
  Logo	
  et	
  une	
  représentation	
  intermédiaire	
  d’un	
  
              programme	
  Logo.	
  
       •      Générer	
  un	
  analyseur	
  syntaxique	
  de	
  cette	
  grammaire.	
  
       •      Créer	
  un	
  interpréteur	
  graphique	
  du	
  langage	
  Logo.	
  
       •      Crée	
  une	
  table	
  des	
  symboles	
  d’un	
  programme.	
  
       •      Vérifier	
  quelques	
  conditions	
  sémantiques.	
  
	
  
	
  




                                                                                                                               	
  
	
  
	
  


       	
                                                                                                                             1	
  
 


Table	
  des	
  matières	
  
OBJECTIFS	
  ............................................................................................................................................................	
  1	
  

I.	
  INTRODUCTION,	
  QU'EST	
  CE	
  QUE	
  LOGO?	
  .............................................................................................	
  3	
  

II.	
  STRUCTURE	
  DE	
  NOTRE	
  PROJET	
  ...........................................................................................................	
  3	
  

III.	
  LEXER,	
  PARSER	
  ET	
  INTERPRETEUR	
  DU	
  LANGAGE	
  LOGO	
  ...........................................................	
  4	
  
A.	
  INTRODUCTION	
  ................................................................................................................................................	
  4	
  
C.	
  ANALYSE	
  SYNTAXIQUE:	
  LE	
  PARSER	
  (LOGO.G)	
  ................................................................................................	
  5	
  
D.	
  ANALYSE	
  SEMANTIQUE:	
  TREE	
  WALKER	
  (LOGOTREE.G)	
  ...............................................................................	
  6	
  
E.	
  EN	
  RESUME,	
  COMMENT	
  AJOUTER	
  UNE	
  FONCTIONNALITE?	
  .............................................................................	
  7	
  
E.	
  QUELLES	
  FONCTIONNALITES	
  AVONS-­‐NOUS	
  AJOUTEES?	
                     ..................................................................................	
  7	
  
PRINCIPALES	
  COMMANDES	
  DE	
  LA	
  TORTUE	
  ..........................................................................................................................	
  7	
  
EXPRESSIONS	
  ARITHMETIQUES	
  .............................................................................................................................................	
  8	
  
EXPRESSIONS	
  BOOLEENNES	
  ...................................................................................................................................................	
  9	
  
IDENTIFICATEURS,	
  AFFECTATION	
  .........................................................................................................................................	
  9	
  

IV.	
  STRUCTURES	
  DE	
  CONTROLE	
  .............................................................................................................	
  12	
  
EVALUATION	
  DIFFEREE	
  D'UNE	
  ARBORESCENCE	
  ..............................................................................................................	
  12	
  
LA	
  REPETITION	
  ......................................................................................................................................................................	
  13	
  
L'ALTERNATIVE	
  (SI)	
  .............................................................................................................................................................	
  14	
  

V.	
  PROCEDURES	
  ET	
  FONCTIONS	
  .............................................................................................................	
  15	
  
PROCEDURES	
  ..........................................................................................................................................................................	
  15	
  
REMARQUES:	
  .....................................................................................................................................................	
  17	
  

VI.	
  ELEMENTS	
  NON	
  TRAITES	
  ET	
  DIFFICULTES	
  RENCONTREES	
  ....................................................	
  18	
  

                  ..........................................................................................................................................	
  18	
  
VII.	
  CONCLUSION	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  


	
  
	
                                                           	
  




2	
   	
  
 


I.	
  Introduction,	
  qu'est	
  ce	
  que	
  Logo?	
  
	
  
Le	
  langage	
  Logo	
  est	
  un	
  langage	
  de	
  programmation	
  qui	
  recouvre	
  	
  deux	
  concepts:	
  
        • un	
  mode	
  d’apprentissage	
  inspiré	
  des	
  travaux	
  de	
  Jean	
  Piaget	
  sur	
  le	
  développement	
  
              cognitif	
  de	
  l’enfant	
  
        • un	
  type	
  d’environnement	
  informatique,	
  à	
  partir	
  d'un	
  langage	
  adapté	
  du	
  LISP	
  
	
  
Le	
  langage	
  Logo	
  est	
  connu	
  pour	
  sa	
  simplicité	
  mais	
  est	
  également	
  capable	
  de	
  manipuler	
  des	
  
expressions	
  arithmétiques,	
  des	
  expressions	
  booléennes	
  ou	
  de	
  mettre	
  en	
  place	
  des	
  structures	
  
de	
  contrôles	
  telles	
  que	
  les	
  conditions,	
  les	
  boucles,	
  les	
  procédures	
  et	
  les	
  fonctions.	
  
	
  
Le	
  but	
  de	
  ce	
  projet	
  est	
  de	
  créer	
  un	
  analyseur	
  lexical	
  et	
  syntaxique	
  du	
  langage	
  Logo.	
  	
  	
  
Pour	
  cela,	
  nous	
  avons	
  utilisé	
  AntLR	
  (Another	
  Tool	
  for	
  Language	
  Recognition).	
  AntLR	
  est	
  un	
  
outil	
  de	
  génération	
  automatique	
  d'analyseur	
  permettant	
  de	
  reconnaître	
  les	
  phrases	
  d'un	
  
programme	
  écrit	
  dans	
  un	
  langage	
  donné.	
  


II.	
  Structure	
  de	
  notre	
  projet	
  
	
  




                                                                                                                                	
  




       	
                                                                                                                                 3	
  
 

	
  

L'interface	
  graphique,	
  réalisée	
  par	
  Claude	
  Moulin,	
  nous	
  permet	
  d'observer	
  et	
  de	
  valider	
  le	
  
travail	
  de	
  développement	
  des	
  grammaires	
  que	
  nous	
  réalisons.	
  

	
  




                                                                                             	
  
	
  
	
  
L'objectif	
  du	
  projet	
  est	
  de	
  réaliser	
  une	
  grammaire	
  du	
  langage	
  LOGO	
  afin	
  de	
  pouvoir	
  
l'analyser.	
  Il	
  y	
  a	
  donc	
  trois	
  types	
  d'analyses	
  à	
  réaliser:	
  
    1. l'analyse	
  lexicale	
  
    2. l'analyse	
  syntaxique	
  
    3. l'analyse	
  sémantique	
  (traitement	
  à	
  partir	
  de	
  l'arbre	
  AST)	
  

Remarque:	
  AntLR	
  utilise	
  une	
  analyse	
  descendante	
  de	
  type	
  LL.	
  


III.	
  Lexer,	
  Parser	
  et	
  interpréteur	
  du	
  langage	
  Logo	
  
	
  

a.	
  Introduction	
  
	
  
Pour	
  réaliser	
  les	
  analyses	
  lexicales	
  et	
  syntaxiques	
  du	
  langage	
  LOGO,	
  nous	
  avons	
  spécifié	
  une	
  
grammaire	
  (Lexer,Parser)	
  qui	
  décrit	
  la	
  façon	
  de	
  découper	
  un	
  flux	
  de	
  caractères	
  en	
  un	
  flux	
  de	
  
mots	
  du	
  langage	
  (tokens)	
  puis	
  d'analyser	
  le	
  flux	
  sortant.	
  
Avec	
  AntLR,	
  nous	
  avons	
  créé	
  un	
  fichier	
  "nomFichier.g"	
  définissant	
  les	
  unités	
  lexicales	
  et	
  
syntaxiques	
  de	
  la	
  grammaire.	
  AntLR	
  a	
  ensuite	
  créer	
  lui	
  même	
  un	
  fichier	
  annexe	
  contenant	
  la	
  
grammaire	
  du	
  lexer.	
  Enfin,	
  il	
  a	
  généré	
  les	
  classes	
  correpondant	
  au	
  lexer	
  et	
  au	
  parser.	
  
	
  
	
  
	
  
	
  
	
  
	
  



4	
   	
  
 

	
  
b.	
  Analyse	
  lexicale:	
  le	
  lexer	
  (Logo.g)	
  
	
  
L'analyseur	
  lexical	
  (ou	
  lexer)	
  est	
  l'outil	
  qui	
  permet	
  de	
  découper	
  un	
  flux	
  de	
  caractères	
  en	
  un	
  
flux	
  de	
  mots	
  du	
  langage:	
  les	
  tokens.	
  
	
  
                                           Flux	
  de	
  caractères	
  	
  =>	
  Flux	
  de	
  tokens	
  
	
  
Ajout	
  des	
  tokens	
  au	
  lexer	
  dans	
  la	
  grammaire	
  Logo.g:	
  
	
  




                                                                  	
  
	
  
	
  

c.	
  Analyse	
  syntaxique:	
  le	
  parser	
  (Logo.g)	
  
	
  
L'analyseur	
  syntaxique	
  (ou	
  parser)	
  vérifie	
  que	
  l'ensemble	
  des	
  mots	
  issus	
  de	
  l'analyse	
  lexicale	
  
(tokens)	
  forme	
  une	
  phrase	
  syntaxiquement	
  correcte.	
  Le	
  parser	
  va	
  donc	
  générer	
  un	
  arbre	
  
syntaxique	
  abstrait	
  (AST)	
  à	
  partir	
  des	
  tokens	
  générés	
  par	
  le	
  lexer.	
  
	
  
                                                   Flux	
  de	
  tokens	
  =>	
  AST	
  
	
  
Nous	
  avons	
  utilisée	
  la	
  règle	
  suivante	
  du	
  parser	
  comme	
  axiome	
  de	
  notre	
  grammaire:	
  
	
  
                                                                                                                                                    	
  
	
  
Remarque	
  importante:	
  Ici,	
  nous	
  avons	
  utilisé	
  un	
  token	
  imaginaire:	
  PROGRAMME.	
  Cela	
  nous	
  
permet	
  de	
  résoudre	
  les	
  problèmes	
  de	
  récursivité	
  à	
  gauche.	
  
En	
  effet,	
  AntLR	
  réalise	
  une	
  analyse	
  descendante	
  de	
  type	
  LL	
  et	
  nous	
  avons	
  vu	
  en	
  cours,	
  
qu'une	
  grammaire	
  récursive	
  à	
  gauche	
  ne	
  pouvait	
  pas	
  être	
  LL(1).	
  
	
  
	
  




       	
                                                                                                                                        5	
  
 

AntLR	
  donne	
  la	
  possibilité	
  de	
  créer	
  automatiquement,	
  semi	
  automatiquement	
  ou	
  
manuellement	
  l'arbre	
  AST.	
  Dans	
  le	
  fichier	
  Logo.g,	
  nous	
  avons	
  ajouté	
  une	
  section	
  option	
  
indiquant	
  au	
  parser	
  de	
  créer	
  l'arbre	
  AST:	
  
	
  



                           	
  
	
  
Les	
  méthodes	
  du	
  parser	
  associées	
  aux	
  règles	
  de	
  la	
  grammaire	
  ne	
  sont	
  alors	
  plus	
  de	
  type	
  void	
  
mais	
  d'un	
  type	
  structuré	
  dont	
  le	
  nom	
  reprend	
  celui	
  de	
  la	
  méthode.	
  
Que	
  fait	
  AntLR?	
  
Pour	
  chaque	
  règle:	
  AntLR	
  crée	
  une	
  racine	
  d'arborescence	
  	
  
Pour	
  chaque	
  token	
  présent	
  dans	
  une	
  règle:	
  
      • AntLR	
  crée	
  un	
  noeud	
  (Tree)	
  
      • Ajoute	
  ce	
  noeud	
  comme	
  fils	
  du	
  noeud	
  courant	
  (les	
  noeuds	
  forment	
  donc	
  une	
  liste)	
  
      • Attache	
  les	
  noeuds	
  de	
  la	
  liste	
  à	
  un	
  noeud	
  racine	
  de	
  type	
  nil.	
  	
  
          	
  
          	
  
Ajout	
  des	
  instructions	
  au	
  parser	
  dans	
  la	
  grammaire	
  Logo.g:	
  
	
  



                     	
  
	
  
Les	
  noeuds	
  AV,	
  TD	
  et	
  TG	
  dans	
  l'exemple	
  ci-­‐dessus	
  sont	
  des	
  noeuds	
  racine	
  car	
  ils	
  sont	
  suffixés	
  
avec	
  un	
  symbole	
  ^.	
  Au	
  contraire,	
  pour	
  ne	
  pas	
  créer	
  de	
  noeud	
  avec	
  un	
  token,	
  on	
  peut	
  le	
  
suffixer	
  avec	
  un	
  symbole	
  !.	
  
	
  

d.	
  Analyse	
  sémantique:	
  tree	
  Walker	
  (LogoTree.g)	
  
	
  
Le	
  tree-­‐walker	
  parcourt	
  l'arbre	
  AST	
  généré	
  par	
  le	
  parser	
  et	
  exécute	
  les	
  actions.	
  
	
  
Pour	
  les	
  fonctionnalités	
  concernant	
  l'UI	
  (qui	
  consistent	
  à	
  tracer	
  un	
  trait	
  sur	
  l'écran	
  en	
  se	
  
déplaçant	
  par	
  exemple),	
  nous	
  avons	
  fait	
  appel	
  à	
  la	
  classe	
  Traceur.	
  
	
  




                                                                                                                                 	
  
                                                                         	
  

Pour	
  les	
  autres	
  fonctionnalités	
  comme	
  par	
  exemple	
  l'affectation	
  de	
  variables,	
  nous	
  avons	
  
fait	
  appel	
  à	
  des	
  fonctions	
  que	
  nous	
  avons	
  développées	
  dans	
  la	
  classe	
  LogoUtil.java.	
  
	
  




6	
   	
  
 




                                                                                           	
  
	
  

e.	
  En	
  résumé,	
  comment	
  ajouter	
  une	
  fonctionnalité?	
  
Pour	
  ajouter	
  une	
  fonctionnalité,	
  il	
  faut:	
  
Dans	
  la	
  grammaire	
  Logo.g:	
  
     1. Ajouter	
  un	
  token	
  au	
  lexer	
  	
  
     2. Ajouter	
  une	
  instruction	
  au	
  parser	
  	
  
     3. Sauvegarder	
  (les	
  classes	
  lexer	
  et	
  parser	
  sont	
  générées)	
  
           	
  
           	
  
Dans	
  la	
  grammaire	
  LogoTree.g:	
  
     1. Ajouter	
  le	
  parsing	
  d'un	
  arbre	
  	
  
     2. Faire	
  générer	
  le	
  parseur	
  d'arbre	
  
     3. Ajouter	
  une	
  méthode	
  à	
  la	
  classe	
  logogui.Traceur	
  
	
  
	
  

e.	
  Quelles	
  fonctionnalités	
  avons-­‐nous	
  ajoutées?	
  
Principales	
  commandes	
  de	
  la	
  tortue	
  
Nous	
  avons	
  implémenté	
  les	
  commandes	
  de	
  base	
  permettant	
  à	
  la	
  tortue	
  d'avancer,	
  
d'effectuer	
  une	
  rotation,	
  de	
  reculer	
  ...	
  
	
  
Lexer	
  (Logo.g)	
  




                         	
  
	
  
Parser	
  (Logo.g)	
  




                         	
  
	
  
	
  

	
  

	
  



       	
                                                                                                            7	
  
 

Tree-­‐Walker	
  (LogoTree.g)	
  




                                                                                              	
  
                                                                   	
  
	
  
Pour	
  les	
  instructions	
  élémentaires	
  suivantes	
  (CF	
  fenêtre	
  de	
  gauche),	
  l'arbre	
  suivant	
  (fenêtre	
  
de	
  droite)	
  est	
  généré	
  par	
  le	
  parser:	
  
	
  




                                                                                     	
  
	
  
La	
  représentation	
  AntLR	
  sous	
  forme	
  de	
  liste	
  est	
  la	
  suivante:	
  
	
  
                              (PROGRAMME	
  (FPOS	
  [500	
  500])	
  (AV	
  100)	
  (TD	
  300)	
  )	
  
	
  
	
  
AntLR	
  utilise	
  deux	
  tokens	
  imaginaires:	
  UP	
  et	
  DOWN	
  pour	
  indiquer	
  les	
  niveaux	
  dans	
  l'arbre.	
  
	
  
	
  

Expressions	
  arithmétiques	
  
	
  
Nous	
  avons	
  implémenté	
  certaines	
  opérations	
  arithmétiques	
  telles	
  que	
  l'addition,	
  la	
  
soustraction,	
  la	
  multiplication,	
  la	
  division	
  et	
  l'opération	
  puissance.	
  
Afin	
  de	
  créer	
  une	
  grammaire	
  non	
  ambigüe,	
  nous	
  avons	
  donné	
  la	
  priorité	
  aux	
  opérateurs	
  
multiplier	
  et	
  diviser	
  sur	
  les	
  opérateurs	
  additionner	
  et	
  soustraire.	
  
	
  
Lexer	
  (Logo.g)	
  

                        	
  
                        	
  
                        	
  
                        	
  
	
  

	
  

	
  




8	
   	
  
 

Parser	
  (Logo.g)	
  




                                                                        	
  
	
  

Tree-­‐Walker	
  (LogoTree.g)	
  




                                                                                          	
  
	
  
Expressions	
  booléennes	
  
	
  
De	
  la	
  même	
  façon	
  que	
  pour	
  les	
  expressions	
  arithmétiques,	
  nous	
  avons	
  implémenté	
  les	
  
expressions	
  booléennes	
  de	
  base	
  telles	
  que	
  égal,	
  différent,	
  supérieur	
  et	
  inférieur.	
  
	
  

Parser	
  (Logo.g)	
  




                                                                                                 	
  
	
  

Tree-­‐Walker	
  (LogoTree.g)	
  




                                                                               	
  
                                                                 	
  
                                                                 	
  

Identificateurs,	
  affectation	
  
	
  
Variables	
  globales	
  
	
  
La	
  déclaration	
  et	
  l’affectation	
  d’une	
  variable	
  globale	
  sont	
  effectuées	
  grâce	
  au	
  mot-­‐clé	
  
DONNE.	
  Dans	
  le	
  tree-­‐walker,	
  nous	
  appelons	
  la	
  méthode	
  setVar(String,Double)	
  définie	
  dans	
  
la	
  classe	
  LogoUtil	
  du	
  fichier	
  LogoUtil.java.	
  	
  
	
  
	
  



       	
                                                                                                                        9	
  
 

Tree-­‐Walker	
  (LogoTree.g)	
  




                                                    	
  
                                                                         	
  
	
  

LogoUtil.java	
  




                                                                                                                                   	
  
	
  
La	
  fonction	
  setVar	
  de	
  la	
  classe	
  	
  LogoUtil	
  stocke	
  les	
  variables	
  dans	
  une	
  table	
  de	
  hachage	
  
"variables"	
  qui	
  associe	
  le	
  nom	
  de	
  la	
  variable	
  (String)	
  à	
  sa	
  valeur	
  (Double).	
  
	
  
	
  
Variables	
  locales	
  
	
  
Pour	
  les	
  variables	
  locales,	
  nous	
  avons	
  du	
  gérer	
  le	
  problème	
  des	
  portées	
  imbriquées.	
  
	
  
Nous	
  avons	
  représenté	
  chaque	
  portée	
  par	
  une	
  hashmap	
  contenant	
  le	
  dictionnaire	
  des	
  
symboles	
  qui	
  sont	
  déclarés	
  dans	
  la	
  portée	
  concernée.	
  	
  
Pour	
  gérer	
  le	
  problème	
  des	
  portées	
  imbriquées,	
  nous	
  avons	
  	
  donc	
  utilisé	
  une	
  pile	
  de	
  
hashmap.	
  
        • A	
  chaque	
  fois	
  que	
  nous	
  rentrons	
  dans	
  un	
  bloc,	
  nous	
  empilons	
  la	
  hashmap	
  contenant	
  
                 les	
  variables	
  locales	
  déclarées	
  dans	
  ce	
  bloc	
  	
  
        • A	
  chaque	
  fois	
  que	
  nous	
  sortons	
  d'un	
  bloc,	
  nous	
  dépilons	
  cette	
  hashmap	
  	
  (qui	
  se	
  
                 trouve	
  au	
  sommet	
  de	
  la	
  pile)	
  
	
  
Ainsi,	
  avec	
  cette	
  méthode,	
  la	
  portée	
  courante	
  courante	
  est	
  toujours	
  la	
  portée	
  au	
  sommet	
  de	
  
la	
  pile.	
  
	
  
Contexte	
  d'un	
  symbole	
  =	
  portée	
  dans	
  laquelle	
  il	
  est	
  	
  
	
              (+	
  portées	
  	
  dans	
  laquelle	
  la	
  portée	
  est	
  imbriquée)	
  éventuellement	
  
	
  
	
  

	
  

	
  

	
  

	
  

	
  



10	
   	
  
 

LogoUtil.java	
  




                                                                                                                                                 	
  
	
  
	
  
	
  
Insertion	
  d'un	
  identificateur	
  dans	
  un	
  contexte	
  
	
  
L’insertion	
  d’un	
  identificateur	
  se	
  fait	
  dans	
  le	
  dictionnaire	
  de	
  la	
  portée	
  en	
  sommet	
  de	
  pile.	
  
	
  
Recherche	
  d'un	
  identificateur	
  dans	
  un	
  contexte	
  
	
  
Pour	
  rechercher	
  un	
  identificateur	
  nous	
  utilisons	
  son	
  contexte	
  (qui	
  possède	
  une	
  pile	
  de	
  
portées	
  donc	
  une	
  pile	
  de	
  hashmaps).	
  Nous	
  cherchons	
  donc	
  l'identificateur	
  dans	
  cette	
  pile	
  de	
  
portées	
  de	
  la	
  façon	
  suivante:	
  
   1. nous	
  regardons	
  si	
  l'identificateur	
  se	
  situe	
  dans	
  la	
  portée	
  courante	
  (donc	
  au	
  sommet	
  
          de	
  la	
  pile	
  de	
  portées	
  du	
  contexte)	
  
   2. si	
  nous	
  ne	
  trouvons	
  pas	
  l'identificateur	
  dans	
  la	
  portée	
  courante,	
  nous	
  parcourons	
  la	
  
          pile	
  élément	
  par	
  élément	
  jusqu'à	
  trouver	
  l'identificateur.	
  (parcours	
  de	
  la	
  portée	
  la	
  
          plus	
  récente	
  à	
  la	
  portée	
  la	
  plus	
  ancienne)	
  
   3. si	
  nous	
  ne	
  trouvons	
  pas	
  l'identificateur	
  dans	
  la	
  pile	
  de	
  portée	
  (donc	
  s'il	
  n'est	
  dans	
  
          aucune	
  portée)	
  alors	
  nous	
  regardons	
  dans	
  la	
  hashmap	
  contenant	
  les	
  variables	
  
          globales.	
  	
  
   4. si	
  l'identificateur	
  n'est	
  pas	
  dans	
  cette	
  hashmap,	
  il	
  n'est	
  pas	
  défini.	
  
	
  
	
  

	
  

	
  

	
  

	
  

	
  

	
  



       	
                                                                                                                                    11	
  
 

LogoUtil.java	
  

	
  




                                                                                                                         	
  
	
  



IV.	
  Structures	
  de	
  contrôle	
  
Evaluation	
  différée	
  d'une	
  arborescence	
  

Pour	
  les	
  structures	
  de	
  contrôle	
  qui	
  suivent,	
  nous	
  avons	
  utilisé	
  le	
  parsing	
  différé.	
  	
  
En	
  quoi	
  cela	
  consiste-­‐t-­‐il?	
  
Le	
  parsing	
  différé	
  se	
  fait	
  à	
  l'aide	
  d'une	
  règle	
  que	
  l'on	
  écrit	
  dans	
  la	
  grammaire.	
  On	
  mémorise	
  
l'index	
  sur	
  lequel	
  cette	
  règle	
  doit	
  commencer	
  le	
  matching.	
  
Avant	
  d'appeler	
  la	
  méthode	
  du	
  parser	
  associée	
  à	
  la	
  règle,	
  on	
  empile	
  l'index	
  sur	
  lequel	
  elle	
  
doit	
  commencer	
  le	
  matching	
  et	
  on	
  dépile	
  ensuite	
  le	
  noeud	
  qu'elle	
  aura	
  placé	
  pour	
  la	
  suite	
  du	
  
matching	
  et	
  qui	
  s'avère	
  inutile.	
  

	
  
	
                                           	
  




12	
   	
  
 

La	
  répétition	
  

Repeat	
  
	
  

Tree-­‐Walker	
  (LogoTree.g)	
  




                                                                                          	
  
	
  
Nous	
  avons	
  placé	
  un	
  point	
  (.)	
  après	
  l'expression	
  "exp"	
  afin	
  que	
  le	
  parsing	
  ne	
  se	
  fasse	
  pas	
  par	
  
défaut.	
  Le	
  point	
  représente	
  l'index	
  de	
  l'arborescence.	
  	
  
	
  




                                                                                                   	
  
	
  
L'arbre	
  AntLR	
  associé	
  est	
  donc	
  le	
  suivant:	
  
	
  
                                          REPEAT	
  DOWN	
  <atom>	
  <.>	
  UP.	
  
	
  
Rappel:	
  AntLR	
  utilise	
  deux	
  tokens	
  imaginaires:	
  UP	
  et	
  DOWN	
  pour	
  indiquer	
  les	
  niveaux	
  dans	
  
l'arbre.	
  
	
  
La	
  règle	
  list_evaluation	
  doit	
  connaître	
  l'index	
  de	
  l'arborescence	
  car	
  lorsqu'elle	
  va	
  être	
  
appelée,	
  elle	
  va	
  devoir	
  dépiler	
  cet	
  index.	
  
	
  
Le	
  code	
  situé	
  dans	
  la	
  boucle	
  FOR	
  ci-­‐dessus	
  effectue	
  les	
  actions	
  suivantes:	
  
       • empile	
  l'index	
  du	
  noeud	
  racine	
  traité	
  par	
  list_evaluation	
  
          push(mark_list)	
  
       • appelle	
  la	
  méthode	
  list_evaluation
          list_evaluation()	
  =	
  règle	
  qui	
  permet	
  de	
  parser	
  un	
  arbre	
  dont	
  la	
  racine	
  est	
  le	
  token	
  
          LIST	
  et	
  dont	
  les	
  fils	
  sont	
  les	
  instructions	
  




       	
                                                                                                                                        13	
  
 


         •    dépile	
  le	
  noeud	
  superflu	
  que	
  list_evaluation	
  va	
  empiler	
  
              pop()	
  
          	
  
Les	
  méthode	
  push() et	
  pop()	
  sont	
  des	
  méthodes	
  que	
  nous	
  avons	
  développées	
  dans	
  
LogoTree.g	
  afin	
  d'alléger	
  l'écriture:	
  
	
  




                                                                             	
  
	
  
	
  

While	
  
	
  
Pour	
  le	
  while,	
  nous	
  avons	
  suivi	
  la	
  même	
  méthode	
  que	
  pour	
  le	
  repeat.	
  
	
  
                                       	
  
	
  
Tree-­‐Walker	
  (LogoTree.g)	
  




                                                                                                                    	
  
	
  

L'alternative	
  (si)	
  
	
  
Dans	
  le	
  cas	
  de	
  l'alternative,	
  nous	
  utilisons	
  la	
  possibilité	
  d'ignorer	
  une	
  branche	
  de	
  l'arbre	
  au	
  
cours	
  du	
  parcours	
  initial	
  et	
  d'y	
  revenir	
  par	
  la	
  suite	
  en	
  sauvegardant	
  son	
  index.	
  
La	
  particularité	
  de	
  l'instruction	
  alternative	
  est	
  que	
  le	
  second	
  bloc	
  d'instructions	
  est	
  facultatif.	
  	
  
	
  
Si	
  l'expression	
  booléenne	
  renvoie	
  vraie	
  alors	
  exécuter	
  le	
  bloc	
  1	
  sinon	
  exécuter	
  le	
  bloc	
  2	
  
(optionnel	
  car	
  "?"):	
  
	
  
                                                   	
  


14	
   	
  
 

	
  
	
  
Nous	
  initialisons	
  le	
  marqueur	
  d'index	
  (mark_list2)	
  à	
  0.	
  La	
  récupération	
  de	
  l'index	
  a	
  lieu	
  grâce	
  
à	
  la	
  méthode	
  "input.mark()"que	
  l'on	
  affecte	
  à	
  mark_list2.	
  	
  	
  
Si	
  mark_list2>0	
  alors	
  nous	
  pouvons	
  traiter	
  le	
  second	
  bloc	
  d'instructions,	
  sinon,	
  l'interpréteur	
  
ne	
  l'a	
  pas	
  trouvé.	
  
	
  
Tree-­‐Walker	
  (LogoTree.g)	
  




                                                                                                                                 	
  
	
  


V.	
  Procédures	
  et	
  fonctions	
  
Procédures	
  
	
  
Afin	
  de	
  générer	
  des	
  branches	
  d'instructions	
  qui	
  seront	
  plus	
  facilement	
  accessibles	
  lors	
  du	
  
parcours	
  de	
  l'arbre	
  AST,	
  nous	
  avons	
  créé	
  deux	
  tokens	
  imaginaires:	
  ARG	
  et	
  et	
  PARAM.	
  
ARG	
  est	
  utilisé	
  lors	
  de	
  la	
  déclaration	
  de	
  notre	
  procédure.	
  
PARAM	
  est	
  utilisé	
  lors	
  de	
  l'appel	
  de	
  notre	
  procédure.	
  
	
  




                                                                                                                                                  	
  
	
       	
  
Nous	
  avons	
  également	
  créé	
  une	
  classe	
  Procedure	
  qui	
  contient	
  les	
  deux	
  structures	
  suivantes:	
  
     • une	
  liste	
  ordreParam	
  utilisée	
  pour	
  enregistrer	
  les	
  paramètres	
  et	
  leur	
  ordre	
  au	
  
          moment	
  de	
  la	
  déclaration	
  de	
  notre	
  procédure	
  	
  



       	
                                                                                                                                15	
  
 

              private ArrayList<String> ordreParam;
              	
  
         •    une	
  hashmap	
  params	
  utilisée	
  pour	
  associer	
  une	
  valeur	
  à	
  chaque	
  variable	
  lors	
  de	
  
              l'appel	
  de	
  notre	
  procédure	
  
              private ArrayList<String> ordreParam;	
  
              	
  
	
  
	
  
Déclaration	
  d'une	
  procédure	
  
	
  




                                                                                                                                                 	
  
	
  
	
  
La	
  fonction	
  "pushProcedure"	
  définie	
  dans	
  la	
  classe	
  LogoUtils,	
  va	
  nous	
  permettre	
  d'empiler	
  
notre	
  procédure	
  sur	
  une	
  pile	
  de	
  procédures	
  afin	
  de	
  simplifier	
  l'ajout	
  des	
  paramètres	
  	
  lors	
  de	
  
la	
  déclaration.	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  



16	
   	
  
 

Appel	
  d'une	
  procédure	
  
	
  




                                                                                                                                                         	
  
	
  
On	
  va	
  récupérer	
  le	
  nom	
  de	
  la	
  procédure	
  en	
  cours	
  et	
  on	
  va	
  dire	
  à	
  notre	
  variable	
  de	
  type	
  
LogoUtil	
  (u)	
  de	
  récupérer	
  la	
  procédure	
  du	
  nom	
  contenu	
  dans	
  la	
  variable:	
  "nameProc"	
  c'est	
  à	
  
dire	
  de	
  la	
  chercher	
  dans	
  la	
  pile	
  puis	
  de	
  l'extraire	
  de	
  cette	
  pile.	
  On	
  va	
  ensuite	
  modifier	
  cette	
  
procédure	
  en	
  associant	
  une	
  valeur	
  à	
  chaque	
  variable	
  déclarée	
  lors	
  de	
  la	
  déclaration	
  de	
  
procédure.	
  

	
  
Remarque:	
  
	
  
Arité	
  d'une	
  procédure	
  
La	
  	
  méthode	
  getArite()	
  dans	
  notre	
  classe	
  Procedure	
  vérifie	
  que	
  le	
  nombre	
  de	
  paramètres	
  
passés	
  lors	
  de	
  l'appel	
  de	
  cette	
  procédure	
  (	
  dans	
  la	
  hashmap	
  params)	
  est	
  bien	
  égal	
  au	
  nombre	
  
de	
  paramètres	
  déterminé	
  lors	
  de	
  la	
  déclaration	
  de	
  cette	
  procédure	
  (dans	
  la	
  liste	
  
ordreParam).	
  
	
  




       	
                                                                                                                                         17	
  
 




                                                                                       	
  



VI.	
  Eléments	
  non	
  traités	
  et	
  difficultés	
  rencontrées	
  
	
  
Eléments	
  non	
  traités	
  
Faute	
  de	
  temps,	
  nous	
  n'avons	
  pas	
  implémenté	
  les	
  fonctionnalités	
  suivantes:	
  
   • Les	
  procédures	
  récursives	
  
   • La	
  primitive	
  LOOP	
  qui	
  renvoie	
  le	
  nombre	
  de	
  tours	
  dans	
  une	
  boucle.	
  
   • La	
  primitive	
  STOP.	
  
   • La	
  possibilité	
  d'utiliser	
  les	
  opérateurs	
  AND	
  et	
  OR	
  dans	
  les	
  expressions	
  booléennes.	
  
          	
  

Difficultés	
  rencontrées	
  
         •    Au	
  début	
  du	
  projet,	
  il	
  nous	
  a	
  fallu	
  du	
  temps	
  pour	
  nos	
  familiariser	
  la	
  syntaxe	
  et	
  le	
  
              fonctionnement	
  de	
  AntLR.	
  
         •    Nous	
  avons	
  rencontré	
  quelques	
  difficultés	
  dans	
  la	
  gestion	
  des	
  tokens	
  imaginaires	
  
              générés	
  par	
  AntLR	
  <UP>	
  and	
  <DOWN>.	
  Cela	
  nous	
  créait	
  des	
  erreurs	
  de	
  marquage.	
  Il	
  y	
  
              avait	
  un	
  décalage	
  entre	
  l'arbre	
  que	
  l'on	
  créait	
  et	
  l'arbre	
  que	
  l'on	
  parsait.	
  


VII.	
  Conclusion	
  
	
  
Ce	
  projet	
  nous	
  a	
  permis	
  d'aller	
  plus	
  loin	
  dans	
  notre	
  compréhension	
  des	
  différents	
  types	
  
d'analyse:	
  lexicale,	
  syntaxique	
  et	
  sémantique.	
  Il	
  nous	
  a	
  permis	
  également	
  de	
  voir	
  un	
  exemple	
  
concret	
  et	
  d'appliquer	
  les	
  principes	
  théoriques	
  vus	
  en	
  cours.	
  	
  
Nous	
  avons	
  désormais	
  une	
  vision	
  globale	
  plus	
  claire	
  sur	
  les	
  différentes	
  phases	
  allant	
  de	
  
l'écriture	
  à	
  l'exécution	
  d'un	
  programme.




	
  




18	
   	
  

Contenu connexe

En vedette

Barachois novembre 15 à 28
Barachois novembre 15 à 28Barachois novembre 15 à 28
Barachois novembre 15 à 28JournalBarachois
 
Kikrounchlars novembre 92
Kikrounchlars novembre 92Kikrounchlars novembre 92
Kikrounchlars novembre 92bakoon
 
1235 cheminssurlevisage (roger)
1235 cheminssurlevisage (roger)1235 cheminssurlevisage (roger)
1235 cheminssurlevisage (roger)Dominique Pongi
 
Actualite PLFSS 2013
Actualite PLFSS 2013Actualite PLFSS 2013
Actualite PLFSS 2013Hospimedia
 
Présentation de Cloudshare
Présentation de CloudsharePrésentation de Cloudshare
Présentation de CloudshareBBoySturdy
 
2009 Prise en charge spécifique de la population carcérale
2009 Prise en charge spécifique de la population carcérale2009 Prise en charge spécifique de la population carcérale
2009 Prise en charge spécifique de la population carcéraleAPRHOC
 
Allegoria ecovolution
Allegoria ecovolutionAllegoria ecovolution
Allegoria ecovolutiononibi29
 
2011 03 07 Convaincre et fidéliser la clientèle en optimisant son site web - ...
2011 03 07 Convaincre et fidéliser la clientèle en optimisant son site web - ...2011 03 07 Convaincre et fidéliser la clientèle en optimisant son site web - ...
2011 03 07 Convaincre et fidéliser la clientèle en optimisant son site web - ...COMPETITIC
 
Crédit Agricole 2016 - Objectifs financiers du Groupe et de Crédit Agricole SA
Crédit Agricole 2016 - Objectifs financiers du Groupe et de Crédit Agricole SACrédit Agricole 2016 - Objectifs financiers du Groupe et de Crédit Agricole SA
Crédit Agricole 2016 - Objectifs financiers du Groupe et de Crédit Agricole SAGroupe Crédit Agricole
 
07 les-accidents-ne-datent-pas-d%27aujourd%27hui
07 les-accidents-ne-datent-pas-d%27aujourd%27hui07 les-accidents-ne-datent-pas-d%27aujourd%27hui
07 les-accidents-ne-datent-pas-d%27aujourd%27huiDominique Pongi
 

En vedette (20)

Barachois novembre 15 à 28
Barachois novembre 15 à 28Barachois novembre 15 à 28
Barachois novembre 15 à 28
 
Letitanic
Letitanic Letitanic
Letitanic
 
Kikrounchlars novembre 92
Kikrounchlars novembre 92Kikrounchlars novembre 92
Kikrounchlars novembre 92
 
1235 cheminssurlevisage (roger)
1235 cheminssurlevisage (roger)1235 cheminssurlevisage (roger)
1235 cheminssurlevisage (roger)
 
Film
FilmFilm
Film
 
Actualite PLFSS 2013
Actualite PLFSS 2013Actualite PLFSS 2013
Actualite PLFSS 2013
 
Introduction - session 2
Introduction - session 2Introduction - session 2
Introduction - session 2
 
Présentation de Cloudshare
Présentation de CloudsharePrésentation de Cloudshare
Présentation de Cloudshare
 
I a pdf1
I a pdf1I a pdf1
I a pdf1
 
Stille nacht
Stille nachtStille nacht
Stille nacht
 
2009 Prise en charge spécifique de la population carcérale
2009 Prise en charge spécifique de la population carcérale2009 Prise en charge spécifique de la population carcérale
2009 Prise en charge spécifique de la population carcérale
 
Eugenie grandet
Eugenie grandetEugenie grandet
Eugenie grandet
 
Perspectives en matière de portails géographiques et de 3D
Perspectives en matière de portails géographiques et de 3DPerspectives en matière de portails géographiques et de 3D
Perspectives en matière de portails géographiques et de 3D
 
Allegoria ecovolution
Allegoria ecovolutionAllegoria ecovolution
Allegoria ecovolution
 
2011 03 07 Convaincre et fidéliser la clientèle en optimisant son site web - ...
2011 03 07 Convaincre et fidéliser la clientèle en optimisant son site web - ...2011 03 07 Convaincre et fidéliser la clientèle en optimisant son site web - ...
2011 03 07 Convaincre et fidéliser la clientèle en optimisant son site web - ...
 
Mont ste odile1
Mont ste odile1Mont ste odile1
Mont ste odile1
 
1 crise cardiaque_
1 crise cardiaque_1 crise cardiaque_
1 crise cardiaque_
 
Crédit Agricole 2016 - Objectifs financiers du Groupe et de Crédit Agricole SA
Crédit Agricole 2016 - Objectifs financiers du Groupe et de Crédit Agricole SACrédit Agricole 2016 - Objectifs financiers du Groupe et de Crédit Agricole SA
Crédit Agricole 2016 - Objectifs financiers du Groupe et de Crédit Agricole SA
 
07 les-accidents-ne-datent-pas-d%27aujourd%27hui
07 les-accidents-ne-datent-pas-d%27aujourd%27hui07 les-accidents-ne-datent-pas-d%27aujourd%27hui
07 les-accidents-ne-datent-pas-d%27aujourd%27hui
 
Janvier11 revue292
Janvier11 revue292Janvier11 revue292
Janvier11 revue292
 

Similaire à Logo

Réalisation d'un compilateur de mini langage - Khawarizmi
Réalisation d'un compilateur  de mini langage - KhawarizmiRéalisation d'un compilateur  de mini langage - Khawarizmi
Réalisation d'un compilateur de mini langage - KhawarizmiBachir Benyammi
 
Dev Web 101 #2 : development for dummies
Dev Web 101 #2 : development for dummiesDev Web 101 #2 : development for dummies
Dev Web 101 #2 : development for dummiesJean Michel
 
Chapitre 1 (algorithme)
Chapitre 1 (algorithme)Chapitre 1 (algorithme)
Chapitre 1 (algorithme)mahbouba
 
Samar - Premier bilan d'étape - Oct. 2010
Samar - Premier bilan d'étape - Oct. 2010Samar - Premier bilan d'étape - Oct. 2010
Samar - Premier bilan d'étape - Oct. 2010Stefane Fermigier
 
Compilationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
CompilationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnCompilationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
Compilationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnsaraayoub440
 
Tp python dauphine
Tp python dauphineTp python dauphine
Tp python dauphinenoussa krid
 
« LabVIEW : programmation et applications » ou comment apprendre à utiliser L...
« LabVIEW : programmation et applications » ou comment apprendre à utiliser L...« LabVIEW : programmation et applications » ou comment apprendre à utiliser L...
« LabVIEW : programmation et applications » ou comment apprendre à utiliser L...Luc Desruelle
 
C028AL_slides_module1-fr-gz.pdf
C028AL_slides_module1-fr-gz.pdfC028AL_slides_module1-fr-gz.pdf
C028AL_slides_module1-fr-gz.pdfABID303441
 
Geneva jug Lucene Solr
Geneva jug Lucene Solr Geneva jug Lucene Solr
Geneva jug Lucene Solr francelabs
 
Algorithmique_et_programmation_part2
Algorithmique_et_programmation_part2Algorithmique_et_programmation_part2
Algorithmique_et_programmation_part2Emeric Tapachès
 

Similaire à Logo (20)

Réalisation d'un compilateur de mini langage - Khawarizmi
Réalisation d'un compilateur  de mini langage - KhawarizmiRéalisation d'un compilateur  de mini langage - Khawarizmi
Réalisation d'un compilateur de mini langage - Khawarizmi
 
compilation1-2020.pdf
compilation1-2020.pdfcompilation1-2020.pdf
compilation1-2020.pdf
 
Recherche de citations
Recherche de citationsRecherche de citations
Recherche de citations
 
Dev Web 101 #2 : development for dummies
Dev Web 101 #2 : development for dummiesDev Web 101 #2 : development for dummies
Dev Web 101 #2 : development for dummies
 
Chapitre 1 (algorithme)
Chapitre 1 (algorithme)Chapitre 1 (algorithme)
Chapitre 1 (algorithme)
 
Samar - Premier bilan d'étape - Oct. 2010
Samar - Premier bilan d'étape - Oct. 2010Samar - Premier bilan d'étape - Oct. 2010
Samar - Premier bilan d'étape - Oct. 2010
 
Xml
XmlXml
Xml
 
Langage C++
Langage C++Langage C++
Langage C++
 
Compilationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
CompilationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnCompilationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
Compilationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
 
Tp python dauphine
Tp python dauphineTp python dauphine
Tp python dauphine
 
Tp python
Tp pythonTp python
Tp python
 
System SG
System SGSystem SG
System SG
 
Php seance1
Php seance1Php seance1
Php seance1
 
« LabVIEW : programmation et applications » ou comment apprendre à utiliser L...
« LabVIEW : programmation et applications » ou comment apprendre à utiliser L...« LabVIEW : programmation et applications » ou comment apprendre à utiliser L...
« LabVIEW : programmation et applications » ou comment apprendre à utiliser L...
 
C028AL_slides_module1-fr-gz.pdf
C028AL_slides_module1-fr-gz.pdfC028AL_slides_module1-fr-gz.pdf
C028AL_slides_module1-fr-gz.pdf
 
Pdf test
Pdf testPdf test
Pdf test
 
Machine Translation
Machine TranslationMachine Translation
Machine Translation
 
Compilation
CompilationCompilation
Compilation
 
Geneva jug Lucene Solr
Geneva jug Lucene Solr Geneva jug Lucene Solr
Geneva jug Lucene Solr
 
Algorithmique_et_programmation_part2
Algorithmique_et_programmation_part2Algorithmique_et_programmation_part2
Algorithmique_et_programmation_part2
 

Plus de Elsa Friscira

Draw In The Air Android App
Draw In The Air Android AppDraw In The Air Android App
Draw In The Air Android AppElsa Friscira
 
GroupFun HCI Lab - EPFL
GroupFun HCI Lab - EPFL GroupFun HCI Lab - EPFL
GroupFun HCI Lab - EPFL Elsa Friscira
 
GroupFun design process poster
GroupFun design process posterGroupFun design process poster
GroupFun design process posterElsa Friscira
 
Ia02 friscira muller_rapport
Ia02 friscira muller_rapportIa02 friscira muller_rapport
Ia02 friscira muller_rapportElsa Friscira
 
ACM DEV '12 Proceedings of the 2nd ACM Symposium on Computing for Development
ACM DEV '12 Proceedings of the 2nd ACM Symposium on Computing for DevelopmentACM DEV '12 Proceedings of the 2nd ACM Symposium on Computing for Development
ACM DEV '12 Proceedings of the 2nd ACM Symposium on Computing for DevelopmentElsa Friscira
 

Plus de Elsa Friscira (6)

Draw In The Air Android App
Draw In The Air Android AppDraw In The Air Android App
Draw In The Air Android App
 
GroupFun HCI Lab - EPFL
GroupFun HCI Lab - EPFL GroupFun HCI Lab - EPFL
GroupFun HCI Lab - EPFL
 
GroupFun design process poster
GroupFun design process posterGroupFun design process poster
GroupFun design process poster
 
Ia02 friscira muller_rapport
Ia02 friscira muller_rapportIa02 friscira muller_rapport
Ia02 friscira muller_rapport
 
ACM DEV '12 Proceedings of the 2nd ACM Symposium on Computing for Development
ACM DEV '12 Proceedings of the 2nd ACM Symposium on Computing for DevelopmentACM DEV '12 Proceedings of the 2nd ACM Symposium on Computing for Development
ACM DEV '12 Proceedings of the 2nd ACM Symposium on Computing for Development
 
ACM Dev 2012
ACM Dev 2012ACM Dev 2012
ACM Dev 2012
 

Logo

  • 1.   NF11  -­‐  Génération  d'analyseur  lexical  et   syntaxique   Fayçal  Laatef  &  Friscira  Elsa     Groupe  p014       Objectifs   • Créer  une  grammaire  du  langage  Logo  et  une  représentation  intermédiaire  d’un   programme  Logo.   • Générer  un  analyseur  syntaxique  de  cette  grammaire.   • Créer  un  interpréteur  graphique  du  langage  Logo.   • Crée  une  table  des  symboles  d’un  programme.   • Vérifier  quelques  conditions  sémantiques.               1  
  • 2.   Table  des  matières   OBJECTIFS  ............................................................................................................................................................  1   I.  INTRODUCTION,  QU'EST  CE  QUE  LOGO?  .............................................................................................  3   II.  STRUCTURE  DE  NOTRE  PROJET  ...........................................................................................................  3   III.  LEXER,  PARSER  ET  INTERPRETEUR  DU  LANGAGE  LOGO  ...........................................................  4   A.  INTRODUCTION  ................................................................................................................................................  4   C.  ANALYSE  SYNTAXIQUE:  LE  PARSER  (LOGO.G)  ................................................................................................  5   D.  ANALYSE  SEMANTIQUE:  TREE  WALKER  (LOGOTREE.G)  ...............................................................................  6   E.  EN  RESUME,  COMMENT  AJOUTER  UNE  FONCTIONNALITE?  .............................................................................  7   E.  QUELLES  FONCTIONNALITES  AVONS-­‐NOUS  AJOUTEES?   ..................................................................................  7   PRINCIPALES  COMMANDES  DE  LA  TORTUE  ..........................................................................................................................  7   EXPRESSIONS  ARITHMETIQUES  .............................................................................................................................................  8   EXPRESSIONS  BOOLEENNES  ...................................................................................................................................................  9   IDENTIFICATEURS,  AFFECTATION  .........................................................................................................................................  9   IV.  STRUCTURES  DE  CONTROLE  .............................................................................................................  12   EVALUATION  DIFFEREE  D'UNE  ARBORESCENCE  ..............................................................................................................  12   LA  REPETITION  ......................................................................................................................................................................  13   L'ALTERNATIVE  (SI)  .............................................................................................................................................................  14   V.  PROCEDURES  ET  FONCTIONS  .............................................................................................................  15   PROCEDURES  ..........................................................................................................................................................................  15   REMARQUES:  .....................................................................................................................................................  17   VI.  ELEMENTS  NON  TRAITES  ET  DIFFICULTES  RENCONTREES  ....................................................  18   ..........................................................................................................................................  18   VII.  CONCLUSION                             2    
  • 3.   I.  Introduction,  qu'est  ce  que  Logo?     Le  langage  Logo  est  un  langage  de  programmation  qui  recouvre    deux  concepts:   • un  mode  d’apprentissage  inspiré  des  travaux  de  Jean  Piaget  sur  le  développement   cognitif  de  l’enfant   • un  type  d’environnement  informatique,  à  partir  d'un  langage  adapté  du  LISP     Le  langage  Logo  est  connu  pour  sa  simplicité  mais  est  également  capable  de  manipuler  des   expressions  arithmétiques,  des  expressions  booléennes  ou  de  mettre  en  place  des  structures   de  contrôles  telles  que  les  conditions,  les  boucles,  les  procédures  et  les  fonctions.     Le  but  de  ce  projet  est  de  créer  un  analyseur  lexical  et  syntaxique  du  langage  Logo.       Pour  cela,  nous  avons  utilisé  AntLR  (Another  Tool  for  Language  Recognition).  AntLR  est  un   outil  de  génération  automatique  d'analyseur  permettant  de  reconnaître  les  phrases  d'un   programme  écrit  dans  un  langage  donné.   II.  Structure  de  notre  projet         3  
  • 4.     L'interface  graphique,  réalisée  par  Claude  Moulin,  nous  permet  d'observer  et  de  valider  le   travail  de  développement  des  grammaires  que  nous  réalisons.           L'objectif  du  projet  est  de  réaliser  une  grammaire  du  langage  LOGO  afin  de  pouvoir   l'analyser.  Il  y  a  donc  trois  types  d'analyses  à  réaliser:   1. l'analyse  lexicale   2. l'analyse  syntaxique   3. l'analyse  sémantique  (traitement  à  partir  de  l'arbre  AST)   Remarque:  AntLR  utilise  une  analyse  descendante  de  type  LL.   III.  Lexer,  Parser  et  interpréteur  du  langage  Logo     a.  Introduction     Pour  réaliser  les  analyses  lexicales  et  syntaxiques  du  langage  LOGO,  nous  avons  spécifié  une   grammaire  (Lexer,Parser)  qui  décrit  la  façon  de  découper  un  flux  de  caractères  en  un  flux  de   mots  du  langage  (tokens)  puis  d'analyser  le  flux  sortant.   Avec  AntLR,  nous  avons  créé  un  fichier  "nomFichier.g"  définissant  les  unités  lexicales  et   syntaxiques  de  la  grammaire.  AntLR  a  ensuite  créer  lui  même  un  fichier  annexe  contenant  la   grammaire  du  lexer.  Enfin,  il  a  généré  les  classes  correpondant  au  lexer  et  au  parser.               4    
  • 5.     b.  Analyse  lexicale:  le  lexer  (Logo.g)     L'analyseur  lexical  (ou  lexer)  est  l'outil  qui  permet  de  découper  un  flux  de  caractères  en  un   flux  de  mots  du  langage:  les  tokens.     Flux  de  caractères    =>  Flux  de  tokens     Ajout  des  tokens  au  lexer  dans  la  grammaire  Logo.g:           c.  Analyse  syntaxique:  le  parser  (Logo.g)     L'analyseur  syntaxique  (ou  parser)  vérifie  que  l'ensemble  des  mots  issus  de  l'analyse  lexicale   (tokens)  forme  une  phrase  syntaxiquement  correcte.  Le  parser  va  donc  générer  un  arbre   syntaxique  abstrait  (AST)  à  partir  des  tokens  générés  par  le  lexer.     Flux  de  tokens  =>  AST     Nous  avons  utilisée  la  règle  suivante  du  parser  comme  axiome  de  notre  grammaire:         Remarque  importante:  Ici,  nous  avons  utilisé  un  token  imaginaire:  PROGRAMME.  Cela  nous   permet  de  résoudre  les  problèmes  de  récursivité  à  gauche.   En  effet,  AntLR  réalise  une  analyse  descendante  de  type  LL  et  nous  avons  vu  en  cours,   qu'une  grammaire  récursive  à  gauche  ne  pouvait  pas  être  LL(1).         5  
  • 6.   AntLR  donne  la  possibilité  de  créer  automatiquement,  semi  automatiquement  ou   manuellement  l'arbre  AST.  Dans  le  fichier  Logo.g,  nous  avons  ajouté  une  section  option   indiquant  au  parser  de  créer  l'arbre  AST:         Les  méthodes  du  parser  associées  aux  règles  de  la  grammaire  ne  sont  alors  plus  de  type  void   mais  d'un  type  structuré  dont  le  nom  reprend  celui  de  la  méthode.   Que  fait  AntLR?   Pour  chaque  règle:  AntLR  crée  une  racine  d'arborescence     Pour  chaque  token  présent  dans  une  règle:   • AntLR  crée  un  noeud  (Tree)   • Ajoute  ce  noeud  comme  fils  du  noeud  courant  (les  noeuds  forment  donc  une  liste)   • Attache  les  noeuds  de  la  liste  à  un  noeud  racine  de  type  nil.         Ajout  des  instructions  au  parser  dans  la  grammaire  Logo.g:         Les  noeuds  AV,  TD  et  TG  dans  l'exemple  ci-­‐dessus  sont  des  noeuds  racine  car  ils  sont  suffixés   avec  un  symbole  ^.  Au  contraire,  pour  ne  pas  créer  de  noeud  avec  un  token,  on  peut  le   suffixer  avec  un  symbole  !.     d.  Analyse  sémantique:  tree  Walker  (LogoTree.g)     Le  tree-­‐walker  parcourt  l'arbre  AST  généré  par  le  parser  et  exécute  les  actions.     Pour  les  fonctionnalités  concernant  l'UI  (qui  consistent  à  tracer  un  trait  sur  l'écran  en  se   déplaçant  par  exemple),  nous  avons  fait  appel  à  la  classe  Traceur.         Pour  les  autres  fonctionnalités  comme  par  exemple  l'affectation  de  variables,  nous  avons   fait  appel  à  des  fonctions  que  nous  avons  développées  dans  la  classe  LogoUtil.java.     6    
  • 7.       e.  En  résumé,  comment  ajouter  une  fonctionnalité?   Pour  ajouter  une  fonctionnalité,  il  faut:   Dans  la  grammaire  Logo.g:   1. Ajouter  un  token  au  lexer     2. Ajouter  une  instruction  au  parser     3. Sauvegarder  (les  classes  lexer  et  parser  sont  générées)       Dans  la  grammaire  LogoTree.g:   1. Ajouter  le  parsing  d'un  arbre     2. Faire  générer  le  parseur  d'arbre   3. Ajouter  une  méthode  à  la  classe  logogui.Traceur       e.  Quelles  fonctionnalités  avons-­‐nous  ajoutées?   Principales  commandes  de  la  tortue   Nous  avons  implémenté  les  commandes  de  base  permettant  à  la  tortue  d'avancer,   d'effectuer  une  rotation,  de  reculer  ...     Lexer  (Logo.g)       Parser  (Logo.g)               7  
  • 8.   Tree-­‐Walker  (LogoTree.g)         Pour  les  instructions  élémentaires  suivantes  (CF  fenêtre  de  gauche),  l'arbre  suivant  (fenêtre   de  droite)  est  généré  par  le  parser:         La  représentation  AntLR  sous  forme  de  liste  est  la  suivante:     (PROGRAMME  (FPOS  [500  500])  (AV  100)  (TD  300)  )       AntLR  utilise  deux  tokens  imaginaires:  UP  et  DOWN  pour  indiquer  les  niveaux  dans  l'arbre.       Expressions  arithmétiques     Nous  avons  implémenté  certaines  opérations  arithmétiques  telles  que  l'addition,  la   soustraction,  la  multiplication,  la  division  et  l'opération  puissance.   Afin  de  créer  une  grammaire  non  ambigüe,  nous  avons  donné  la  priorité  aux  opérateurs   multiplier  et  diviser  sur  les  opérateurs  additionner  et  soustraire.     Lexer  (Logo.g)                 8    
  • 9.   Parser  (Logo.g)       Tree-­‐Walker  (LogoTree.g)       Expressions  booléennes     De  la  même  façon  que  pour  les  expressions  arithmétiques,  nous  avons  implémenté  les   expressions  booléennes  de  base  telles  que  égal,  différent,  supérieur  et  inférieur.     Parser  (Logo.g)       Tree-­‐Walker  (LogoTree.g)         Identificateurs,  affectation     Variables  globales     La  déclaration  et  l’affectation  d’une  variable  globale  sont  effectuées  grâce  au  mot-­‐clé   DONNE.  Dans  le  tree-­‐walker,  nous  appelons  la  méthode  setVar(String,Double)  définie  dans   la  classe  LogoUtil  du  fichier  LogoUtil.java.           9  
  • 10.   Tree-­‐Walker  (LogoTree.g)         LogoUtil.java       La  fonction  setVar  de  la  classe    LogoUtil  stocke  les  variables  dans  une  table  de  hachage   "variables"  qui  associe  le  nom  de  la  variable  (String)  à  sa  valeur  (Double).       Variables  locales     Pour  les  variables  locales,  nous  avons  du  gérer  le  problème  des  portées  imbriquées.     Nous  avons  représenté  chaque  portée  par  une  hashmap  contenant  le  dictionnaire  des   symboles  qui  sont  déclarés  dans  la  portée  concernée.     Pour  gérer  le  problème  des  portées  imbriquées,  nous  avons    donc  utilisé  une  pile  de   hashmap.   • A  chaque  fois  que  nous  rentrons  dans  un  bloc,  nous  empilons  la  hashmap  contenant   les  variables  locales  déclarées  dans  ce  bloc     • A  chaque  fois  que  nous  sortons  d'un  bloc,  nous  dépilons  cette  hashmap    (qui  se   trouve  au  sommet  de  la  pile)     Ainsi,  avec  cette  méthode,  la  portée  courante  courante  est  toujours  la  portée  au  sommet  de   la  pile.     Contexte  d'un  symbole  =  portée  dans  laquelle  il  est       (+  portées    dans  laquelle  la  portée  est  imbriquée)  éventuellement                 10    
  • 11.   LogoUtil.java           Insertion  d'un  identificateur  dans  un  contexte     L’insertion  d’un  identificateur  se  fait  dans  le  dictionnaire  de  la  portée  en  sommet  de  pile.     Recherche  d'un  identificateur  dans  un  contexte     Pour  rechercher  un  identificateur  nous  utilisons  son  contexte  (qui  possède  une  pile  de   portées  donc  une  pile  de  hashmaps).  Nous  cherchons  donc  l'identificateur  dans  cette  pile  de   portées  de  la  façon  suivante:   1. nous  regardons  si  l'identificateur  se  situe  dans  la  portée  courante  (donc  au  sommet   de  la  pile  de  portées  du  contexte)   2. si  nous  ne  trouvons  pas  l'identificateur  dans  la  portée  courante,  nous  parcourons  la   pile  élément  par  élément  jusqu'à  trouver  l'identificateur.  (parcours  de  la  portée  la   plus  récente  à  la  portée  la  plus  ancienne)   3. si  nous  ne  trouvons  pas  l'identificateur  dans  la  pile  de  portée  (donc  s'il  n'est  dans   aucune  portée)  alors  nous  regardons  dans  la  hashmap  contenant  les  variables   globales.     4. si  l'identificateur  n'est  pas  dans  cette  hashmap,  il  n'est  pas  défini.                     11  
  • 12.   LogoUtil.java         IV.  Structures  de  contrôle   Evaluation  différée  d'une  arborescence   Pour  les  structures  de  contrôle  qui  suivent,  nous  avons  utilisé  le  parsing  différé.     En  quoi  cela  consiste-­‐t-­‐il?   Le  parsing  différé  se  fait  à  l'aide  d'une  règle  que  l'on  écrit  dans  la  grammaire.  On  mémorise   l'index  sur  lequel  cette  règle  doit  commencer  le  matching.   Avant  d'appeler  la  méthode  du  parser  associée  à  la  règle,  on  empile  l'index  sur  lequel  elle   doit  commencer  le  matching  et  on  dépile  ensuite  le  noeud  qu'elle  aura  placé  pour  la  suite  du   matching  et  qui  s'avère  inutile.         12    
  • 13.   La  répétition   Repeat     Tree-­‐Walker  (LogoTree.g)       Nous  avons  placé  un  point  (.)  après  l'expression  "exp"  afin  que  le  parsing  ne  se  fasse  pas  par   défaut.  Le  point  représente  l'index  de  l'arborescence.           L'arbre  AntLR  associé  est  donc  le  suivant:     REPEAT  DOWN  <atom>  <.>  UP.     Rappel:  AntLR  utilise  deux  tokens  imaginaires:  UP  et  DOWN  pour  indiquer  les  niveaux  dans   l'arbre.     La  règle  list_evaluation  doit  connaître  l'index  de  l'arborescence  car  lorsqu'elle  va  être   appelée,  elle  va  devoir  dépiler  cet  index.     Le  code  situé  dans  la  boucle  FOR  ci-­‐dessus  effectue  les  actions  suivantes:   • empile  l'index  du  noeud  racine  traité  par  list_evaluation   push(mark_list)   • appelle  la  méthode  list_evaluation list_evaluation()  =  règle  qui  permet  de  parser  un  arbre  dont  la  racine  est  le  token   LIST  et  dont  les  fils  sont  les  instructions     13  
  • 14.   • dépile  le  noeud  superflu  que  list_evaluation  va  empiler   pop()     Les  méthode  push() et  pop()  sont  des  méthodes  que  nous  avons  développées  dans   LogoTree.g  afin  d'alléger  l'écriture:           While     Pour  le  while,  nous  avons  suivi  la  même  méthode  que  pour  le  repeat.         Tree-­‐Walker  (LogoTree.g)       L'alternative  (si)     Dans  le  cas  de  l'alternative,  nous  utilisons  la  possibilité  d'ignorer  une  branche  de  l'arbre  au   cours  du  parcours  initial  et  d'y  revenir  par  la  suite  en  sauvegardant  son  index.   La  particularité  de  l'instruction  alternative  est  que  le  second  bloc  d'instructions  est  facultatif.       Si  l'expression  booléenne  renvoie  vraie  alors  exécuter  le  bloc  1  sinon  exécuter  le  bloc  2   (optionnel  car  "?"):       14    
  • 15.       Nous  initialisons  le  marqueur  d'index  (mark_list2)  à  0.  La  récupération  de  l'index  a  lieu  grâce   à  la  méthode  "input.mark()"que  l'on  affecte  à  mark_list2.       Si  mark_list2>0  alors  nous  pouvons  traiter  le  second  bloc  d'instructions,  sinon,  l'interpréteur   ne  l'a  pas  trouvé.     Tree-­‐Walker  (LogoTree.g)       V.  Procédures  et  fonctions   Procédures     Afin  de  générer  des  branches  d'instructions  qui  seront  plus  facilement  accessibles  lors  du   parcours  de  l'arbre  AST,  nous  avons  créé  deux  tokens  imaginaires:  ARG  et  et  PARAM.   ARG  est  utilisé  lors  de  la  déclaration  de  notre  procédure.   PARAM  est  utilisé  lors  de  l'appel  de  notre  procédure.           Nous  avons  également  créé  une  classe  Procedure  qui  contient  les  deux  structures  suivantes:   • une  liste  ordreParam  utilisée  pour  enregistrer  les  paramètres  et  leur  ordre  au   moment  de  la  déclaration  de  notre  procédure       15  
  • 16.   private ArrayList<String> ordreParam;   • une  hashmap  params  utilisée  pour  associer  une  valeur  à  chaque  variable  lors  de   l'appel  de  notre  procédure   private ArrayList<String> ordreParam;         Déclaration  d'une  procédure           La  fonction  "pushProcedure"  définie  dans  la  classe  LogoUtils,  va  nous  permettre  d'empiler   notre  procédure  sur  une  pile  de  procédures  afin  de  simplifier  l'ajout  des  paramètres    lors  de   la  déclaration.                                   16    
  • 17.   Appel  d'une  procédure         On  va  récupérer  le  nom  de  la  procédure  en  cours  et  on  va  dire  à  notre  variable  de  type   LogoUtil  (u)  de  récupérer  la  procédure  du  nom  contenu  dans  la  variable:  "nameProc"  c'est  à   dire  de  la  chercher  dans  la  pile  puis  de  l'extraire  de  cette  pile.  On  va  ensuite  modifier  cette   procédure  en  associant  une  valeur  à  chaque  variable  déclarée  lors  de  la  déclaration  de   procédure.     Remarque:     Arité  d'une  procédure   La    méthode  getArite()  dans  notre  classe  Procedure  vérifie  que  le  nombre  de  paramètres   passés  lors  de  l'appel  de  cette  procédure  (  dans  la  hashmap  params)  est  bien  égal  au  nombre   de  paramètres  déterminé  lors  de  la  déclaration  de  cette  procédure  (dans  la  liste   ordreParam).       17  
  • 18.     VI.  Eléments  non  traités  et  difficultés  rencontrées     Eléments  non  traités   Faute  de  temps,  nous  n'avons  pas  implémenté  les  fonctionnalités  suivantes:   • Les  procédures  récursives   • La  primitive  LOOP  qui  renvoie  le  nombre  de  tours  dans  une  boucle.   • La  primitive  STOP.   • La  possibilité  d'utiliser  les  opérateurs  AND  et  OR  dans  les  expressions  booléennes.     Difficultés  rencontrées   • Au  début  du  projet,  il  nous  a  fallu  du  temps  pour  nos  familiariser  la  syntaxe  et  le   fonctionnement  de  AntLR.   • Nous  avons  rencontré  quelques  difficultés  dans  la  gestion  des  tokens  imaginaires   générés  par  AntLR  <UP>  and  <DOWN>.  Cela  nous  créait  des  erreurs  de  marquage.  Il  y   avait  un  décalage  entre  l'arbre  que  l'on  créait  et  l'arbre  que  l'on  parsait.   VII.  Conclusion     Ce  projet  nous  a  permis  d'aller  plus  loin  dans  notre  compréhension  des  différents  types   d'analyse:  lexicale,  syntaxique  et  sémantique.  Il  nous  a  permis  également  de  voir  un  exemple   concret  et  d'appliquer  les  principes  théoriques  vus  en  cours.     Nous  avons  désormais  une  vision  globale  plus  claire  sur  les  différentes  phases  allant  de   l'écriture  à  l'exécution  d'un  programme.   18