| 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}}}. |