Faculté I&C, Claude Petitpierre, André Maurer 1 JavaCC Java compilers compiler (version générant du Javascript)
Faculté I&C, Claude Petitpierre, André Maurer 2 Source lue par JavaCC 1.Options 2.Program header 3.Tokens 4.Productions options { STATIC = true; } PARSER_BEGIN(ExpressionCompiler) class ExpressionCompiler{ var variables = new Array(); // Javascript == Java } // (exemple) PARSER_END(ExpressionCompiler) TOKEN : { // nom du fichier résultant | } void expr() : { } { term() ("+" term() {génération de code;})* }
Faculté I&C, Claude Petitpierre, André Maurer 3 options { // obligatoire, seule possibilité STATIC = true; } PARSER_BEGIN(ExpressionCompiler) // Header class ExpressionCompiler{ var variables = new Array(); // Javascript == Java var varMap = new Array(); function keepVarName(name) { // code auxiliaire if (varMap[name] == undefined) { // si nécessaire varMap[name] = true; variables.push(name); } } } PARSER_END(ExpressionCompiler) Option + header
Faculté I&C, Claude Petitpierre, André Maurer 4 Exemples de tokens SPECIAL_TOKEN : // ignorés dans la grammaire, mais mémorisés { | | | | } TOKEN : { | | | | } TOKEN : { | <IDENTIFIER: ( ["a"-"z"] | ["A"-"Z"] ) ( ["a"-"z"] | ["A"-"Z"] | ["0"-"9"] )* > }
Faculté I&C, Claude Petitpierre, André Maurer 5 Règles de production // principal void prog() : { } { expr() } void factor() : { } { ( | | "(" expr() ")" ) } void expr() : { } { term() ("+" term() )* } void term() : { } { factor() ("*" factor() )* } Parseur dexpressions: 3 + ((x+11)*5 + 8)
Faculté I&C, Claude Petitpierre, André Maurer 6 Répétitions void product() : { /*déclarations, init*/ } { ( tag() ) + ( ) * endTag() } ( x )* 0 – n fois ( x )+ 1 – n fois ( x )? optionnel [ x ] même que ci-dessus
Faculté I&C, Claude Petitpierre, André Maurer 7 LOOKAHEAD void statement() : { var nb = 0; } { "add" ( LOOKAHEAD (3) "A" "," nb=number() | "A" "," "B" | LOOKAHEAD ( "B" "," number() ) "B" "," nb=number() | "B" "," "B" ) }
Faculté I&C, Claude Petitpierre, André Maurer 8 Génération de code void factor() : { var t; } { ( t= {res.push(parseInt(t.image));} | {res.push(token.image);} | "(" expr() ")" ) } // note: token est défini par défaut, il correspond au // dernier token rencontré
Faculté I&C, Claude Petitpierre, André Maurer 9 Transmission de variables void factor(entier) : { var t; } { ( t= {res.push(parseInt(t.image)+entier);} | "(" expr() ")" ) { return t.image; } }
Faculté I&C, Claude Petitpierre, André Maurer 10 Génération dun programme exécutable void factor() : { var myToken; } { ( { print("res.unshift(parseInt("+token.image+"))\n");} | myToken = { print("var x = g..ById('"+myToken.image+"').value\n"); print("res.unshift(parseInt(x))\n"); keepVarName(myToken.image); } | "(" expr() ")" ) }
Faculté I&C, Claude Petitpierre, André Maurer 11 Tokens avec mêmes débuts TOKEN : { | } Texte lu: : :aaa Le token choisi est celui qui est le plus long possible. Sil y a deux solutions de même longueur, la première est sélectionnée.
Faculté I&C, Claude Petitpierre, André Maurer 12 JavaCC: queue des tokens et des special tokens Token next specialToken image Token next specialToken image Token next specialToken image Token next specialToken image Token next specialToken image special tokens apparaissant dans lordre inverse des flèches tous les tokens du fichier lu on peut sauver le premier pour les parcourir tous à la fin de la compilation
Faculté I&C, Claude Petitpierre, André Maurer 13 Compilation Fichiers générés ExpressionParser.js : le parseur ExpressionParserTokenManager.js : détection des tokens ExpressionParserConstants.js : numéro de chaque token
Faculté I&C, Claude Petitpierre, André Maurer 14 Appel des compilateurs générés par JavaCC var res function compile() { source à try { compiler initTokenManager(); ExpressionParserTokenManager( new inputStream( sourceString ) ) prog() // appel de la production initiale alert(res[0]) // montre le résultat créé par le parseur } catch (e) { alert(!e.mess?e:e.mess) // erreurs } }
Faculté I&C, Claude Petitpierre, André Maurer 15 Fichiers à importer dans l'application précédente Les deux premiers sont générés par JavaCC (les constantes ne sont pas nécessaires) Le troisième contient la gestion de la source à parser et compiler
Faculté I&C, Claude Petitpierre, André Maurer 16 Actions à faire générer par le parseur void expr() : { } { term() ( "+" term() { res.push(res.pop()+res.pop()); } )* } pop pop push