NF11	  -­‐	  Génération	  danalyseur	  lexical	  et	  syntaxique	  Fayçal	  Laatef	  &	  Friscira	  Elsa	  	  Groupe	  p0...
 Table	  des	  matières	  OBJECTIFS	  .......................................................................................
 I.	  Introduction,	  quest	  ce	  que	  Logo?	  	  Le	  langage	  Logo	  est	  un	  langage	  de	  programmation	  qui	  ...
 	  Linterface	  graphique,	  réalisée	  par	  Claude	  Moulin,	  nous	  permet	  dobserver	  et	  de	  valider	  le	  tra...
 	  b.	  Analyse	  lexicale:	  le	  lexer	  (Logo.g)	  	  Lanalyseur	  lexical	  (ou	  lexer)	  est	  loutil	  qui	  perme...
 AntLR	  donne	  la	  possibilité	  de	  créer	  automatiquement,	  semi	  automatiquement	  ou	  manuellement	  larbre	  ...
                                                                                            	  	  e.	  En	  résumé,	  comm...
 Tree-­‐Walker	  (LogoTree.g)	                                                                                            ...
 Parser	  (Logo.g)	                                                                          	  	  Tree-­‐Walker	  (LogoTr...
 Tree-­‐Walker	  (LogoTree.g)	                                                      	                                     ...
 LogoUtil.java	                                                                                                           ...
 LogoUtil.java	  	                                                                                                        ...
 La	  répétition	  Repeat	  	  Tree-­‐Walker	  (LogoTree.g)	                                                              ...
          •    dépile	  le	  noeud	  superflu	  que	  list_evaluation	  va	  empiler	                pop()	            	  ...
 	  	  Nous	  initialisons	  le	  marqueur	  dindex	  (mark_list2)	  à	  0.	  La	  récupération	  de	  lindex	  a	  lieu	 ...
               private ArrayList<String> ordreParam;              	           •    une	  hashmap	  params	  utilisée	  pou...
 Appel	  dune	  procédure	  	                                                                                             ...
                                                                                        	  VI.	  Eléments	  non	  traités	...
Prochain SlideShare
Chargement dans…5
×

Logo

342 vues

Publié le

0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
342
Sur SlideShare
0
Issues des intégrations
0
Intégrations
1
Actions
Partages
0
Téléchargements
3
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Logo

  1. 1.  NF11  -­‐  Génération  danalyseur  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. 2.  Table  des  matières  OBJECTIFS  ............................................................................................................................................................  1  I.  INTRODUCTION,  QUEST  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  DUNE  ARBORESCENCE  ..............................................................................................................  12  LA  REPETITION  ......................................................................................................................................................................  13  LALTERNATIVE  (SI)  .............................................................................................................................................................  14  V.  PROCEDURES  ET  FONCTIONS  .............................................................................................................  15  PROCEDURES  ..........................................................................................................................................................................  15  REMARQUES:  .....................................................................................................................................................  17  VI.  ELEMENTS  NON  TRAITES  ET  DIFFICULTES  RENCONTREES  ....................................................  18   ..........................................................................................................................................  18  VII.  CONCLUSION                            2    
  3. 3.  I.  Introduction,  quest  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  dun  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  danalyseur  permettant  de  reconnaître  les  phrases  dun  programme  écrit  dans  un  langage  donné.  II.  Structure  de  notre  projet         3  
  4. 4.    Linterface  graphique,  réalisée  par  Claude  Moulin,  nous  permet  dobserver  et  de  valider  le  travail  de  développement  des  grammaires  que  nous  réalisons.          Lobjectif  du  projet  est  de  réaliser  une  grammaire  du  langage  LOGO  afin  de  pouvoir  lanalyser.  Il  y  a  donc  trois  types  danalyses  à  réaliser:   1. lanalyse  lexicale   2. lanalyse  syntaxique   3. lanalyse  sémantique  (traitement  à  partir  de  larbre  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  danalyser  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. 5.    b.  Analyse  lexicale:  le  lexer  (Logo.g)    Lanalyseur  lexical  (ou  lexer)  est  loutil  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)    Lanalyseur  syntaxique  (ou  parser)  vérifie  que  lensemble  des  mots  issus  de  lanalyse  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,  quune  grammaire  récursive  à  gauche  ne  pouvait  pas  être  LL(1).         5  
  6. 6.  AntLR  donne  la  possibilité  de  créer  automatiquement,  semi  automatiquement  ou  manuellement  larbre  AST.  Dans  le  fichier  Logo.g,  nous  avons  ajouté  une  section  option  indiquant  au  parser  de  créer  larbre  AST:        Les  méthodes  du  parser  associées  aux  règles  de  la  grammaire  ne  sont  alors  plus  de  type  void  mais  dun  type  structuré  dont  le  nom  reprend  celui  de  la  méthode.  Que  fait  AntLR?  Pour  chaque  règle:  AntLR  crée  une  racine  darborescence    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  lexemple  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  larbre  AST  généré  par  le  parser  et  exécute  les  actions.    Pour  les  fonctionnalités  concernant  lUI  (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  laffectation  de  variables,  nous  avons  fait  appel  à  des  fonctions  que  nous  avons  développées  dans  la  classe  LogoUtil.java.    6    
  7. 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  dun  arbre     2. Faire  générer  le  parseur  darbre   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  davancer,  deffectuer  une  rotation,  de  reculer  ...    Lexer  (Logo.g)      Parser  (Logo.g)               7  
  8. 8.  Tree-­‐Walker  (LogoTree.g)        Pour  les  instructions  élémentaires  suivantes  (CF  fenêtre  de  gauche),  larbre  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  larbre.      Expressions  arithmétiques    Nous  avons  implémenté  certaines  opérations  arithmétiques  telles  que  laddition,  la  soustraction,  la  multiplication,  la  division  et  lopé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. 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. 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  dun  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  dun  symbole  =  portée  dans  laquelle  il  est       (+  portées    dans  laquelle  la  portée  est  imbriquée)  éventuellement                10    
  11. 11.  LogoUtil.java          Insertion  dun  identificateur  dans  un  contexte    L’insertion  d’un  identificateur  se  fait  dans  le  dictionnaire  de  la  portée  en  sommet  de  pile.    Recherche  dun  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  lidentificateur  dans  cette  pile  de  portées  de  la  façon  suivante:   1. nous  regardons  si  lidentificateur  se  situe  dans  la  portée  courante  (donc  au  sommet   de  la  pile  de  portées  du  contexte)   2. si  nous  ne  trouvons  pas  lidentificateur  dans  la  portée  courante,  nous  parcourons  la   pile  élément  par  élément  jusquà  trouver  lidentificateur.  (parcours  de  la  portée  la   plus  récente  à  la  portée  la  plus  ancienne)   3. si  nous  ne  trouvons  pas  lidentificateur  dans  la  pile  de  portée  (donc  sil  nest  dans   aucune  portée)  alors  nous  regardons  dans  la  hashmap  contenant  les  variables   globales.     4. si  lidentificateur  nest  pas  dans  cette  hashmap,  il  nest  pas  défini.                     11  
  12. 12.  LogoUtil.java        IV.  Structures  de  contrôle  Evaluation  différée  dune  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  à  laide  dune  règle  que  lon  écrit  dans  la  grammaire.  On  mémorise  lindex  sur  lequel  cette  règle  doit  commencer  le  matching.  Avant  dappeler  la  méthode  du  parser  associée  à  la  règle,  on  empile  lindex  sur  lequel  elle  doit  commencer  le  matching  et  on  dépile  ensuite  le  noeud  quelle  aura  placé  pour  la  suite  du  matching  et  qui  savère  inutile.        12    
  13. 13.  La  répétition  Repeat    Tree-­‐Walker  (LogoTree.g)      Nous  avons  placé  un  point  (.)  après  lexpression  "exp"  afin  que  le  parsing  ne  se  fasse  pas  par  défaut.  Le  point  représente  lindex  de  larborescence.          Larbre  AntLR  associé  est  donc  le  suivant:     REPEAT  DOWN  <atom>  <.>  UP.    Rappel:  AntLR  utilise  deux  tokens  imaginaires:  UP  et  DOWN  pour  indiquer  les  niveaux  dans  larbre.    La  règle  list_evaluation  doit  connaître  lindex  de  larborescence  car  lorsquelle  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  lindex  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. 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  dalléger  lécriture:          While    Pour  le  while,  nous  avons  suivi  la  même  méthode  que  pour  le  repeat.        Tree-­‐Walker  (LogoTree.g)      Lalternative  (si)    Dans  le  cas  de  lalternative,  nous  utilisons  la  possibilité  dignorer  une  branche  de  larbre  au  cours  du  parcours  initial  et  dy  revenir  par  la  suite  en  sauvegardant  son  index.  La  particularité  de  linstruction  alternative  est  que  le  second  bloc  dinstructions  est  facultatif.      Si  lexpression  booléenne  renvoie  vraie  alors  exécuter  le  bloc  1  sinon  exécuter  le  bloc  2  (optionnel  car  "?"):      14    
  15. 15.      Nous  initialisons  le  marqueur  dindex  (mark_list2)  à  0.  La  récupération  de  lindex  a  lieu  grâce  à  la  méthode  "input.mark()"que  lon  affecte  à  mark_list2.      Si  mark_list2>0  alors  nous  pouvons  traiter  le  second  bloc  dinstructions,  sinon,  linterpréteur  ne  la  pas  trouvé.    Tree-­‐Walker  (LogoTree.g)      V.  Procédures  et  fonctions  Procédures    Afin  de  générer  des  branches  dinstructions  qui  seront  plus  facilement  accessibles  lors  du  parcours  de  larbre  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  lappel  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. 16.   private ArrayList<String> ordreParam;   • une  hashmap  params  utilisée  pour  associer  une  valeur  à  chaque  variable  lors  de   lappel  de  notre  procédure   private ArrayList<String> ordreParam;        Déclaration  dune  procédure          La  fonction  "pushProcedure"  définie  dans  la  classe  LogoUtils,  va  nous  permettre  dempiler  notre  procédure  sur  une  pile  de  procédures  afin  de  simplifier  lajout  des  paramètres    lors  de  la  déclaration.                                  16    
  17. 17.  Appel  dune  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"  cest  à  dire  de  la  chercher  dans  la  pile  puis  de  lextraire  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é  dune  procédure  La    méthode  getArite()  dans  notre  classe  Procedure  vérifie  que  le  nombre  de  paramètres  passés  lors  de  lappel  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. 18.    VI.  Eléments  non  traités  et  difficultés  rencontrées    Eléments  non  traités  Faute  de  temps,  nous  navons  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é  dutiliser  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  larbre  que  lon  créait  et  larbre  que  lon  parsait.  VII.  Conclusion    Ce  projet  nous  a  permis  daller  plus  loin  dans  notre  compréhension  des  différents  types  danalyse:  lexicale,  syntaxique  et  sémantique.  Il  nous  a  permis  également  de  voir  un  exemple  concret  et  dappliquer  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  à  lexécution  dun  programme.  18    

×