Annexes


A Systèmes de types des langages de programmation

A.1 Langages de programmation et systèmes de types

A.1.1 Langages typés et non typés

Les langages de programmation sont dépendants des applications qu'ils permettent de programmer : les opérations définies dans un langage permettent de réaliser des tâches particulières. Par exemple, le langage Lisp permet d'implémenter une algorithmique fonctionnelle adaptée à l'intelligence artificielle et à la déduction automatique. Le langage C, qui permet de manipuler les adresses mémoire, est couramment utilisé pour implémenter des fonctions du système d'exploitation. Certains langages à objets tels que Java permettent de concevoir des interfaces utilisateurs à un moindre coût et d'utiliser, de façon intégrée, des protocoles réseau de haut niveau. La nature des types de données proposés par chacun de ces langages diffère selon la nature des données traitées : le langage C permet la manipulation de variables de type pointeur, tandis que le langage Java l'interdit. Les structures de données complexes dans le langage Lisp sont toutes construites à base de tuples, tandis que les autre langages proposent des constructions de types plus élaborées (structures, enregistrements).

L'affectation de types aux variables et aux expressions d'un programme permet au programmeur de ne pas avoir le souci de la représentation en mémoire des données manipulées. Lorsqu'il utilise un langage non typé, tel que l'assembleur, le programmeur doit contrôler que le domaine des variables et les paramètres des instructions qu'il écrit sont corrects. De même, il doit gérer la réservation et la libération des espaces mémoire nécessaires pour le stockage de ces variables.

