• Aucun résultat trouvé

1.2 Définition d’un langage

1.2.3 Les différents styles de définition de la sémantique comportementale

Dans la littérature, différents styles peuvent être utilisés pour définir la sémantique d’un langage [Kle07 ; SK95 ; Mos06 ; Com08]. Les approches opérationnelle, dénotationnelle, trans-lationnelle et axiomatique permettent de définir la sémantique comportementale d’un langage.

1.2. Définition d’un langage

La sémantique axiomatique peut également être utilisée pour spécifier la sémantique structu-relle sous forme de contraintes. D’autres approches existent [SK95 ; Mos06] mais elles peuvent souvent être vues comme des variantes ou des combinaisons des quatre approches mention-nées précédemment. Pour illustrer chacune d’entre elles, nous allons décrire la sémantique de la fonction add qui permet d’obtenir le résultat (res) de l’addition de deux nombres (op1 et op2).

1.2.3.1 Sémantique opérationnelle

La sémantique opérationnelle permet de décrire l’exécution d’un programme sous la forme d’une séquence de pas d’exécution [Kle07]. Elle est souvent représentée sous la forme d’un système de transitions où chaque nœud est appelé un état d’exécution ou une configuration. Un nœud regroupe les valeurs à un instant donné de l’ensemble des attributs dynamiques qui évoluent au cours de l’exécution. L’ensemble des nœuds modélisent donc tous les états pos-sibles de l’exécution du programme, c.-à-d. son espace d’état. Les transitions correspondent aux pas d’exécution permettant de passer d’une configuration à une autre en appliquant un ensemble d’opérations sur l’état d’exécution courant. Cette sémantique est aussi qualifiée d’intentionnelle [GDT14] car elle se focalise sur l’intention c.-à-d. la séquence des pas d’exécu-tion permettant d’obtenir le résultat. La sémantique opérad’exécu-tionnelle peut donc être vue comme une suite de transformations successives modélisant la façon dont l’exécution du programme progresse d’un état d’exécution à un autre.

Pour la fonction add, la Figure 1.2 représente le système de transitions qui capture sa sémantique opérationnelle. Les valeurs a, b et c ∈ Z représentent respectivement les valeurs initiales de op1, op2, et res pour un programme donné. L’application de la fonction add est modélisée par la transition de la configuration i à la configuration j.

FIGURE1.2 – Sémantique opérationnelle de la fonction add.

Les sémantiques opérationnelles sont habituellement classifiées en deux catégories [SK95]. Les sémantiques à petits pas (ou en anglais Structural Operational Semantics (SOS) [Plo04]) utilisent des pas atomiques pour décrire l’exécution d’un programme. Dans ce cas, les pas d’exécution ne peuvent pas être découpés plus finement. Les sémantiques à grands pas (ou sémantiques naturelles [Kah87]) décrivent globalement comment les résultats de l’exécution d’un programme sont obtenus. Chaque pas est donc composé d’un ensemble de pas d’exécu-tion atomiques mais seul le résultat global de l’exécud’exécu-tion de tous ces pas est observable.

1.2.3.2 Sémantique dénotationnelle

La sémantique dénotationnelle associe à chaque élément e d’un programme sa dénota-tion A[[e]]σ dans le domaine sémantique choisi c.-à-d. un objet mathématique qui représente le comportement désigné par e [Kle07 ; SK95]. Une dénotation est typiquement construite à l’aide d’une fonction prenant en argument des données d’entrées et fournissant en sortie des don-nées représentant le résultat de cette fonction. La sémantique dénotationnelle ne s’intéresse pas aux différents pas d’exécution nécessaires pour calculer les sorties mais seulement aux liens entre les entrées et les sorties c.-à-d. à l’effet des programmes. Elle est aussi qualifiée de sémantique extensionnelle [GDT14] car seules les relations visibles entre les entrées et les sorties (c.-à-d. l’extension) comptent. En ce sens, la sémantique dénotationnelle correspond à une abstraction de la sémantique opérationnelle.

