Coloration de code source

publicité
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.
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;<br>
</FONT><br>
<FONT color=0000ff>public</FONT> <FONT color=0000ff>class</FONT>
<FONT color=007f00>Exemple</FONT> {<br>
<br>
<FONT color=0000ff>int</FONT> <FONT color=007f00>i</FONT>;<br>
<br>
<FONT color=0000ff>public</FONT> <FONT color=007f00>Exemple</FONT>()
{<br>
<FONT color=0000ff>System</FONT>.<FONT color=0000ff>out</FONT>.<FONT
color=0000ff>println</FONT>(<FONT color=7f0000>"création de
l'objet"</FONT>);<br>
<br>
<FONT color=007f00>i</FONT> <FONT color=00007f>=</FONT> <FONT
color=ff0000>1</FONT>;<br>
}<br>
<br>
<br>
}<br>
</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
<FONT color=00007f>
vert
<FONT color=007f00>
violet
<FONT color=007f7f>
rouge
<FONT color=7f0000>
blanc
<FONT color=White>
bleu pale
<FONT color=0000ff>
vert pale
<FONT color=00ff00>
violet pale
<FONT color=00ffff>
rouge pale
<FONT color=ff0000>
Travail à réaliser
Écrire votre fichier jflex que vous pouvez par exemple appeler java.jflex.
Votre fichier jflex aura comme option%standalone
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.*;
public class MainJava {
public static void main(String [] argv) {
if (argv.length == 0) {
System.out.println("Usage : java JavaSyntax <inputfile>");
}
else {
// header HTML
System.out.println("<HTML>");
System.out.println("<BODY bgcolor = #FFFFFF>");
/* 1 - Scanner declaration */
JavaSyntax scanner = null;
try {
// écrire la page de titre et CODE
/* 2 - scanner = new JavaSyntax() -> Scanner instantiation
java.io.FileReader(argv[i]) -> communique au scanner le fichier à scanné */
scanner = new JavaSyntax( new java.io.FileReader(argv[i]) );
/* 4 - scanne le fichier jusqu'à la fin
la fonction JavaSyntax() retourne JavaSyntax.YYEOF
IMP: The function yylex returns an integer constant because in the .jf
%integer was used, otherwise yylex returns a class of type YyToken */
while ( scanner.yylex() != JavaSyntax.YYEOF );
/* fermer la tage <code> */
System.out.println("</CODE>");
}
catch (java.io.FileNotFoundException e) {
System.out.println("File not found : \"" + argv[i] + "\"");
}
catch (java.io.IOException e) {
System.out.println("IO error scanning file \"" + argv[i] + "\"");
System.out.println(e);
}
catch (Exception e) {
System.out.println("Unexpected exception:");
e.printStackTrace();
}
}
/* Footer Html */
System.out.println("</BODY>");
System.out.println("</HTML>");
}
}
}
Téléchargement