| | 1 | {{{ |
| | 2 | #!html |
| | 3 | <h1>TME4 : Ecriture d'un parser lofig</h1> |
| | 4 | }}} |
| | 5 | [[PageOutline]] |
| | 6 | |
| | 7 | = Introduction = |
| | 8 | |
| | 9 | Ce TME constitue la suite du TME3 sur lex et yacc. Cette seconde partie a pour but de |
| | 10 | vous faire construire en mémoire la structure de données \emph{lofig} présentée en cours. |
| | 11 | A chaque règle importante de la grammaire correspond la création d'un objet de la |
| | 12 | structure de données \emph{lofig}. |
| | 13 | |
| | 14 | Nous faisons l'hypothèse que le scanner et le parser du TME4 sont achevés. |
| | 15 | Vous êtes invités à utiliser vos propres fichiers vst.l et vst.y, mais vous pouvez également |
| | 16 | utiliser les fichiers vst.l et vst.y fournis avec ce TME. ces fichiers contiennent |
| | 17 | cependant quelques erreurs que vous devrez corriger afin de vous obliger à les comprendre. |
| | 18 | |
| | 19 | = Etape 1 : Communication entre le scanner et le parser = |
| | 20 | |
| | 21 | Dans le TME3, portant sur l'analyse syntaxique du format .vst, le scanner transmettait au parser |
| | 22 | des numéros de tokens définissant le type des tokens reconnus. cela a permis de vérifier que |
| | 23 | les règles de grammaire étaient correctement écrites, et que les constructions grammaticales |
| | 24 | du format .vst étaient correctement reconnues. |
| | 25 | |
| | 26 | Chaque fois que le scanner reconnait un token, il peut également transmettre au parser |
| | 27 | une valeur associée à ce token, en utilisant la variable globale yylval. |
| | 28 | Le type de la valeur associée à un token peut être différent suivant le token |
| | 29 | (ce peut être une valeur numérique, ou un pointeur sur chaîne de caractères, ou autre chose). |
| | 30 | Il faut donc définir, pour chaque token auquel on souhaite associer une valeur, |
| | 31 | le type de la valeur qui sera stockée dans la variable yylval. |
| | 32 | |
| | 33 | Dans cette étape, on ne va pas directement construire la structure de données \emph{lofig}, |
| | 34 | mais on va se contenter d'introduire dans le parser les \emph{actions de compilation} lui |
| | 35 | permettant d'afficher sur le terminal (en utilisant printf) le texte correspondant aux différentes |
| | 36 | constructtions grammaticales reconnues. Dans cette première étape, on se limitera même |
| | 37 | à afficher les constructions grammaticales correspondant à la partie {{{entity}}} du |
| | 38 | fichier analysé. Le but ici est simplement de vérifier le mécanisme de transmission |
| | 39 | de valeurs entre le scanner et le parser. |
| | 40 | |
| | 41 | Il faut pour cela modifier les deux fichiers vst.l et vst.y. |
| | 42 | |
| | 43 | * Déterminez quels tokens retournent une valeur significative |
| | 44 | (les tokens n'ont pas tous une valeur). Dans le fichier vst.y, typez |
| | 45 | les tokens qui doivent l'être en utilisant la construction \verb+%token |
| | 46 | <type> TOKEN+. |
| | 47 | * On rappelle que pour chaque token reconnu par le parser, la chaîne de caractères |
| | 48 | correspondant à ce token est stockée dans un buffer pointé par la variable |
| | 49 | {{{yytext}}}, et que le scanner réutilise ce même buffer pour chaque nouveau token. |
| | 50 | Quand on souhaite que le scanner transmette cette chaîne au parser, il faut que le scanner |
| | 51 | recopie cette chaîne de caractères dans un autre buffer et transmette au parser un pointeur sur |
| | 52 | ce nouveau buffer. Il faut donc mofifier le fichier vst.l en conséquence. |
| | 53 | * Le type de la variable yylval contenant la valeur du token est défini |
| | 54 | dans le fichier vst.y, en utilisant le mot clé {{{%union}}}. |
| | 55 | Modifier le fichier vst.y en conséquence. |
| | 56 | * Pour permettre aux différentes règles du parser de communiquer entre elles, il faut également |
| | 57 | définir le type de la variable associée à chacune des règles du parser qui renvoient une valeur. |
| | 58 | On rappelle que la valeur associée à un token dans une règle est stockée dans la variable {{{$i}}} |
| | 59 | (où i est l'index du token dans la règle), et que la valeur du token défini par la règle |
| | 60 | (c'est à dire la valeur du membre de gauche) est stockée dans la variable {{{$$}}}. |
| | 61 | Modifier le fichier vst.y pour définir le type des token associés aux règles du parser |
| | 62 | en utilisant la construction {{{%type <type> règle}}}. |
| | 63 | * Ajouter les affichages, c'est à dire les actions de compilation associées aux règles |
| | 64 | qui interviennent dans la partie "entity" du fichier exemple.vst. On |
| | 65 | pourra pour cela définir dans le fichier vst.y un objet de type {{{port_t}}}, |
| | 66 | permettant de représenter un ensemble de ports sous forme de liste chaînée. |
| | 67 | Chaque objet {{{port_t}}} comporte un champs "NAME" définissant son nom, |
| | 68 | un champs "TYPE" définissant sa direction, et un champs "NEXT" permettant |
| | 69 | de construire une liste chaînée. On introduira dans les règles "port" |
| | 70 | et "ports" les actions permettant de construire la liste des ports, et on |
| | 71 | utilisera dans la règle "entity" une boucle for pour parcourir cette liste |
| | 72 | et afficher les ports. |
| | 73 | |
| | 74 | ''Avertissement : Bison émet un avertissement "type clash on default action" pour certaines |
| | 75 | règles, lorsque l'action de compilation n'est pas définie. En effet, il effectue par défaut |
| | 76 | l'opération {{{{$$ = $1}}}}, et il proteste lorsque les deux tokens n'ont pas le même type. |
| | 77 | Il faut définir une action de compilation vide {{{{}}}} pour éviter ce problème.'' |
| | 78 | |
| | 79 | = Etape 2 : Affichage du fichier complet = |
| | 80 | |
| | 81 | Dans cette seconde partie, on souhaite complêter les actions de compilation définies |
| | 82 | dans le fichier vst.y, de façon à afficher la totalité du fichier exemple.vst, |
| | 83 | sous une forme qui respecte la syntaxe du format .vst. |
| | 84 | Il faut donc traiter les constructions grammaticales |
| | 85 | correspondant à la partie "architecture" du fichier. |
| | 86 | |
| | 87 | 1. On commencera par introduire dans la règle "architecture" |
| | 88 | les actions de compilations permettant d'afficher le début et la fin de la section |
| | 89 | "architecture". |
| | 90 | 1. Introduire dans les règles "component" et "signal" |
| | 91 | les actions de compilation permettant d'afficher les components et les signaux. |
| | 92 | 1. Introduire dans les règles "instances", "links" et "link" les actions de |
| | 93 | compilation permettant d'afficher les instances. On pourra pour cela définir dans |
| | 94 | le fichier .vst un objet de type {{{link_t}}}, permettant de représenter un ensemble |
| | 95 | de links sous forme d'une liste chaînée. On pourra s'inspirer de ce qui a été |
| | 96 | fait dans la première étape pour l'objet {{{port_t}}}. |
| | 97 | 1. Vérifier que le fichier texte généré par votre parser respecte la syntaxe |
| | 98 | du format .vst, en utilisant le parser pour analyser le fichier qu'il a généré. |
| | 99 | |
| | 100 | |
| | 101 | = Etape 3 : Construction de la structure lofig = |
| | 102 | |
| | 103 | La construction de la structure mémoire lofig fait appel à des fonctions spéficiques. |
| | 104 | \emph{Une page de manuel} existe pour chacun des objets de cette structure et chacune |
| | 105 | de ces fonctions. Nous vous invitons à les consulter. |
| | 106 | |
| | 107 | Les différents objets dont vous aurez besoin sont: |
| | 108 | * {{{lofig}}} pour représenter l'\emph{entity} et les \emph{component}s; |
| | 109 | * {{{losig}}} pour représenter les \emph{signal}s; |
| | 110 | * {{{loins}}} pour représenter les \emph{instances}; |
| | 111 | * {{{locon}}} pour représenter les \emph{port}s; |
| | 112 | * {{{chain}}} est une structure utilitaire qui contient deux pointeurs. |
| | 113 | \end{itemize} |
| | 114 | |
| | 115 | La structure chain permet en particulier de construire des ensembles d'objets |
| | 116 | de même type sous forme de listes chaînées (ensembles de signaux possédant |
| | 117 | une caractéristique commune par exemple). |
| | 118 | |
| | 119 | Les différentes fonctions dont vous aurez besoin sont: |
| | 120 | \begin{itemize}\itemsep=-.4ex |
| | 121 | \item {{{mbkenv}}} pour initialiser le fonctionnement des bibliothèques d'\textbf{Alliance} |
| | 122 | (cette fonction ne prend aucun paramètre et ne rend rien mais elle intialise un certain |
| | 123 | nombre de variables globales et elle lit l'environnement unix concernant Alliance. |
| | 124 | Elle doit etre invoquée au début de la fonction main(). |
| | 125 | \item {{{addlofig}}} pour créer l'\emph{entity} et les \emph{component}s; |
| | 126 | \item {{{getlofig}}} qui renvoie un pointeur vers une figure désignée par son nom; |
| | 127 | \item {{{addlocon}}} pour créer les \emph{port}s, aussi bien dans les figures que dans les instances; |
| | 128 | \item {{{addlosig}}} pour créer les \emph{signal}s; |
| | 129 | \item {{{addloins}}} pour créer les \emph{instance}s; |
| | 130 | \item {{{addchain}}} pour créer les bipointeurs; |
| | 131 | \item {{{reverse}}} pour «~retourner~» l'ordre des éléments dans une liste de type chain; |
| | 132 | \item {{{freechain+ pour libérer une liste créée par \verb+\addchain}}}; |
| | 133 | \item {{{namealloc}}} pour insérer tous les noms (chaînes de caractères) dans un dictionnaire. |
| | 134 | Grâce à cette fonction, $n$ pointeurs représentant $n$ chaînes de caractères identiques pointent |
| | 135 | sur une unique zone de mémoire, permettant de tester l'égalité des pointeurs (par {{{==}}}) |
| | 136 | en lieu et place de l'égalité de chaque caractère (par {{{strcmp}}}). |
| | 137 | \end{itemize} |
| | 138 | |
| | 139 | Un fichier utilisant ces types et fonctions doit inclure le fichier {{{alliance.h}}}, |
| | 140 | et l'édition de liens doit comporter {{{-lalliance}}}. Ces fichiers référencés se trouvent |
| | 141 | sous {{{~encadr/cao/include}}} et {{{~encadr/cao/lib}}}. Modifiez vos sources |
| | 142 | et votre {{{Makefile}}} en conséquence. |
| | 143 | |
| | 144 | Indication : Pour construire la structure de données, on est amené à manipuler plusieurs |
| | 145 | structures lofig : On a une structure lofig correspondant à l'{{{entity}}} dont on souhaite |
| | 146 | construire la net-list, mais on est amené à construire une structure lofig pour chacune |
| | 147 | des figures instanciées (c'est à dire pour chacun des {{{component}}}). Les structures |
| | 148 | lofig associées aux {{{component}}} sont des boîtes "vides", qui ne contiennent que |
| | 149 | la liste de porta, mais pas d'instances et pas de signaux. |
| | 150 | Vous utiliserez deux variables globales, l'une pointant sur la figure représentant |
| | 151 | l'{{{entity}}}, et l'autre pointant sur le {{{component}}} en cours d'analyse, |
| | 152 | et vous construirez la structure de donnée dans l'ordre suivant: |
| | 153 | |
| | 154 | 1. ajoutez la figure; |
| | 155 | 1. ajoutez les ports de la figure et les signaux externes; |
| | 156 | 1. ajoutez les components; |
| | 157 | 1. ajoutez les signaux internes; |
| | 158 | 1. ajoutez les instances. |
| | 159 | Vous ferez l'hypothèse simplificatrice que les connecteurs de |
| | 160 | l'instance (port map) \emph{sont dans le même ordre} que les connecteurs du |
| | 161 | modèle (component); |
| | 162 | |
| | 163 | Pour vous aider à déboguer et vérifier que la construction est correcte, vous pouvez utiliser |
| | 164 | la fonction {{{viewlofig}}}. Vous pouvez également sauvegarder sur disque la structure de données |
| | 165 | construite en mémoire en utilisant la fonction {{{savelofig}}}. |
| | 166 | Il est préférable de changer le nom de la figure avant d'effectuer la sauvegarde, |
| | 167 | sans oublier d'utiliser la fonction {{{namealloc}}}. |