La particularité d’une sémantique dénotationnelle est d’être composable [SK95] c.-à-d. que la dénotation d’un élément peut être construite à partir des dénotations de ces sous-éléments. La dénotation d’un élément dépend aussi de l’environnement d’exécution (c.-à-d. de l’état de la mémoire) tel qu’il existe une fonction σ qui associe à chaque variable x sa valeur telle que σ : x → Z. La sémantique dénotationnelle de la fonction add peut ainsi être exprimée de la façon suivante :

A[[add(op1, op2)]]σ = A[[op1]]σ+ A[[op2]]σ = σ(op1) + σ(op2).

1.2.3.3 Sémantique translationnelle

La sémantique translationnelle, aussi appelée sémantique par traduction, permet d’expri-mer la sémantique d’un langage en traduisant des programmes de ce langage source vers un langage cible dont la sémantique est rigoureusement définie [Kle07]. Autrement dit, les concepts des programmes du langage source sont exprimés en termes des éléments de la syntaxe (abstraite ou concrète) du langage cible. La sémantique du langage cible étant énon-cée précisément, il est ainsi possible de connaître la signification des éléments du programme source.

Le Listing 1.1 montre le résultat de la traduction en assembleur Thumb de la fonction add. L’outil permettant de faire la traduction capture ainsi la sémantique de cette fonction sous forme translationnelle.

.thumb // Type du jeu d’instructions

.text // Section de code

.global add // Rend la visibilité de la fonction add publique add:

1.2. Définition d’un langage

ADD r0, r0, r1 // Addition de op1 et op2 (dans r0 et r1): r0 = r0 + r1

MOV pc, lr // Retour à l’appelant avec le résultat dans r0

Listing 1.1 – Fonction add en assembleur Thumb obtenue grâce à une sémantique translationnelle.

1.2.3.4 Sémantique axiomatique

La sémantique axiomatique permet de définir la sémantique d’un langage à l’aide de pro-positions logiques (les axiomes) qui décrivent l’effet d’un programme sous forme d’assertions sur l’état du programme [Kle07]. Les axiomes peuvent être spécifiés sous forme d’invariants pour indiquer que toutes les exécutions d’un programme doivent satisfaire certaines condi-tions. Ils peuvent aussi être exprimés sous forme de préconditions et de postconditions sur les opérations d’un programme. L’algorithme d’une opération doit ainsi s’assurer de satisfaire les postconditions à partir des hypothèses posées par les préconditions. La sémantique axioma-tique peut être vue comme une abstraction de la sémanaxioma-tique dénotationnelle car elle définit une relation entre les entrées et les sorties sans modéliser l’état du programme.

La sémantique axiomatique de la fonction add est présentée dans le Listing 1.2 avec le formalisme ACSL de Frama-C2 [Kir+15]. Le mot-clé ensures exprime une post-condition sur le résultat (\result en ACSL) à partir des valeurs initiales de op1 et op2 identifiées avec le mot-clé\old.

/*@ ensures \result == \old(op1) + \old(op2) */ int add (int op1, int op2);

Listing 1.2 – Sémantique axiomatique de la fonction add avec le formalisme ACSL.

Conclusion sur la sémantique des langages La signification des concepts d’un langage est définie par sa sémantique. Celle-ci peut être capturée en utilisant différents styles dont les quatre principaux (c.-à-d. opérationnel, dénotationnel, translationnel et axiomatique) ont été présentés dans cette section. Dans le cadre de cette thèse, nos travaux s’intéressent princi-palement à la sémantique comportementale des langages afin de définir des moteurs d’exé-cution permettant d’exécuter des programmes conformes à ces langages. Dans la suite de ce document (sauf mention contraire), l’utilisation du terme “sémantique” fera donc référence à la sémantique comportementale et non à la sémantique structurelle.