Master 1 Compilation Coloration de code source Ce TP sur l'analyse lexicale correspond à un projet plus ambitieux puisqu'il s'agit de colorer les différents éléments du langage en produisant directement du HTML. Rappel sur des notions importantes de jflex Par défaut, lorsque l'analyseur lexical fonctionne en ne créant pas de main et qu'il est couplé à un autre programme, il utilise une méthode Yytoken yylex(). Le type Yytoken est à définir par le concepteur de l'analyseur. Voici un exemple de fichier qui permet de créer un analyseur lexical qui supprime les commentaires commençant par // ainsi que les fichiers annexes. La classe Commentaire est la classe principale qui appelle l'analyseur lexical sur un fichier passé en paramètre, la classe Yytoken est la «token» ou lexème créé par l'utilisateur : public class Yytoken { private String description; private int valeur; public Yytoken(String d){ description = d; valeur = 0; public Yytoken(String d, int v){ this(d); valeur = v; public String tostring(){ return description+"("+valeur+")"; import java.io.ioexception; import java.io.bufferedreader; import java.io.filereader; public class Commentaire {
public static void main(string [] args) throws IOException{ System.out.println(args[0]); // créer un analyseur EnleveCommentaires qui va prendre ses entrées dans le fichier de nom arg[0] EnleveCommentaires yy = null; yy = new EnleveCommentaires( new FileReader(args[0])); Yytoken token; // la fin de fichier est codée par le token null while((token = yy.yylex())!= null) System.out.print(token); %% %unicode %line %class EnleveCommentaires %% "//".* { ; \r\n { return new Yytoken("\n");.+ { return new Yytoken(yytext()); Ce qui donnera sur le fichier : fichier d'essai un commentaire // ci-dessous pas ici donnera : java Commentaire essai.txt essai.txt fichier d'essai(0) (0)un commentaire(0) (0) (0)pas ici(0) (0) Travail préliminaire : Taper le code ci-dessus Bien comprendre les différents éléments et l'interfaçage de ces éléments Le fichier jflex ne marche pas tout le temps pour certains commentaires, lesquels? Écrivez un ou plusieuts fichiers qui supprimeront les nombres de votre fichier et mettra les textes en majuscules
Contexte Cette technique est connue comme étant de la coloration syntaxique mais qui correspond en fait à de la coloration lexicale. Nous allons dans notre cas appliquer ce principe à la coloration des programmes Java, le but final étant d'obtenir une coloration syntaxique comme ci-dessous : Exemple.java import java.util.scanner; public class Exemple { int i; public Exemple(){ System.out.println("création de l'objet"); i = 1; ce qui correspond au fichier HTML généré suivant : <HTML> <BODY bgcolor = #FFFFFF> <H2>Exemple.java</H2> <CODE> <FONT color=00ff00>import java.util.scanner; </FONT> <FONT color=0000ff>public</font> <FONT color=0000ff>class</font> <FONT color=007f00>exemple</font> { <FONT color=0000ff>int</font> <FONT color=007f00>i</font>; <FONT color=0000ff>public</font> <FONT color=007f00>exemple</font>() { <FONT color=0000ff>system</font>.<font color=0000ff>out</font>.<font color=0000ff>println</font>(<font color=7f0000>"création de l'objet"</font>); <FONT color=007f00>i</font> <FONT color=00007f>=</font> <FONT
color=ff0000>1</font>; </CODE> </BODY> </HTML> Les couleurs ne sont peut-être pas les plus pertinentes mais c'est à vous éventuellement de les modifier. Pour le moment, votre analyseur lexical écrit en jflex prendra en compte les éléments suivants : 1. les mots-clefs if then else while switch case do break for return void int float double char long unsigned signed public private protected class System out println 2. les entiers (on ne prendra pas en compte dans un premier temps les nombres réels) ; 3. les importations (les lignes qui commencent par import xxx.yyy.zzz) ; 4. les chaînes de caractères entre guillemets ; 5. les identificateurs qui en Java commencent par une lettre ou le symbole "_" et se poursuivent par des lettres, le symbole "_" et des chiffres ; 6. et les différents opérateurs +,-,<,>=,==,. A chacune de ces unités lexicales, on lui affectera une couleur propre et chaque couleur correspondra simplement à un affichage du code suivant : <FONT color=xxx> </FONT> Par exemple, pour générer la chaîne de caractères en rouge vous devrez produire le code suivant : <FONT color=7f0000>"création de l'objet"</font>; Je vous propose les couleurs suivantes mais il est bien sûr tout à fait possible d'en utiliser d'autres : bleu vert violet rouge blanc bleu pale vert pale violet pale rouge pale <FONT color=00007f> <FONT color=007f00> <FONT color=007f7f> <FONT color=7f0000> <FONT color=white> <FONT color=0000ff> <FONT color=00ff00> <FONT color=00ffff> <FONT color=ff0000> Travail à réaliser Écrire votre fichier jflex que vous pouvez par exemple appeler java.jflex.
Votre fichier jflex aura comme option %unicode et %class JavaSyntax Vous pouvez éventuellement utiliser une classe intermédiaire pour améliorer la lisibilité du code dans votre fichier jflex. Par exemple, pour écrire un texte en rouge j'utilise dans ma partie action la commande suivante : MonHtmlLib.colPrint(MonHtmlLib.C_ROUGE); qui appelle dans la classe MonHtmlLib le code <FONT color=7f0000> Votre fichier java.jflex devra sortir tout le code au format HTML sans l'en-tête du fichier et son footer. N'oubliez pas que vous devez également transformer certains caractères par exemple < devra être transformé en HTML en > Ajout de l'en-tête et du footer Pour rajouter ces deux derniers éléments et pour former un fichier HTML complet, nous allons écrire un fichier Main qui permettra de lui passer en paramètre un fichier java et en sortie il sortira un fichier HTML complet. Comme le main ne sera plus généré par le fichier jflex vous enlèverez l'option %standlone et vous ajouterez à votre fichier jflex l'option %integer. Voici ci-dessous une bonne partie du squelette du programme à vous de le compléter en supposant que votre analyseurlexical s'appelle JavaSyntax sinon changer le nom dans le programme cidessous : import java.io.filereader; public class MainJava { public static void main(string [] argv) { if (argv.length == 0) { System.out.println("Utilisation : java JavaSyntax <inputfile>"); else { // header HTML System.out.println("<HTML>"); System.out.println("<BODY bgcolor = #FFFFFF>"); for (int i = 0; i < argv.length; i++) { /* 1 - déclaration du scanner */ JavaSyntax scanner = null; try { // écrire la page de titre et CODE System.out.println("<H2>"+argv[0]+"</H2>"); System.out.println("<CODE>"); /* 2 - scanner = new JavaSyntax() -> instantiation du Scanner par le JavaSyntax() 3 - new java.io.filereader(argv[i]) -> communique au scanner le fic scanner = new JavaSyntax( new FileReader(argv[i]) ); /* 4 - scanne le fichier jusqu'à la fin while ( scanner.yylex()!= null ); /* fermer la tage <code> */ System.out.println("</CODE>");
catch (java.io.filenotfoundexception e) { System.out.println("Fichier non trouvé : \"" + argv[i] + "\""); catch (Exception e) { System.out.println("Unexpected exception:"); e.printstacktrace(); /* Footer Html */ System.out.println("</BODY>"); System.out.println("</HTML>");