Par contre, Le l-calcul, qui peut également être considéré comme un langage non typé (ce n'est pas un langage de programmation), garantit l'absence d'erreur car toute donnée est une fonction et retourne donc forcément un résultat valide, de même tout opérateur est une fonction et retourne donc un résultat. Cependant les expressions fonctionnelles sont difficiles à comprendre. Cela présente un inconvénient pour la maintenance des programmes écrits dans des langages proches du l-calcul (Lisp, Scheme).

Les types de données apportent un supplément d'information permettant au système de prendre en charge les tâches qui incombent au programmeur dans les langages non typés (réservation de mémoire, contrôle des domaines de valeur), tout en apportant une meilleure lisibilité des programmes [Cardelli 85], ce qui se traduit par :

  • une économie de temps d'exécution
  • une économie de temps de développement
  • une économie de compilation
  • une simplicité d'expression des langages

A.1.2 Systèmes de types

Nous donnons ici la définition des éléments d'un langage de programmation typé, ainsi que deux approches permettant l'affectation de types aux variables d'un programme.

Définitions

L'ensemble des types pouvant être exprimés dans un langage, les règles qui permettent de les définir et les règles qui définissent le type d'une expression sont communément appelés système de types du langage.

L'ensemble des types valides d'un langage est composé de types de base représentant les unités d'information atomique pouvant être manipulées par le langage. Par exemple, les types entier, booléen, caractère, chaîne ou réel sont des types de base couramment définis dans les langages de programmation. Ces types de base peuvent être combinés entre eux pour définir des types construits. Deux approches permettent de définir ou d'utiliser les types construits :

  1. Définition explicite des types de données : une expression de type décrit un type construit, ses opérandes sont des types de base ou d'autres types construits et ses opérateurs sont appelés constructeurs de type.
  2. Définition implicite des types de données : le type d'une expression est calculé lors de son évaluation. Le type des variables utilisées dans un programme est déduit lors de leur utilisation.

Chacune de ces deux approches implique des politiques différentes pour la compilation et l'interprétation des langages qui les utilisent. Les techniques mises en oeuvre pour garantir la correction d'un programme vis-à-vis du système de types du langage sont également différentes.

D'une manière générale nous pouvons dire que les langages explicitement typés permettent une meilleure compréhension des programmes et une économie du temps de compilation et d'exécution. En contrepartie, ils imposent des contraintes sur l'application des traitements à des variables d'un type donné : les variables utilisées dans un calcul doivent être d'un type acceptable pour l'opérande auquel elles sont appliqués.

La plupart des langages explicitement typés permettent de nommer des expressions de type pour les ré-utiliser ultérieurement. Le nommage d'une expression de type est introduit par un mot-clé spécifique (typedef en C, type en Pascal) et définit un nom de type. Si un nom de type est utilisé dans l'expression qui le définit, le type est alors un type récursif.

Le calcul des types des expressions et des variables des programmes écrits dans des langages implicitement typés implique un surcoût de temps à l'exécution du programme. Le type d'une variable ne peut pas toujours être déduit d'une seule expression, et le système doit faire des hypothèses sur le type de la variable qui pourront être confirmées ou infirmées par la suite. Dans l'exemple suivant,

a = 1 + 3;

Le type de a peut être entier ou réel, le système doit conserver tous les types potentiels de la variable a, pour éventuellement choisir ultérieurement. L'expression

a = sin (b/2);

détermine le type réel pour a. Certains types peuvent être incomplets du fait qu'une expression utilise des variables dont le type n'a pas encore été déterminé. Dans ce cas des variables de type doivent être introduites pour paramétrer le type cherché. Une expression est dite entièrement typée lorsque l'ensemble des variables de type utilisées pour définir son type sont valuées (voir section A.4).

A.1.3 Contrôle de type et sécurité à l'exécution

Les types de données permettent une plus grande lisibilité des programmes et un temps de développement réduit. L'utilisation de systèmes de types permettent également d'écarter les erreurs à l'exécution. En effet, lors de la compilation ou de l'exécution d'un programme, le système de types est un moyen de contrôler que les paramètres appliqués à un opérateur ou à une fonction sont corrects. Il est ainsi possible de prévoir si une opération pourra aboutir et donnera un résultat (type et domaine des paramètres corrects) ou si elle déclenchera à coup sûr une erreur (paramètres incorrects).

La sécurité des programme à l'exécution n'est pas l'intérêt premier de ce travail, mais cette propriété de sécurité s'appuie d'une part sur le fait qu'un programme est bien typé, d'autre part que le système de type du langage permet d'assurer cette propriété, c'est à dire que les opérations permises par les langages ne produisent que des variables de valeurs correctes par rapport à leur type. Ce n'est pas le cas, par exemple, de l'opération de coercition (ou casting) du langage C qui permet de changer le type d'une valeur sans contrôler sa validité pour le type dans lequel elle est transformée.

Les systèmes de types assurant la propriété de sécurité à l'exécution restreignent en général la souplesse de programmation en interdisant les opérations de changement de type pouvant engendrer des erreurs de type. L'arithmétique de pointeurs est généralement exclue des langages utilisant un système de type conservant la propriété de sécurité.

La conception d'un langage de programmation se heurte donc au défi de proposer un système de type sûr sans restreindre les opérations proposées à l'utilisateur.

A.2 Un contrôleur de types simple

Dans cette section nous décrivons un langage permettant de spécifier le système de types d'un langage et de l'exploiter pour décrire les algorithmes de contrôle et d'inférence de types.

Un système de types s'appuie sur la syntaxe du langage pour lequel il est défini, associant aux noeuds de l'arbre syntaxique (construit par l'interpréteur ou le compilateur) une information de type sous la forme d'attributs. Nous donnons ici une représentation permettant de décrire la façon dont ces attributs sont calculés et/ou vérifiés.

Nous appuyons notre description sur un exemple de langage simple que nous nommerons L. Ce langage permet de décrire des programmes constitués d'un ensemble de variables typées et d'une expression unique. Sa grammaire est donnée par la figure 57. Les programmes décrits par le langage L (P) sont composés d'une partie déclaration (D) où sont déclarées les variables et les types (T) auxquelles elles appartiennent et d'une partie expression (E) combinant des littéraux et des variables (id) à l'aide des opérateurs d'addition d'entiers (+), de concaténation de chaînes (&), d'accès à un tableau, à une structure et d'application de fonctions.

P ® D ; E
D ® D ; D | id : T
T ® 'entier' ½ 'chaîne' | 'tableau' '[' entier ']' 'de' T |
     'structure' '{' D '}' |
     'fonction' '(' id ':' T ')' ':' T '{' E '}'
E ® littéral ½ nb ½ id ½ E '+' E ½ E '&' E |
     E '[' E ']' | E '.' id | E '(' E ')'

Figure 57 - Grammaire du langage L.

Le langage L est un langage fonctionnel ne contenant pas de structures de contrôle telles que les boucles ou les expressions conditionnelles. Les structures de contrôle ne posant pas de problèmes particulier pour le contrôle de type et nous les avons ignorées pour simplifier la syntaxe du langage.

Un programme est engendré par le non-terminal P de la grammaire. Les déclarations de variables typées (D) sont composées d'un identificateur et d'une expression de type. Voici un exemple de programme écrit avec le langage L qui calcule le double de la variable a :

a : entier;
double : fonction ( c : entier ) : entier
  {
    c + c
  };
double (a)

Les expressions de types de ce programme sont : entier (pour définir le type de la variable a) et fonction (entier) : entier (pour définir le type de la variable double).

Le langage L comme tous les langages de programmation définissent deux catégories de types, les types de base et les types construits :

Les expressions de type ne sont pas appropriées au algorithmes de contrôle de type. Il est plus commode de représenter les types sous forme de graphes. La figure 58 montre la représentation sous forme de graphe d'une expression de type. Dans un graphe de types, les noeud terminaux représentent les types de base et les noeuds non terminaux sont étiquetés avec les constructeurs des types qu'ils représentent (en police courrier), les noms de types appartenant à chacun des noeuds étant donnés à titre indicatif (en italique).

[Here is a Drawing]

Figure 58 - Un exemple de type construit et son graphe de types

Par la suite nous assimilerons un type et le graphe engendré par l'ensemble des sommets pouvant être atteints depuis le sommet représentant le type. Dans la figure 58, nous avons représenté le type ident en rouge.

Vérification du type d'une expression

Le contrôle de type d'une expression s'appuie sur un ensemble de règles sémantiques donnant le type de cette expression en fonction du type de ses opérandes. Pour les unités syntaxiques représentant les types de base, ces règles sont :

E ® littéral

chaîne

E ® nb

entier

La fonction TypeSymb recherche dans la table des symboles le type d'un identificateur id. Cette fonction est utilisée lorsqu'un identificateur est rencontré dans une expression :

E ® id

TypeSymb (id)

Le type d'une expression construite dépend du type de ses opérandes :

E ® E1 + E2

si Type (E1) = entier

et Type (E2) = entier

alors entier
sinon erreur de type.

E ® E1 & E2

si Type (E1) = chaîne

et Type (E2) = chaîne

alors chaîne

sinon erreur de type.

La vérification de type lors de l'accès à une cellule de tableau dépend du type des éléments du tableau. Pour désigner ces éléments, on utilise une variable de type t, permettant de faire abstraction du type de données stockés dans le tableau.

E ® E1[ E2]

si Type(E1) = tableau de t
et Type(E2) = entier
alors t

sinon erreur de type.

E ® ­E1

si Type(E1)= pointeur vers t
alors t

sinon erreur de type.

Lors de l'accès à un champ de structure il faut vérifier que l'identificateur de champ représente réellement un champ de la structure, pour cela, on utilise la fonction champs, retournant l'ensemble des identificateurs des champs d'une structure. La fonction ChercherType recherche le type d'un champ particulier d'une structure.

E ® E1.id

si Type (E1) = structure
et id Ì Champs (E1)
alors ChercherType (E1.id) sinon erreur de type.

E ® E1(E2)

si Type (E1) = fonction (t1) : t2
et Type (E2) = t1
alors t2 sinon erreur de type.

Un algorithme simple de contrôle de type consiste à parcourir l'arbre syntaxique de l'expression en calculant le type de chaque noeud en fonction des types de ses composants. Le type de l'expression est correct si l'algorithme ne retourne pas d'erreur de type.

Les fonctionalités décrites ci-dessus sont proposées par de nombreux langages de programmation et nécessitent la mise en oeuvre de techniques de contrôle de type plus complexes pour déterminer si un programme est bien typé et donc exempt d'erreurs non désirables à l'exécution (propriété de sûreté). Ces techniques avancées que sont l'inférence de type, la surcharge d'opérateur, la coercition, l'équivalence de types ou encore les fonctions polymorphes sont exposées dans la section suivante.

A.3 Limites et extensions du contrôle de types simple

Le langage et l'algorithme de vérification de type présentés ci-dessus sont basiques et ne supportent pas la plupart des caractéristiques de langages de programmation de haut niveau. Les caractéristiques suivantes ne sont pas proposées par le langage L et ne sont pas supportées :

  • Utilisation de variables de types : les critères d'égalité entre types ne se fondent que sur l'égalité des constructeurs. L'algorithme ne permet pas de déterminer si une variable du programme est compatible avec une variable de type. Le contrôle de type doit pouvoir déterminer si une expression du langage appartient à un type contenant des variables de types dans sa définition.
  • Types récursifs : l'utilisation des variables de types permet la définition de types intervenant dans leur propre définition. Cette propriété introduit des cycles dans le graphe de représentation des types de données, l'algorithme de contrôle de types doit prendre en compte la gestion des cycles.
  • Surcharge des opérateurs : dans le langage L chaque opérateur agit sur des opérandes dont le type est bien défini. Dans certains langages, le même opérateur peut représenter des opérations différentes quand il est appliqué à des types des données différentes. Un exemple simple est l'opérateur + qui peut être indifféremment appliqué à des opérandes entiers ou réels. La comparaison de types de données ne doit pas simplement se faire sur l'identification des types, mais sur des critères plus généraux.
  • Types implicites : le langage ML [Milner 90] admet l'utilisation d'identificateurs dont le type n'est pas déclaré. Lors de l'interprétation de programmes écrits dans ce langage, le système de types doit calculer le type de ces identificateurs lors de leur utilisation.
  • Abstraction des types de données : l'implémentation de fonctions indépendantes du type des objets qu'elles manipulent permet leur réutilisation dans des environnement différents.

Pour permettre ces fonctionalités dans un langage de programmation, tout en conservant la propriété de sécurité à l'exécution, un contrôleur de types doit intégrer :

  • une méthode d'inférence de type pour calculer le type des variables implicitement typées du programme, permettant ainsi la manipulation de variables implicitement typées ;
  • une méthode de calcul d'équivalence de types ne se basant pas seulement sur l'identification des types, mais sur leur construction structurelle (notion d'équivalence structurelle) et permettant de prendre en compte les types récursifs ;
  • une méthode de conversion de données entre types ayant des structures équivalentes.

A.4 Inférence de type

L'inférence de type a pour but de calculer, s'il existe, le type d'une expression non typée. Lorsqu'une expression est évaluée, les types de chacune des variables et de ses opérandes doivent être évalués pour savoir s'il sont compatibles avec l'opérateur.

Formellement, le problème de l'inférence de type est exprimé de la façon suivante : étant donnée une expression M, existe-t-il un type A parmi les types pouvant être engendrés par les règles du système de types tel que Type (M) = A ?

L'algorithme d'inférence de type d'une expression exploite la même structure de données que l'algorithme de vérification : Pour typer l'expression M, on parcoure l'arbre syntaxique de l'expression M en assignant à chaque noeud un attribut de type calculé conformément aux règles du système de types associé au langage.

Contrairement à l'algorithme de vérification de type, l'algorithme d'inférence parcourt l'arbre syntaxique d'une expression de bas en haut, en calculant un attribut type pour chacun des noeuds de l'expression (en rouge sur l'exemple de la figure 59) en fonction des attributs des fils du noeud.

Pour calculer le type de la variable e, l'algorithme calcule d'abord le type de ses opérandes. Le premier opérande est de type entier (2), l'autre est le résultat de l'accès au tableau n, si le type du tableau n est connu alors le système peut décider si l'expression à un type valide (tableau d'entier ou de réels) et affecter un type à la variable e.

Dans le cas où le type de n n'est pas connu, alors une nouvelle variable de type n est crée dans l'environnement, et le type tableau de n est affecté à la variable n. Le type de la variable e pourra être effectivement déterminé si l'opérateur + peut être appliqué à un entier et à n.


[Here is a Drawing]

e = 2 + n[3];


Figure 59 - Inférence du type d'une expression

Le problème de l'inférence se généralise à la reconstruction de type en calculant un type pour chacune des variables d'un programme. Pour cela toutes les variables de types non libres (ne pouvant être renommées) introduites lors de l'inférence doivent être valuées par des expressions de type. Il est montré dans [Cardelli 85] que ce problème est décidable pour les systèmes de types n'incluant pas de quantificateurs.

Lors de la reconstruction de types d'un programme il est fréquent de tester l'équivalence de deux expressions de types. Par exemple lorsqu'une variable à laquelle est associé une expression de type est modifiée, il faut comparer le type de la valeur affectée avec l'expression de type. Comme pour l'abstraction de types de données et pour la surcharge des opérateurs, un système de types permettant le typage implicite s'appuie sur l'équivalence des expressions de types.

A.5 Équivalence de types

Les systèmes de types des langages calculant la validité des types lors de l'abstraction de types de données, du nommage des expressions de type ou de la surcharge des opérateurs utilisent la notion d'équivalence de types de données. L'équivalence peut exister à plusieurs niveaux :

  • équivalence de noms : deux types sont équivalents si et seulement si ils portent le même nom. Les compilateurs des langages de programmation interdisant généralement les définitions multiples, deux variables appartenant à des types ayant le même identificateur appartiennent au même type.

    Cette notion d'équivalence est très restrictive car elle implique que les types des variables comparées soient nommés. L'équivalence de deux types « égaux », mais de noms différents ne sera pas relevée.

  • équivalence structurale : deux types sont équivalents s'ils ont le même constructeur et les types qui les définissent sont équivalents deux à deux.

    Cette définition permet de mettre en équivalence des types portant des noms différents en se basant sur la correspondance des constructeurs et l'équivalence des composantes du type :

    Soient deux types a et b de constructions respectives C(a1,¼,an) et C'(b1,¼,bm), où C et C' sont des constructeurs et ai, bj les types composants respectivement les types a et b. a et b sont structuralement équivalents si et seulement si :

    1. C est le même constructeur que C'.
    2. n = m et "i Î [1,n], ai est structuralement équivalent à bi.

L'équivalence structurale peut être implémentée par un algorithme de parcours de graphes dirigés sans cycles, mais cette implémentation ne permet pas de déterminer l'équivalence de types contenant des variables de types ou des définitions récursives.

L'algorithme d'unification permet de calculer l'équivalence structurale d'expressions contenant des variables de types. En conséquence, la récursion dans la définition des types est prise en compte.

Nous détaillons dans la suite un algorithme d'unification utilisant des classes d'équivalence de types pour prendre en compte la circularité du graphe de type.

A.5.1 Algorithme d'unification

L'algorithme d'unification permet de comparer deux types pour trouver une relation d'équivalence. Cet algorithme est une généralisation de l'algorithme d'unification donné dans [Aho 91] aux graphes de types n-aires.

Les types sont définis par des graphes orientés dont les noeuds représentent soit des types soit des variables de types. Le noeuds représentant des types sont étiquetés par le constructeur du type représenté. Les arcs représentent la relation « entre dans le définition de ».

Le principe de l'algorithme repose sur la construction de classes d'équivalence regroupant des noeuds en cours d'unification. Le rôle de ces classes d'équivalence est de ne pas répéter l'unification sur des noeuds participant aux cycles des graphes de types. Chaque classe est représentée de façon unique par un de ses noeuds.

La fonction Fusionner_Classes (n1, n2) permet de créer une nouvelle classe d'équivalence en fusionnant les classes auxquelles appartiennent les noeuds n1 et n2. Si une seule des deux classes est représentée par un noeud qui n'est pas une variable, Fusionner_Classes choisit ce noeud comme représentant de la nouvelle classe. Ainsi, un noeud correspondant à une variable ne peut être représentant d'une classe comprenant des noeuds correspondant à un type construit ou un type de base, ce qui mènerait à unifier à travers cette variable des noeuds non équivalents.

La fonction Trouver_Classe (n) retourne le représentant de la classe d'équivalence à laquelle appartient le noeud n.

Au début de l'unification chaque noeud représente une classe dont il est l'unique élément. Les conditions d'unifications des deux noeuds sont :

  • l'appartenance à la même classe,
  • la représentation d'un même type de base,
  • la représentation de deux types de même constructeur, à la condition de pouvoir unifier les types participant à leur construction (noeuds fils),
  • la représentation par l'un des noeuds d'une variable de type.

Algorithme :

Unifier (m, n : noeud) : booléen;
début
 s := Trouver_Classe (m);
 t := Trouver_Classe (n);
  
 si s = t alors retourner vrai;
 
 sinon si s et t sont des noeuds représentant le même type de
base 
   alors  retourner vrai;
 
 sinon si
  s est un noeud de constructeur a et de fils s1...sp et
  t est un noeud de constructeur a et de fils t1...tp 
   alors
    Fusionner_Classes (s, t);
    retourner (Unifier (s1, t1) et ... et Unifier (sp, tp));
 
 sinon si s ou t représente une variable alors 
   Fusionner_Classes (s, t);
   retourner vrai;
 
 sinon retourner faux;
 finsi
 
fin

Avec cet algorithme, on détermine si deux types sont équivalents. Si c'est le cas, toute variable d'un des deux types est utilisable à la place d'une variable de l'autre type tout en assurant la conformité de sa valeur, ce qui préserve la propriété de sécurité lors des surcharges d'opérateurs. Les variables relevant d'un type unifié avec un type cible peuvent également être converties dans ce type cible pour permettre une coercition sûre.

L'équivalence de type déterminée par l'algorithme d'unification est également utilisée pour l'inférence de type dans les langages implicitement typés (ML, Lisp).

References

[Adobe 91]
Adobe Systems Incorporated, PostScript Language, Addison-Wesley, Menlo Park, California, novembre 1991.
[Adobe 95]
Adobe Systems Incorporated, Manuel d'utilisaton de FrameMaker, version 5, Adobe, juin 1995.
[Adobe]
Adobe Systems Incorporated, Portable Document Format (PDF), en ligne [URI] http://www.adobe.com.
[Akpotsui 97]-->
E. Akpotsui, V. Quint, C. Roisin, ``Type Modelling for Document Transformation in Structured Editing Systems'', Mathematical and Computer Modelling, vol. vol. 25, num. 4, pp. 1-19, 1997.
[Akpotsui 93]
E. Akpotsui, Transformations de types dans les systèmes d'édition de documents structurés, Thèse de doctorat, Institut National Polytechnique de Grenoble, octobre 1993.
[Aho 91]
A. Aho, R. Sethi, J. Ullman, Compilateurs - Principes, techniques et outils, Addison-Wesley, Reading, Massachussets USA, 1991.
[AIS 96]
Balise 3 Reference Manual, AIS S.A, 1996.
[Arnon 93]
D.S. Arnon, ``Scrimshaw: A Language for Document Queries and Transformations'', Electronic Publishing - Origination, Dissemination and Design, proceedings of the EP'94 Conference, vol. 6, num. 4, pp. 385-396, Décembre 1993.
[ATA]
ATA, Air Transport Association of America,
en ligne [URI] http://www.air-transport.org.
[Belaïd 97]
Abdel Belaïd, ``Analyse du document : de l'image à la représentation par les normes de codage'', Document numérique, vol. 1, num. 1, pp. 21-38, 1997.
[Bonhomme 96]-->
S. Bonhomme, C. Roisin, ``Interactively Restructuring HTML Documents'', Computer Network and ISDN Systems, vol. 28, num. 7-11, pp. 1075-1084, May 1996.
[Bonhomme 97]
S. Bonhomme, V. Quint, H. Richy, C. Roisin, I. Vatton, Thot - Manuel utilisateur, 1997,
en ligne [URI] http://opera.inrialpes.fr/thot/doc/Thotman-F.html.
[Bos 98]
B. Bos, H. W. Lie, C. Lilley, I. Jacobs, Cascading Style Sheets, level 2 - CSS2 Specification, num. REC-CSS2-19980512, World Wide Web Consortium, mai 1998,
en ligne [URI] http://www.w3.org/TR/1998/REC-CSS2 .
[Bray 98a]
Tim Bray, al., Extensible Markup Language (XML) 1.0 - W3C Recommendation, num. REC-xml-19980210, World Wide Web Consortium, février 1998,
en ligne [URI] http://www.w3.org/TR/1998/REC-xml-19980210.
[Bray 98b]
T. Braw, al., Namespaces in XML - W3C Working Draft, num. WD-xml-names-19980802, World Wide Web Consortium, août 1998,
en ligne [URI] http://www.w3.org/TR/WD-xml-names .
[Burnard 95]
L. Burnard, Text Encoding for Information Interchange - An Introduction to the Text Encoding Initiative, num. TEI J31, Oxford University Computing Services, Juillet 1995.
[Cai 90]
J. Cai, R. Page, R. Trajan, ``More Efficient Bottom Up Pattern matching in Trees'', Proc. CAAP 90, vol. ed. A. Arnold, Lecture Notes in Computer Science , num. vol. 431, pp. 72-86, Springer-Verlag, 1990.
[Cardelli 85]
L. Cardelli, P. Wegner, ``On Understanding Type, Data Abstraction, and Polymorphism'', Computing Surveys, vol. 17, num. 4, pp. 471-522, Decmbre 1985.
[Chahuneau 97]
F. Chahuneau, ``XML une voie de convergence entre SGML et HTML'', Document numérique, vol. 1, num. 1, pp. 69-74, 1997.
[Clark]
J. Clark, The SP parser, en ligne [URI] http://www.jclark.com .
[Clark 98]
J. Clark, S. Deach, Extensible Stylesheet Language (XSL) Version 1.0 - W3C Working Draft, num. WD-xsl-19980818, World Wide Web Consortium, August 1998,
en ligne [URI] http://www.w3.org/TR/WD-xsl .
[Claves 95]
P. Claves, Restructuration dynamique de documents structurés, Mémoire CNAM, CNAM centre régional associé de Grenoble, Mars 1995.
[Cole 90]
F. Cole et H. Brown, Editing a Structured Document with Classes, num. report n.73, Computing Laboratory, University of Kent, 1990.
[Cole 92]
F. Cole, H. Brown, ``Editing structured Documents-problems and solutions'', Electronic Publishing--Origination Dessemination and Design, vol. 5, num. 4, pp. 209-216, décembre 1992.
[Cover]
R. Cover, The SGML/XML Web Page, Oasis,
[URI] http://www.oasis-open.org/cover .
[Digithome]
Introduction to IDM (Intelligent Document Manager), Digithome Electronic Publishing, Dublin, Ireland, 1996,
En ligne [URI] http://www.digithome.com.
[Dougherty 92]
D. Dougherty , Sed & Awk, O'eilly & Associates, 1992.
[English 96a]
J. English, Cost 2 Reference Manual, Janvier 1996,
En ligne [URI] http://www.art.com/cost/manual.html .
[English 96b]
J. English, RATFINK A library of RTF output utilities for Tcl Version 0.8, Mars 1996,
En ligne [URI] http://www.art.com/cost/ratfink/ratfink.html .
[Feng 93]
A. Feng, T.Wakayama, ``SIMON: A Grammar-based Transformation System for Structured Documents'', Electronic Publishing - Origination, Dissemination and Design, proceedings of the EP'94 Conference, vol. vol. 6 , num. 4, pp. 361 - 372, Décembre 1993.
[Fielding 98]
R. Fielding, al., Hypertext Transfer Protocol -- HTTP/1.1, num. draft-ietf-http-v11-spec-rev-04, World Wide Web Consortium, août 1998,
en ligne [adressse URL] http://www.w3.org/Protocols .
[Frilley 89]
F. Frilley, Différenciation d'ensembles structurés, Doctorat informatique, Université de Paris VII. mars 1989.
[Furuta 88a]
R. Furuta, V. Quint, J. André, ``Interactively Editing Structured Documents'', Electronic Publishing -- Origination, Dissemination and Design, vol. 1, num. 1, pp. 19-44, April 1988.
[Furuta 88b]
R. Furuta et P.D. Stotts, ``Specifying Structured Document Transformations'', Document Manipulation and typography, Cambridge University Press, ed., Procceding of the International Conference on Electronic Publishing, Document Manipulation and Typoraphy, Nice (France), 20-22 Avril 1988.
[Hirvonnen 95]
M. Hirvonen, H. Toivonen, Automatic Transformation of structured Documents, University of Kent at Canterbury, 1995.
[Hoffmann 82]
C.M. Hoffmann, M.J. O'Donnel, ``Pattern Matching in Trees'', Journal of the Association for Computing Machinery, vol. 29, num. 1, pp. 68-95, janvier 1982.
[Inso]
Dyna Tag, Inso Corporation,
en ligne [URI] http://www.inso.com/dynatext/dtagbrief.htm .
[Ion 98]
P. Ion, al., Mathematical Markup Language (MathML) 1.0 Specification - W3C Recommendation, num. REC-MathML-19980407, World Wide Web Consortium, avril 1998,
en ligne [URI] http://www.w3.org/TR/REC-MathML .
[ISO]
ISO, Organisation internationale de normalisation, Genève,
En ligne [URI] http://www.iso.ch.
[ISO 86]
ISO, Information Processing - Text and Office Systems - Standard Generalized Markup Language (SGML) , num. ISO 8879:1986, International Organization for Standardization, Geneva, 1986.
[ISO 94]
ISO, Information Technology - Text and Office Systems - Document Style Semantics and Specification Language (DSSSL), num. ISO/IEC DIS 10179.2:1994, International Organization for Standardization, Geneva, 1994.
[ISO 98a]
ISO, Information technology - Hypermedia/Time-based Structuring Language (HyTime), num. ISO/IEC JTC1/SC18/WG8 N1920, Organisation internationale de normalisation, Genève, 1998.
[ISO 98b]
ISO, Technologies de l'information -- Jeux de caractères graphiques codés sur un seul octet -- Partie 1: Alphabet latin no. 1 , num. ISO/IEC 8859-1:1998, Organisation internationale de normalisation, Genève, 1998.
[Kilpeläinen 92]
P. Kilpeläinen, Tree Matching Problems With Application to Structed Text Databases, num. A-1992-6, Department of computer science, University of Helsinki, Finland, 1992.
[Kuikka 93]
E. Kuikka, M. Pentonnen, ``Transformation of structured documents with the use of grammar'', Electronic Publishing - Origination, Dissemination and Design, proceedings of the EP'94 conference, vol. 6, num. 4, pp. 373-383, décembre 1993.
[Lambolez 95]
P-Y. Lambolez, J-P. Queille, J-F.Voidrot, Claude Chrisment, ``EXREP: a generic rewriting tool for textual information extraction'', Ingénerie des systèmes d'information, vol. Volume 3, num. 4, pp. 471 à 487, 1995.
[Lamport 85]
L. Lamport, LaTeX : A document preparation system, Addisson-Wesley, Reading, Massachussets, 1985.
[Lassila 98]
O. Lassila, R.R. Swick, Resource Description Framework(RDF) Model and Syntax Specification, num. WD-rdf-syntax-19981008, World Wide Web Consortium, Octobre 1998,
en ligne [Adresse URL] http://www.w3.org/TR/WD-rdf-syntax .
[Layaida 97]
N. Layaïda, Madeus : syatème d'édition et de présentation de documents structurés multimédia, Thèse de doctorat, Université Joseph Fourier - Grnoble 1, juin 1997.
[Le Maitre 95]
J. Le Maitre, E. Murisasco, M. Rolbert, ``SgmlQL, un langage d'interrogation de documents structurés'', Actes des 11èmes journées BDA'95, vol. Nancy, , août 1995.
[Le Maitre 98]
J. Le Maitre, E. Murisasco, M. Rolbert, ``From annotated Corpora to Databases : the SgmlQL language'', CSLI lectures notes, vol. n. 77,, janvier 1998.
[Levine 92]
J.R. Levine, T. Mason, D. Brown, Lex & Yacc, O'Reilly & Associates, 1992.
[Maler 98]
E. Maler, S. DeRose, XML Linking Language (XLink) - W3C Working Draft, num. WD-xlink-19980303, World Wide Web Consortium, Mars 1998,
en ligne [URI] http://www.w3.org/TR/WD-xlink .
[Mamrak 89]
S.A. Mamrak, M.J. Kaelbling, C.K. Nicholas, M. Share, ``Chameleon: A System for Solving the Data-Translation Problem'', IEEE Transactions on Software Engineering, pp. 1090-1108, septembre 1995.
[Microsoft 92]
Microsoft Incorporation, Microsoft Word : Guide de l'utilisateur, 1992.
[Microsoft 98]
Microsoft Incorporation, Rich Text Format (RTF) Specification, en ligne, [URI] http://premium.microsoft.com/msdn/library/specs/f15/d11/s6cd3.htm.
[Milner 90]
R. Milner, M. tofte, R. Harper, The Definition of standard ML, The MIT Press, 1990.
[Pepper]
S. Pepper, The Whirlwind Guide to SGML & XML Tools and Vendors, Infotek, [URI] http://www.infotek.no/sgmltool/guide.htm .
[Quint]
V. Quint, I. Vatton, La boite à outils de Thot, INRIA, [en ligne] http://opera.inrialpes.fr/thot/doc/APIman.toc.html.
[Quint 94]
V. Quint, I. Vatton, ``Making Structured Documents Active'', Electronic Pulishing -- Origination, Dissemination and Design, vol. vol. 7, num. 2, pp. 55-74, juin 1994.
[Quint 98]
V. Quint, I. Vatton, ``An Introduction to Amaya'', World Wide Web Journal, vol. 2, num. 2, pp. 39-46, Printemps 1997.
[Raggett 98]
D. Raggett, A. Le Hors, Ian Jacobs, HTML 4.0 Specification - W3C Recommendation, num. REC-html40-19980424, World Wide Web Consortium, Avril 1998,
en ligne [URI] http://www.w3.org/TR/REC-html40 .
[Rus 94]
D. Rus, K. Summers, ``Using White Space for Automated Document Structuring'', Proceedings of the Workshop on Principles of Document Processing, 1994.
[Unicode 96]
The Unicode Consortium, The unicode Standard, Version 2.0, Addison-Wesley, Juillet 1996.
[Schrod 95]
J. Schrod, Christine Detig, STIL - SGML Transformation in Lisp, août 1995,
en ligne [URI] ftp://ftp.th-darmstadt.de/pub/text/sgml/stil/stil.ps.
[Sklar 94]
David Sklar, ``Accelerating Conversion to SGML via the Rainbow Format'', <TAG>, vol. 7, num. 1, pp. 4-5, Janvier 1194.
[Trombettoni 97]
G. Trombettoni, Algorithmes de maintien de solution par propagation locale pour les systèmes de contraintes, Thèse de doctorat, Université de Nice-Sophia Antipolis, juin 1997.
[Wood 98]
L. Wood, al., Document Object Model (DOM) Level 1 Specification - Version 1.0 - W3C Proposed Recommendation, num. PR-DOM-Level-1-19980818, World Wide Web Consortium, août 1998, en ligne [URI] http://www.w3.org/TR/PR-DOM-Level-1 .
[W3C]
The World Wide Web Consortium,
en ligne [URI] http://www.w3.org .
[W3C a]
W3C HTML Validation Service, World Wide Web Consortium,
en ligne [URI] http://validator.w3.org/ .
[W3C b]
W3C, W3C XML Software, World Wide Web Consortium,
en ligne [URI] http://www.w3.org/XML/#software.

Footnotes

[1]
disponible à l'URI : ftp://ftp.funet.fi/pub/languages/perl/CPAN/modules/by-module/SGMLS
[2]
La condition de sélection entre les états M3et M'3n'est cependant plus j'< j-1 mais j'< a (jp)-1, jp étant le noeud cible du pré-couple.

[Table of contents]