Le Langage d'Action
Déclenchement de l'analyseur
Localisation du code
Navigation dans le modèle statique
Types primitifs connus
Accès aux services définis dans les ponts
OOA
Les événements
Envoi d'événement à un assigneur
Accès aux paramètres d'evts d'une action
dans un état
Liens Associatifs: accès normal, accès à
la classe associative
Variables Temporaires
Boucles de Test
Sélection
Blocs
Opérateurs généraux
Opérateurs ensemblistes
Opérateurs booléens
Opérateurs entiers
Opérateurs chaînes
Exemple de langage d'actions
Syntaxe du langage d'actions
Déclenchement de l'analyseur
Il est déclenché après toute modification du code
soit automatiquement (le mode est alors non interactif),
soit par demande de l'utilisateur sur pression de bouton (le mode est
alors interactif)
L'utilisateur peut demander à revérifier tout le code
par le menu "Règles"|"Langage d'Actions"|"Vérifier tout le
Code".
Localisation du code
Le code peut être saisi:
* au niveau d'une action d'un état
* sur un service
* sur un attribut calculé
Navigation dans le modèle statique
un rôle possède un prédicat verbal et un nom de navigation
:
c'est le nom de navigation qu'il faut
utiliser dans le langage d'actions
THIS désigne l'objet récepteur
de l'expression courante
expr.att accès à att,
où att peut être un attribut ou un rôle, pour
chaque élément de expr ; on obtient donc l'ensemble
des att des éléments de expr.
la navigation pointée est sans limite; soit le modèle OOA
suivant:
Les expressions suivantes appliquées à une instance ctrl1
de la classe Contrôle sont valides :
controls.precond : accès aux préconditions (precond)
des tâches contrôlées par ctrl1 (controls)
controls.postconds.impacted_tasks : accès aux tâches
impactées (impacted_tasks) par les postconditions (postconds)
des tâches contrôlées par ctrl1 (controls)
Types primitifs connus
String
Integer
Boolean
Accès aux services définis dans les
ponts OOA
C.serv où C est la clé du
domaine de service à accéder, serv le service accédé
dans le domaine de service
Les événements
^evt(...) ou expr.^evt(...) : envoi de l'événement
evt à la classe courante, ou aux classes de expr ;
si l'événement n'existe pas dans certaines classes réceptrices,
il est proposé à l'utilisateur de le créer pour chacune
des classes qui ne le reçoivent pas .
Envoi d'événement à un assigneur
ASSIGNER A3.^evt(...) : envoi de l'événement
evt à l'assigneur porté par la relation de lettre
clé A3 ; si l'événement n'existe pas, il est
proposé à l'utilisateur de le créer .
Accès aux paramètres d'evts d'une
action dans un état
Si un état est atteint suite à réception de
l'événement evt(arg1, arg2, ...), alors arg1, arg2,
... peuvent être directement utilisés dans le code de
l'action.
Liens Associatifs: accès normal, accès
à la classe associative
Reprenons le modèle ci-dessus. Pour obtenir les tâches impactées
(instances des classes Contrôle ou Elémentaire),
nous avons écrit: controls.postconds.impacted_tasks
Pour obtenir les instances de la classe associative Impactée,
il faut écrire : controls.postconds.@impacted_tasks
Variables Temporaires
TMP var := val; déclaration de la
variable temporaire var avec affectation de la valeur val
Boucles de Test
c IF TRUE: ex1 IF FALSE: ex2
test booléen
val IF 1: ex1 IF 2: ex2 IF 3: ex3
switch/case
val IF 1: ex1 IF 2: ex2 ELSE: ex3
switch/case avec default
s1 DEFAULT s2 retourne
s1 si non vide, s2 sinon
Sélection
expr[cond] sélection suivant la condition
cond
EACH variable de boucle dans une sélection
ou une itération récursive, permet de désigner l'objet
courant traité dans la sélection
Blocs
expr.{...} application du code compris entre
les parenthèses à chaque élément issu de expr
THIS permet à l'intérieur
du bloc d'accéder à la classe
une expression, un attribut, ou un rôle à l'intérieur
d'un bloc sont relatifs au type de expr
EACH variable de boucle dans une sélection
ou une itération récursive, permet de désigner l'objet
courant traité dans la boucle
!EACH, !!EACH, ... variables de boucle de
niveaux supérieurs
Opérateurs généraux
PRINT(x) représentation chaîne
de x
CLASSNAME(x) nom de la classe de x
x ISA C teste si x est de la classe C
NEW C crée une instance de la classe
C
VOID C liste vide de type C
ALL C tous les objets de classe C (ou sous-classes)
DESTROY(x) détruit l'entité
x
a := ex affectation
a += ex ajout
a -= ex suppression
Opérateurs ensemblistes
s1 = s2 égalité (l'ordre importe)
s1 /= s2 inégalité
s1 $+ s2 union
s1 $* s2 intersection
s1 $- s2 complémentaire de s2 dans
s1
s1 $< s2 teste si s1 est inclus dans
s2
CNT(s) nombre d'éléments de
s
SOME(s) TRUE si s est non vide
NO(s) TRUE si s est vide
FIRST(s) extrait le premier élément
de s
LAST(s) extrait le dernier élément
de s
Opérateurs booléens
TRUE
FALSE
NOT(b) négation
b1 + b2 ou
b1 * b2 et
Opérateurs entiers
e1 + e2
e1 - e2
e1 * e2
e1 / e2&
=
/=
<=
>=
<
>
Opérateurs chaînes
"abc" chaîne de caractères
abc ; caractères spéciaux dans une chaîne :
"" devient
"
"n devient
un saut de ligne
"t devient
un tab
s1 + s2 concaténation de s1 et s2
Exemple de langage d'actions
Voici une partie de l'automate de la classe Contrôle du modèle
présenté précédemment:
Syntaxe du langage d'actions
La syntaxe du langage d'actions est exprimée ici en formalisme yacc.
%token TMP SORTBY
%token THIS EACH ISA TRUE FALSE
%token TYPEOP
%token IF ELSE
%token "+="
%token "+" "-" "*" "/" OTHEROP PREOP POSTOP
%token FUNCTION
%token "(" ")" "{" "}" "[" "]" "|"
%token ";" "," ":" "." "#" QUALIFIER "!" INFINITY
%token Name StringLiteral IntegerLiteral REEL
%token "-option"
%%
specification
:
| exprRpt1SC SCOpt;
/* expr: */
expr
: expr0;
expr0
: expr1
| name "+=" expr0
| TMP name "+=" expr0
| expr2 "." name "+=" expr0
| expr1 ifSelectorRpt1;
ifSelector
: IF literal ":" expr1
| ELSE ":" expr1;
expr1
: exprPreUnary
| expr1 op exprPreUnary
| expr1 ISA classId;
op : "+" | "-" | "*" | "/" | OTHEROP;
exprPreUnary
: exprPostUnary
| PREOP exprPreUnary;
exprPostUnary
: expr2
| exprPostUnary POSTOP;
expr2
: expr3
| expr2 "." name
| expr2 "." name "(" parameterList0 ")"
| expr2 "." qual name
| expr2 "." qual name "(" parameterList0 ")"
| expr2 "." beginEach "*" block
| expr2 "." beginEach "*" classId gEach ":" ":" block
| expr2 "." beginEach block
| expr2 "[" beginEach expr1 "]"
| expr2 "." beginEach SORTBY "(" expr ")";
gEach : ;
beginEach : ;
expr3
: name
| name "(" parameterList0 ")"
| qual name
| qual name "(" parameterList0 ")"
| FUNCTION "(" parameterList0 ")"
| THIS | each
| literal
| TYPEOP typeId
| block;
each
: EACH
| "!" each;
block
: "(" expr ")"
| "{" exprRpt1SC SCOpt "}";
literal : string
| IntegerLiteral | "-" IntegerLiteral
| REEL | "-" REEL
| INFINITY | TRUE | FALSE | "#" identifier | identifier "#" identifier;
classId : identifier;
typeId : identifier;
name : identifier;
identifier : Name;
string : StringLiteral | StringLiteral "|" StringLiteral;
qual : QUALIFIER;
ifSelectorRpt1 : ifSelector | ifSelectorRpt1 ifSelector;
parameterList0 : | parameterList1;
parameterList1 : expr | parameterList1 "," expr;
exprRpt1SC : expr | exprRpt1SC ";" expr;
SCOpt : | ";";