Voie d'approfondissement Informatique - CS22, Traduction : TP NOTE

Consignes pour le rendu
PostScript est un langage directement interpreté par les imprimantes du même nom. C'est un langage de description
de graphique mais aussi un langage de programmation complet, pouvant faire des entrées-sorties, des transformations, ...
(a contrario PDF n'est qu'un format de fichier ; pour des traitements il faut disposer d'outils).

Un fichier PostScript commence par %!, et obéit a la grammaire PostScript. L'exemple suivant trace 2 rectangles,
l'un par tracé de contour seul ("stroke") en épaisseur 4 points, l'autre rempli (instruction "fill", en noir par défaut) :
newpath       débute un "chemin"
moveto        positionne au point x, y indiqué précédemment
rlineto       définit un segment, du point courant jusqu'au nouveau point
              qui devient le point courant
closepath     ajoute un segment vers le point de départ
setlinewidth  définit une largeur de tracé de trait
stroke        demande le tracé du contour défini depuis le dernier newpath
fill          demande le remplissage d'un contour (qui doit etre fermé)
     %!
     newpath
       300 400  moveto
       0   100  rlineto
       100 0    rlineto
       0  -100  rlineto
       closepath
       4 setlinewidth
       stroke
     newpath
       200 300 moveto
       0    50 rlineto
       150   0  rlineto
       0   -50  rlineto
       closepath
       fill
     showpage

(Noter que PostScript applique un principe de pile : les opérandes sur lesquels portent une opération sont cités avant l'opération, p.ex. dans 300 400 moveto) L'environnement Linux dispose de la commande "gv" (ghostview) permettant de visualiser un fichier PostScript avant impression. On peut lancer p.ex.: gv -geometry 200x200, puis File->Open et sélection du fichier à visualiser. Les buts de l'exercice sont : a) de reconnnaitre un (tout petit) sous-ensemble de la grammaire PostScript correspondant aux "paths" de l'exemple ci-dessus b) puis, pour illustrer les interactions entre langages, de générer un morceau de code Java qui, inséré dans un GUI fourni, visualise la page précédente ========================================================================== I - RECONNAISSANCE D'UN SOUS-ENSEMBLE PostScript 1.1 - Analyse lexicale seule : lex1.1.flex (3 pts) Reconnaitre toutes les unités lexicales possibles dans un texte d'entrée du type de l'exemple, avec impressions de vérification. 1.2 - Analyse (lexicale + syntaxique) : progression a suivre : NB - Pour chaque question Q à suivre, utiliser 2 spécifs lexQ.flex, gramQ.bison Utiliser l'organisation proposée au CI5.6 a) Passage des unités lexicales une par une : lex1.2a.flex, gram1.2a.bison (1.5 pt) - passer à l'analyseur syntaxique les catégories des unités lexicales - l'analyseur syntaxique fait une impression de vérification pour chacune NB - Pour chaque question Q à suivre, l'analyseur lexQ.flex derivera du precedent par simple changement de l'include b) Règles syntaxiques "de bas niveau" : lex1.2b.flex, gram1.2b.bison (1.5 pt) - ajouter les règles suivantes (les noms suggérés sont ceux de la tête de règle) . règle MoveTo, pour reconnaitre une instruction "moveto" . règle RLineTo, reconnaissant une instruction "rlineto" (2 opérandes cites avant) . règle SetLineWidth (1 opérande cité avant) - vérifier que l'analyseur fonctionne (malgré un conflit shift/reduce) c) règles syntaxiques intermédiaires : lex1.2c.flex, gram1.2c.bison (3 pts) - règle RLineToList reconnaissant une liste de RLineTo - règle FilledPolygon reconnaisant un "chemin" (newpath, moveto, liste de RLineTo) nécessairement clos et rempli - règle Polyline : chemin éventuellement fermé, suivi d'un SetLineWidth et d'un "stroke" d) reconnaissance de fichier PostScript tracant des polygones et polylines lex1.2d.flex, gram1.2d.bison (2 pts): - reconnaitre une liste de chemins (FilledPolygon ou PolyLine) - reconnaitre une "page", liste de chemins encadrée par prologue et "showpage" ========================================================================== II - GENERATION DE CODE POUR VISUALISEUR DE "PATHS" EN JAVA En ajoutant des actions aux regles syntaxiques, l'analyseur pourra générer des morceaux de code Java. Pour cela l'essentiel du code C nécessaire sera fourni. A la question 2.1 on mémorise dans des structures les informations obtenues par la reconnaissance. A la question 2.2, on génére en fin de reconnaissance les portions de code Java voulues. 2.1 - ENREGISTREMENT DES INFORMATIONS DANS DES STRUCTURES C a) Préliminaire : passage des valeurs entieres au niveau syntaxique : lex2.1a.flex, gram2.1a.bison (1.5 pt) - niveau syntaxique : ajouter une directive %union ; pour le moment le seul type int peut suffir - niveau lexical : pour chaque INT, passer sa valeur numérique - niveau syntaxique : impression de controle de la valeur obtenue b) Ajout d'actions dans les règles syntaxique (lex2.1bX.flex, gram2.1bX.bison) : Appelons "figure" l'objet défini par une construction newpath en PostScript. Le code C fourni figs.c définit des structures Fig et FigArray. Principe : - pour chaque objet Polyline ou FilledPolygon, on créera une structure Fig - on stockera l'ensemble des Figs ainsi definies dans un objet FigArray Indications : - utiliser d'autres variables C : référence sur la structure Fig courante (évite de la passer de règle en règle) coordonnées du point courant - pour simplifier, ce code fourni pourra être inclus dans la spécification Bison (!) mais penser à le mentionner dans le makefile - vous pouvez procéder graduellement, selon les indications ci-dessous, mais ne rendre que votre solution la plus complete b1) initialisation d'une Fig : une possibilité est d'avoir une regle NewPath pour la seule (1 pt) unite lexicale NEWPATH ; son action etant de creer une Fig b2) règle MoveTo : fixe le point courant (0.5 pt) b3) règle RLineTo : déduire des 2 arguments (déplacements par rapport au point courant actuel) (1 pt) les coordonnées du nouveau point courant, les mémoriser dans l'objet Fig courant b4) fermeture de chemin (1 pt) . générer un nouveau point identique au point de depart . peut être réalis&ecaute; dans une seule règle intermédiaire "ClosePath" b5) règle SetLineWidth (0.5 pt) : mémoriser la largeur dans la Fig courante, en tant que float b6) terminaison d'une Fig : . ajouter le code action 0 (stroke) pour une Polyline (1 pt) 1 (fill) pour un FilledPolygon . ajouter la référence de Fig dans le FigArray . impression de vérification b7) reconnaissance d'une "page" (supposée ne contenir que des "paths") (1 pt) : imprimer le contenu du FigArray 2.2 - GENERATION DE CODE Java, VISUALISATION Quand on a reconnu une page, a partir du contenu du FigArray, on génère un code Java correspondant ; soit pour l'exemple : v.content.addJFig( new JFig( new int[] { 300, 300, 400, 400, 300 }, new int[] { 300, 200, 200, 300, 300 }, 4.f, JFig.Action.STROKE ); ); v.content.addJFig( new JFig( new int[] { 200, 200, 350, 350, 200 }, new int[] { 300, 250, 250, 300, 300 }, 1.f, Fig.Action.FILL ); ); Note 1 - seuls les arguments des appels Java new JFig( ) sont variables, selon la figure L'instruction v.content.addJFig( xxx ); ajoute une figure au reste du code d'un interface graphique Java fourni, voir "Visualisation", en b) ci-dessous Note 2 - en toute rigueur, les coordonnées absolues ci-dessus ont été calculées en inversant le signe des déplacements verticaux (pour PostScript l'axe Oy est montant, et descendant pour Java) ; une modification simple d'action suffit a) Génération de code Java (0.75 pt) Utiliser les fonctions genFigCode(), genAllFigsCode() du code fourni figs.c pour générer le code Java d'une suite de "paths" comme ci-dessus b) Visualisation dans un G.U.I. Java (0.75 pt) Le code Java d'une suite de "paths" comme ci-dessus peut être inséré dans une interface Java fournie Visu.java (une eventuelle extension .txt est a retirer). Le compiler avec JFig.java, visualiser par : java Visu Que donne l'execution de ce code ? Pour obtenir exactement le même affichage qu'avec gv, il vous faut tenir compte de la Note 2 ci-dessus