Master Informatique 2015-2016 Spécialité STL Développement des

Transcription

Master Informatique 2015-2016 Spécialité STL Développement des
Master Informatique 2015-2016
Spécialité STL
Développement des langages de programmation
DLP – 4I501
Carlos Agon
[email protected]
1/64
Introduction
Librement inspiré du cours ILP de Christian Queinnec.
Slides et mp3 sur le site :
www-master.ufr-info-p6.jussieu.fr/2007/Ext/queinnec/ILP/
2/64
Introduction
Buts
Implanter un langage
de la classe de Javascript
à syntaxe XML
avec un interprète écrit en Java
et un compilateur écrit en Java
qui produit du C.
3/64
Introduction
Buts pédagogiques
Exercice de lecture de code
Usage élaboré de Java 8
Non modification des codes précédemment donnés
Réflexions sur la conception de langages
4/64
Introduction
Cheminement
Carlos Agon
(cours 1-4) Syntaxe, interprétation, compilation vers C (ILP1)
DOM, XML, RelaxNG, JUnit3, JUnit4, visiteur
(cours 5) Fonctions, affectation, boucle (ILP2)
Généricité, analyse statique
Antoine Miné
(cours 6) Exceptions (ILP3)
C longjmp/setjmp
(cours 7) Lambda expressions (ILP3)
Définition, interprétation, compilation
(cours 8-9) Classe, objet, appel de méthode (ILP4)
(cours 10) Édition de liens (ILP4)
5/64
Introduction
Évaluation
Première évaluation (ILP1 et ILP2, cours 1-5) 40%
Deuxième évaluation (ILP1 - ILP4) 60%
TME hebdomadaire
(groupe 1 vendredi) Carlos Agon/Antoine Miné,
(groupe 2 jeudi) Binh Minh Bui Xuan,
(groupe 3 jeudi) Philippe Esling.
6/64
Cours 1
Plan du cours 1
Grand schéma
Langage ILP1
sémantique discursive
syntaxes
XML
DOM
grammaires : Relax NG
DOM et IAST
AST
Tests JUnit3 et JUnit4
7/64
Cours 1
Grand schéma
javaCC, sableCC, CUP, ANTLR
source
syntaxe
Scheme
source
syntaxe
XML
source
syntaxe
concrète
source
DOM
jaxb, castor
XStream, xmlBeans
source
AST
Transformations, optimisations
AST2
texte
C
a.out
AST
resultat
gcc
8/64
Cours 1
Langage ILP1
ILP1
Ce qu’il y a :
constantes (entière, flottante, chaîne de caractères, booléens)
alternative, séquence
variable, bloc local n-aire
invocation de fonctions
opérateurs unaires ou binaires
ce qu’il n’y a pas (encore !) (liste non exhaustive) :
pas
pas
pas
pas
pas
pas
d’affectation
de boucle
de définition de fonction
d’exception
des lambda
de classe
9/64
Cours 1
Langage ILP1
Les composants d’un langage
Des principes de calcul et d’architecture calcul : impératif, fonctionnel,
logique, etc. architecture : modularité, polymorphisme, etc.
Lexique + syntaxe
Un système de types (pas tous)
Une sémantique
Un environnement de programmation compilateurs, débogueurs,
manuels,
Une communauté d’utilisateurs
10/64
Cours 1
Langage ILP1
Syntaxe Python-Caml
let x = 111 in
let y = true in
if ( y == -3.14 )
then print " O " + " K "
else print ( x * 6.0)
endif
newline
11/64
Cours 1
Langage ILP1
Syntaxe Scheme
( let (( x 111))
( let (( y # t ))
( if (= y -3.14)
( print ( plus " O " " K "))
( print (* x 6.0)) ) )
( newline ) )
12/64
Cours 1
Langage ILP1
Syntaxe C/Java
{ int x = 111;
{ boolean y = true ;
if ( y == -3.14 ) {
print ( " O " + " K " );
} else {
print ( x * 6.0);
}
}
newline ();
}
13/64
Cours 1
Langage ILP1
Définition d’un langage
Définitions :
Symbole : signe primitif (lettre, chiffre, point, ligne, ?)
Alphabet : ensemble fini de symboles (Σ)
Chaîne : séquence finie de symboles (la chaîne vide )
Langages formel : ensemble de chaînes définies sur un alphabet Σ
Problèmes :
Comment définir un langage en intension ?
Comment calculer si une chaîne ω appartient ou non à un langage L ?
14/64
Cours 1
Langage ILP1
The dragon book
C’est important,mais, on ne s’y intéressera pas ! On partira donc d’une
syntaxe XML.
15/64
Cours 1
Langage ILP1
Syntaxe arborescente
programme1
blocUnaire
variable
nom=x
valeur
corps
blocUnaire
entier
valeur=111
variable
nom=y
valeur
corps
booleen
valeur=true
alternative
condition
consequence
alternant
...
operationBinaire
operateur===
operandeGauche
variable
nom=y
operandeDroit
flottant
valeur=−3.14
invocationPrimitive
fonction=print
arguments
invocation
fonction arguments
variable
nom=plus
chaine
valeur=O
chaine
valeur=K
16/64
Cours 1
Langage ILP1
Syntaxe XML
< program >
< block >
< bindings >
< binding > < variable name = ’x ’/ >
< initialisation > < float value = ’ 111 ’/ > </ initialisation >
</ binding >
< binding > < variable name = ’y ’/ >
< initialisation > < boolean value = ’ true ’/ > </ initialisation >
</ binding >
</ bindings >
< body >
< alternative >
< condition >
< b in aryOperation operator = ’ == ’ >
< leftOperand > < variable name = ’y ’ </ leftOperand >
< rightOperand >
< unaryOperation operator = ’ - ’ >
< operand > < float value = ’ 3.14 ’/ > </ rightOperand > </ operand >
</ unaryOperation >
</ b in aryOperation >
</ condition >
< consequence >
< invocation >
< function > < variable name = ’ print ’/ > </ function >
< arguments >
. . .
</ arguments >
</ invocation >
</ consequence >
< alternant >
. . .
</ alternant >
17/64
Cours 1
XML
Rudiments d’XML
Un langage normalisé pour représenter des arbres.
<? xml version ="1.0"
encoding = ’ ISO -8859 -1 ’
standalone =" yes "
?>
<? xml - stylesheet type =" text / xsl " href =" style . xsl "? >
<ul > < li > un & nbsp ; </ li >
<! - - attention : -->
< li rien =" du tout "/ >
</ ul >
Attention à UTF-8, ISO-8859-1 (latin1) ou ISO-8859-15 (latin9).
18/64
Cours 1
XML
Terminologie
Un élément débute par le < de la balise ouvrante et se termine avec le
> de la balise fermante correspondante.
Un élément contient au moins une balise mais peut contenir d’autres
éléments, du texte, des commentaires (et des références à des entités
éventuellement des instructions de mise en œuvre).
Une balise (pour tag) débute par un < et s’achève au premier > qui
suit. Une balise possède un nom et, possiblement, des attributs.
Les noms des balises sont structurés par espaces de noms (par
exemple xml:namespace ou rdf:RDF).
19/64
Cours 1
XML
Caractères bizarres en XML
Entités prédéfinies ou sections particulières (échappements) :
& amp ; & lt ; & gt ; & apos ; & quot ;
<? xml version ="1.0" encoding =" ISO -8859 -15" standalone =" ye
<ul > < li / >
<li > <![ CDATA [ 1 li >1 m ?
<! @ #~*} ]] > </ li >
<li > 1 li & gt ;1 m ?
& lt ;! @ #~*} </ li >
</ ul >
20/64
Cours 1
XML
Validation d’XML
Un programme écrit en XML doit être bien formé c’est-à-dire
respectueux des conventions d’XML.
Un programme écrit en XML doit aussi être valide vis-à-vis d’une
grammaire.
Les grammaires sont des DTD (pour Document Type Definition) ou
maintenant des XML Schémas ou des schémas Relax NG.
Énorme intérêt pour la lecture en cas d’erreur.
21/64
Cours 1
XML
Backus Naur Form
BNF
méta-symboles :
::=, (, ), |
non terminaux :
<nom>
terminaux :
«mots»
22/64
Cours 1
XML
Exemple
<terme> ::= <nombre signé> | <nombre signé> <op> <terme>
<nombre signé> ::= <nombre> | «+» <nombre> | «-» <nombre>
<nombre> ::= <entier> | <nombre fractionnaire>
<nombre fractionnaire> ::= <entier> | <entiere> «/» <entiere>
<entier> ::= <chiffre> | <chiffre><entier>
<chiffre> ::= «0» | «1» | ... | «9»
23/64
Cours 1
XML
Exemple
<terme> ::= <nombre signé> | <nombre signé> <op> <terme>
<nombre signé> ::= <nombre> | «+» <nombre> | «-» <nombre>
<nombre> ::= <entier> | <nombre fractionnaire>
<nombre fractionnaire> ::= <entier> | <entiere> «/» <entiere>
<entier> ::= <chiffre> | <chiffre><entier>
<chiffre> ::= «0» | «1» | ... | «9»
1 + 3 - 1/4
1 + 3 * 1/4
1 + 3 * 1/0
23/64
Cours 1
RelaxNG
RelaxNG
Relax NG est un formalisme pour spécifier des grammaires pour XML (bien
plus lisible que les schémas XML (suffixe .xsd mais pour lesquels existe un
mode dans Eclipse)).
Les grammaires Relax NG (prononcer relaxing) sont des documents XML
(suffixe .rng) écrivables de façon compacte (suffixe .rnc) et surtout
lisibles !
Une fois validé, les textes peuvent être réifiés en DOM (Document Object
Model).
24/64
Cours 1
RelaxNG
Grammaire RelaxNG – ILP1
Les caractéristiques simples sont codées comme des attributs, les
composants complexes (sous-arbres) sont codés comme des sous-éléments.
Ressource: Grammars/grammar1.rnc
s t a r t = program
program = element program {
expression +
}
expression =
alternative
| sequence
| block
| constant
| invocation
| operation
| variable
25/64
Cours 1
RelaxNG
alternative = element alternative {
element condition
{ expression } ,
element consequence { expression + } ,
element alternant
{ expression + } ?
}
sequence = element sequence {
expression +
}
block = element block {
element bindings {
element binding {
variable ,
element initialisation {
expression
}
} *
},
element body { expression + }
}
26/64
Cours 1
RelaxNG
invocation = element invocation {
element function { expression } ,
element arguments { expression * }
}
variable = element variable {
a t t r i b u t e name { xsd : Name - ( xsd : Name { pattern = " (
empty
}
operation =
unaryOperation
| binaryOperation
unaryOperation = element unaryOperation {
a t t r i b u t e operator { " -" | " ! " } ,
element operand
{ expression }
}
27/64
Cours 1
RelaxNG
binaryOperation = element binaryOperation {
element leftOperand { expression } ,
a t t r i b u t e operator {
" + " | " -" | " * " | " / " | " % " |
"|" | "&" | "^" |
" <" | " <= " | " == " | " >= " | " >" | " <>" | " != "
},
element rightOperand { expression }
}
constant =
element integer {
a t t r i b u t e value { xsd : integer } ,
empty }
| element float {
a t t r i b u t e value { xsd : float } ,
empty }
| element string { t e x t }
| element boolean {
a t t r i b u t e value { " true " | " false " } ,
empty }
28/64
Cours 1
RelaxNG
Validation
< program >
< block >
< bindings >
< binding > < variable name = ’x ’/ >
< initialisation > < float value = ’ 111 ’/ > </ initialisation >
</ binding >
< binding > < variable name = ’y ’/ >
< initialisation > < boolean value = ’ true ’/ > </ initialisation >
</ binding >
</ bindings >
< body >
< alternative >
< condition >
< b in aryOperation operator = ’ == ’ >
< leftOperand > < variable name = ’y ’ </ leftOperand >
< rightOperand >
< unaryOperation operator = ’ - ’ >
< operand > < float value = ’ 3.14 ’/ > </ rightOperand > </ operand >
</ unaryOperation >
</ b in aryOperation >
</ condition >
< consequence >
< invocation >
< function > < variable name = ’ print ’/ > </ function >
< arguments >
. . .
Si le programme est validé vis-à-vis la grammaire, il sera réifié en DOM
(Document Object Model).
29/64
Cours 1
DOM
Interface DOM
L’interface DOM (pour Document Object Model) lit le document XML et
le convertit entièrement en un arbre (en fait un graphe modifiable).
DOM est une interface, il faut lui adjoindre une implantation et, pour
XML, il faut adjoindre un analyseur syntaxique (pour parser)
30/64
Cours 1
DOM
Verification
Paquetage org.w3c.dom.*
Implantations : javax.xml.parsers.*, org.xml.sax.*
RelaxNG : com.thaiopensource.validate.ValidationDriver;
public IASTprogram getProgram () throws Pa rseExc eption {
try {
final String programText = input . getText ();
final String rngFilePath = rngFile . g et A bs o lu te P at h ();
final InputSource isg = V a l i d a t i o n D r i v e r . fi l eI np u tS ou r ce ( rngFilePath );
final V al i dat ion Dri ver vd = new V a l i d a t i o n D r i v e r ();
vd . loadSchema ( isg );
InputSource is = new InputSource ( new StringReader ( programText ));
if ( ! vd . validate ( is ) ) {
throw new P arseExceptio n ( " Invalid XML program ! " );
}
...
}
31/64
Cours 1
DOM
Conversion à DOM
public IASTprogram getProgram () throws Pa rseExc eption {
try {
...
final D o c u m e n t B u i l d e r F a c t o r y dbf =
D o c u m e n t B u i l d e r F a c t o r y . newInstance ();
final Docu men t Bu il d er db = dbf . n e w D o c u m e n t B u i l d e r ();
// the previous value of is is totally drained !
is = new InputSource ( new StringReader ( programText ));
final Document document = db . parse ( is );
...
} catch ( ParseE xcepti on e ) {
throw e ;
} catch ( Exception e ) {
throw new Pa rseExc eption ( e );
}
}
32/64
Cours 1
DOM
Les interfaces du DOM
org.w3c.dom.Document
org.w3c.dom.Node
org.w3c.dom.Element
org.w3c.dom.CharacterData
org.w3c.dom.NodeList
33/64
Cours 1
DOM
Arpentage du DOM
org.w3c.dom.Document
Element getDocumentElement ();
org.w3c.dom.Node
Node . uneCONSTANTE getNodeType ();
// avec Node . DOCUMENT_NODE , Node . ELEMENT_NODE ,
// Node . TEXT_NODE ...
NodeList getChildNodes ();
org.w3c.dom.Element hérite de Node
String getTagName ();
String getAttribute ( " attributeName " );
org.w3c.dom.Text hérite de Node
String getData ();
org.w3c.dom.NodeList
int getLength ();
Node item ( int );
34/64
Cours 1
DOM
Variations autour du DOM
attention au découpage des textes, aux blancs superflus,
<a b = ’c ’
> </ a >
<a b = ’c ’ >
</ a >
attention à la présence de commentaires, instructions de traitement
<a >
<b > text1
<! -- comment -- >
text2
</ b >
</ a >
35/64
Cours 1
DOM
Du bon emploi de XML
XML favorise l’auto-description avec des balises signifiantes
Ne pas employer d’attributs là où une certaine extensibilité est envisagée ou là
où ne peut être contenue l’information souhaitée.
XML cherche à minimiser les efforts d’analyse (d’où l’intérêt des conteneurs)
< point >
<x >1 </ x >
<y >2 </ y >
</ point >
< ligne >
< characteristics
color = ’ blue ’ / >
< points >
< point > .. </ point >
< point > .. </ point >
</ points >
</ ligne >
< point x = ’1 ’ y = ’2 ’/ >
< ligne >
< point > .. </ point >
< characteristics ../ >
< point > .. </ point >
..
</ ligne >
36/64
Cours 1
Sémantique
Sémantique discursive
Langage non typé statiquement : les variables n’ont pas de type
Langage sûr, typé dynamiquement : toute valeur a un type (donc de la
classe de Scheme, Javascript, Smalltalk)
Langage à instruction (séquence, alternative, bloc unaire)
Toute expression est une instruction
Les expressions sont des constantes, des variables, des opérations ou
des appels de fonctions (des invocations).
37/64
Cours 1
Sémantique
Détails sémantiques
Opérateurs unaires : - (opposé) et ! (négation)
Opérateurs binaires :
arithmétiques : + (sur nombres et chaînes), -, *, /, % (sur entiers),
comparateurs arithmétiques : <, <=, >, >=,
comparateurs généraux : ==, <>, != (autre graphie),
booléens : |, &, ^.
Variables globales prédéfinies : fonctions primitives : print et newline
(leur résultat est indéfini) ou constantes comme pi.
Le nom d’une variable ne peut débuter par ilp ou ILP.
L’alternative est binaire ou ternaire (l’alternant est facultatif).
La séquence contient au moins un terme.
38/64
AST
AST
DOM est une façon simple de réifier un document XML (quelques lignes de
programme), mais il est peu adapté à la manipulation d’arbres de syntaxe
AST (pour Abstract Syntax Tree) car il est non typé, trop coûteux, mal
extensible.
Une fois le DOM obtenu, on le transforme en un AST.
NOTA : on aurait pu passer directement de la syntaxe concrète à l’AST.
39/64
AST
Grand schéma
javaCC, sableCC, CUP, ANTLR
source
syntaxe
Scheme
source
syntaxe
XML
source
syntaxe
concrète
source
DOM
jaxb, castor
XStream, xmlBeans
source
AST
Transformations, optimisations
AST2
texte
C
a.out
AST
resultat
gcc
40/64
AST
IAST
Le paquetage com.paracamplus.ilp1.interfaces fournit une interface pour
chaque concept syntaxique :
IAST
IASTalternative
IASTconstant
IASTboolean
IASTinteger
IASTfloat
IASTstring
IASTinvocation
IASToperation
IA STun ary Op er ati on
IAS T bi n a ry O per a ti o n
IASTsequence
IASTBlock
IASTvariable
IASTprogram
41/64
AST
Alternative
D’un point de vue syntaxique, une alternative est une entité ayant trois
composants dont un optionnel :
alternative = element alternative {
element condition
{ expression } ,
element consequence { instructions } ,
element alternant
{ instructions } ?
}
42/64
AST
IASTalternative
package com . paracamplus . ilp1 . interfaces ;
public interface IASTalternative
extends IAST {
IASTexpression getCondition ();
IASTexpression getConsequence ();
@OrNull IASTexpression getAlternant ();
/* * Indique si l ’ alternative est ternaire . */
boolean isTernary ();
}
Interfaces décalquables de la grammaire !
Pourquoi ?
Pour dissocier les interfaces des implantations afin de permettre d’autres
analyseurs syntaxiques
43/64
AST
Hiérarchies
IAST
implante
AST
hérite
IASTalternative
IASToperation
IASTinvocation
ASTalternative
ASToperation
ASTinvocation
ASTinvocationPrimitive
44/64
AST
AST
Les classes dans le package com.paracamplus.ilp1.ast implantent les
interfaces respectives dans com.paracamplus.ilp1.interfaces.
AST
implante IAST
ASTalternative implante IASTalternative
ASTBlock
implante IASTBlock
ASTboolean
implante IASTboolean
ASTstring
implante IASTstring
ASTinteger
implante IASTinteger
ASTfloat
implante IASTfloat
ASTinvocation
implante IASTinvocation
ASToperation
implante IASToperation
ASTun aryOpera tion
implante IAS Tu na ryOperation
AS Tbin ary Op er ati on
implante IA S Tb i n aryOperation
ASTsequence
implante IASTsequence
ASTvariable
implante IASTvariable
45/64
AST
ASTalternative
package com . paracamplus . ilp1 . ast ;
import com . paracamplus . ilp1 . annotation . OrNull ;
import com . paracamplus . ilp1 . interfaces . IASTalternative ;
import com . paracamplus . ilp1 . interfaces . IASTexpression ;
public class ASTalternative extends ASTexpression
implements IASTalternative {
public ASTalternative ( IASTexpression condition ,
IASTexpression consequence ,
IASTexpression alternant ) {
this . condition = condition ;
this . consequence = consequence ;
this . alternant = alternant ;
}
46/64
AST
private final IASTexpression condition ;
private final IASTexpression consequence ;
private @OrNull final IASTexpression alterna
public IASTexpression getCondition () {
return condition ;
}
public IASTexpression getConsequence () {
return consequence ;
}
public IASTexpression getAlternant () {
return alternant ;
}
public boolean isTernary () {
return this . alternant != null ;
47/64
AST
Conversion DOM vers AST
public IASTprogram getProgram ()
throws ParseException {
try {
... Validation
}
... XML to DOM
final Document document = db . parse ( is );
IASTprogram program = parse ( document );
return program ;
} catch ( ParseException e ) {
throw e ;
} catch ( Exception e ) {
throw new ParseException ( e );
}
}
48/64
AST
La classe Parser
La conversion est effectuée par la méthode parse(Node) de la classe
Parser :
package com . paracamplus . ilp1 . ast ;
public class Parser extends A b s t r a c t E x t e n s i b l e P a r s e r {
public Parser ( IParse rFacto ry factory ) {
super ( factory );
addMethod ( " alternative " , Parser . class );
addMethod ( " sequence " , Parser . class );
addMethod ( " in t eg er C on st a nt " , Parser . class , " integer " );
addMethod ( " floatConstant " , Parser . class , " float " );
addMethod ( " st ringCo nstant " , Parser . class , " string " );
addMethod ( " bo o le an C on st a nt " , Parser . class , " boolean " );
addMethod ( " un aryOpe ration " , Parser . class );
addMethod ( " bi n ar yO p er at i on " , Parser . class );
addMethod ( " block " , Parser . class );
addMethod ( " binding " , Parser . class );
addMethod ( " variable " , Parser . class );
addMethod ( " invocation " , Parser . class );
}
49/64
AST
public abstract class A b s t r a c t E x t e n s i b l e P a r s e r extends Ab stract Parser
public A b s t r a c t E x t e n s i b l e P a r s e r ( IPa rserFa ctory factory ) {
super ( factory );
this . parsers = new HashMap < >();
}
private final HashMap < String , Method > parsers ;
public void addParser ( String name , Method method ) {
this . parsers . put ( name , method );
}
public void addMethod ( String name , Class <? > clazz ) {
addParser ( name , findMethod ( name , clazz ));
}
public void addMethod ( String name , Class <? > clazz ,
String tagName ) {
addParser ( tagName , findMethod ( name , clazz ));
}
50/64
AST
public Method findMethod ( String name , Class <? > clazz ) {
try {
for ( Method m : clazz . getMethods () ) {
if ( ! name . equals ( m . getName ()) ) {
continue ;
}
if ( Modifier . isStatic ( m . getModifiers ()) ) {
continue ;
}
Class <? >[] par ameter Types = m . g e t P a r a m e t e r T y p e s ();
if ( param eterTy pes . length != 1 ) {
continue ;
}
if ( ! Element . class . i s A s s i g n a b l e F r o m ( par ameter Types [0])
continue ;
}
return m ;
}
if ( Object . class == clazz ) {
final String msg = " Cannot find suitable parsing method !
throw new R u n t i m e E x c e p t i o n ( msg );
} else {
return findMethod ( name , clazz . getSuperclass ());
}
} catch ( S e c u r i t y E x c e p t i o n e1 ) {
final String msg = " Cannot access parsing method ! " ;
51/64
throw new R u n t i m e E x c e p t i o n ( msg );}}
AST
public IAST parse ( final Node n ) throws Parse Except ion {
switch ( n . getNodeType () ) {
case Node . ELEMENT_NODE : {
final Element e = ( Element ) n ;
final String name = e . getTagName ();
if ( parsers . containsKey ( name ) ) {
final Method method = parsers . get ( name );
try {
Object result = method . invoke ( this , new Object []{ e });
if ( result != null && result instanceof IAST ) {
return ( IAST ) result ;
} else {
final String msg = " Not an IAST " + result ;
throw new Pa rseExc eption ( msg );
}
} catch ( I l l e g a l A r g u m e n t E x c e p t i o n exc ) { ...
} catch ( I l l e g a l A c c e s s E x c e p t i o n exc ) { ...
} catch ( I n v o c a t i o n T a r g e t E x c e p t i o n exc ) { ...
}
} else {
final String msg = " Unknown element name : " + name ;
throw new Pa rseExc eption ( msg );
}
}
default : {
final String msg = " Unknown node type : "
52/64
AST
Méthode pour l’alternative
public IAST expres sion alternative ( Element e ) throws Pars eExcep tion {
IAST iastc = f i n d T h e n P a r s e C h i l d C o n t e n t (e , " condition " );
IAST expres sion condition = n a r r o w T o I A S T e x p r e s s i o n ( iastc );
IAST expres sion [] iaste =
f i n d T h e n P a r s e C h i l d A s E x p r e s s i o n s (e , " consequence " );
IAST expres sion consequence = getFactory (). newSequence ( iaste );
try {
IAST expres sion [] iasta =
f i n d T h e n P a r s e C h i l d A s E x p r e s s i o n s (e , " alternant " );
IAST expres sion alternant = getFactory (). newSequence ( iasta );
return getFactory (). new Altern ative (
condition , consequence , alternant );
} catch ( P arseEx ceptio n exc ) {
return getFactory (). new Altern ative (
condition , consequence , null );
}
}
53/64
AST
Récapitulation
syntaxe d’ILP1 (grammaire RelaxNG, XML, IAST)
représentation d’un programme ILP1 (AST)
RelaxNG, DOM, XML
54/64
AST
Grand schéma
javaCC, sableCC, CUP, ANTLR
source
syntaxe
Scheme
source
syntaxe
XML
source
syntaxe
concrète
source
DOM
jaxb, castor
XStream, xmlBeans
source
AST
Transformations, optimisations
AST2
texte
C
a.out
AST
resultat
gcc
55/64
AST
Bibliographie
Cours de C http://www-ari.ufr-info-p6.jussieu.fr/
RESSOURCES/doc/cederoms/Videoc2000/
Cours de Java http://www.pps.jussieu.fr/~emmanuel/Public/
enseignement/JAVA/SJP.pdf
developper en java avec Eclipse
http://www.jmdoudoux.fr/java/dejae/ (500 pages)
Cours sur XML http://apiacoa.free.fr/teaching/xml/
RelaxNG http:
//www.oasis-open.org/committees/relax-ng/tutorial.html
ou le livre « Relax NG » d’Éric Van der Vlist, O’Reilly 2003.
56/64
AST
Tests
Tests
Tests avec JUnit3 Cf. http://www.junit.org/
package com . paracamplus . ilp1 . tools . test ;
import junit . framework . TestCase ;
import com . paracamplus . ilp1 . tools . ProgramCaller ;
public class ProgramCallerTest extends TestCase {
public void t e s t P r o g r a m Ca l l er I n ex i s t e n t V er b o s e () {
final String programName = " lasdljsdfousadfl lsjd " ;
ProgramCaller pc =
new ProgramCaller ( programName );
assertNotNull ( pc );
pc . setVerbose ();
pc . run ();
assertTrue ( pc . getExitValue () != 0);
}
57/64
AST
Tests
Séquencement JUnit3
Pour une classe de tests SomeTest :
1
2
charger la classe de test SomeTest
pour chaque méthode nommée testX,
1
2
3
4
instancier la classe de test SomeTest
tourner setUp()
tourner testX
tourner tearDown()
58/64
AST
Tests
JUnit 4
Les tests ne sont plus déclarés par héritage mais par annotation (cf. aussi
TestNG). Les annotations sont (sur les méthodes) :
@BeforeClass
@Before
@Test
@Test ( expected = Exception . class )
@After
@AfterClass
et quelques autres comme (sur les classes) :
@RunWith
@SuiteClasses
@Parameters
59/64
AST
Tests
Séquencement JUnit4
Pour une classe de tests Foobar :
1
charger la classe Foobar
2
tourner toutes les methodes @BeforeClass
pour chaque méthode annotée @Test,
3
1
2
3
4
4
instancier la classe Foobar
tourner toutes les méthodes @Before
tourner la méthode testée
tourner toutes les méthodes @After
enfin, tourner toutes les methodes @AfterClass
60/64
AST
Tests
Annotations
Les annotations sont des métadonnées dans le code source
originalement en JAVA avec Javadoc
annotations connues : @Deprecated, @Override, ...
annotations multi paramétrées : @Annotation(arg1="val1",
arg2="val2", ... )
Utilisations des annotations :
par le compilateur pour détecter des erreurs
pour la documentation
pour la génération de code
pour la génération de fichiers
Avec les annotations le code source est parcouru mais il n’est pas modifié.
61/64
AST
Tests
Définition d’une annotation
public @interface MyAnnotation {
int arg1 () default 4;
String arg2 ();
}
@MyAnnotation ( arg1 =0 , arg2 = " valeur2 " )
public class UneCLasse {
...
}
62/64
AST
Tests
Les annotations des annotations
@Target ({ ElementType . METHOD , ElementType . CONSTRUCTOR })
@Retention ( RetentionPolicy . RUNTIME )
@Inherited
public @interface MyAnnotation {
int arg1 () default 4;
String arg2 ();
}
Pour l’annotation @Retention :
RetentionPolicy.SOURCE : dans le code source uniquement
(ignorée par le compilateur)
RetentionPolicy.CLASS : dans le code source et le bytecode
(fichier .java et .class)
RetentionPolicy.RUNTIME : dans le code source et le bytecode et pendant
l’exécution par introspection
63/64
AST
Tests
Les annotations pendant l’exécution
La pluspart des méta-objets implémentent
java.lang.reflect.AnnotatedElement :
boolean isAnnotationPresent(Class<? extends
Annotation>) :
True si le méta-objet est annoté avec le type du paramètre
<T extends Annotation> getAnnotation(Class<T>) :
renvoie l’annotation de type T ou null
Annotation[] getAnnotations() :
renvoie la liste des annotations
Annotation[] getDeclaredAnnotations() :
renvoie la liste des annotations directes (pas les heritées)
64/64

Documents pareils