RIA
laboria

laboratoire de recherche
en informatique
et automatique

ARCHIVES

Présentation
du langage LEX
pour systèmes
d'exploitation portables.

J.F. Challine.

J.P. Fischbach.

55p

Institut de Recherche
d'Informatique
et d'Automatique

Domaine de Voluceau
Rocquencourt
78150 - Le Chesnay
Tél. 954.90.20

Rapport de Recherche n°29
août 1973.
PRÉSENTATION DU LANGAGE LEX
POUR SYSTEMES D'EXPLOITATION PORTABLES

J.F. Challine

J.P. Fischbach

(présenté par M. Depeyrot)

RÉSUMÉ

Le langage LEX, élaboré dans le cadre du projet SPECTRE [4], est présenté. Langage de haut niveau
il incorpore un certain nombre de caractéristiques de bas niveau qui en font un outil très adapté à
l'écriture d'exécutifs portables. Le parallélisme existant entre unité centrale et programmes de traite-
ment d'une part, voies de liaison et programmes d'entrée sortie d'autre part a conduit à une forma-
lisation poussée des entrées-sorties caractérisant principalement le langage.

Cette version "brute" du langage, destinée à incorporer des innovations élaborées intuitivement, ser-
vira par la suite à expérimenter l'efficacité de méthodes théoriques de structuration des langages. Ceci
devrait permettre d'en dégager ultérieurement une version "nette" et rigoureuse tout en démontrant
éventuellement les retombées que l'on peut attendre d'une approche formelle.

ABSTRACT

The LEX language, elaborated within the SPECTRE project [4] is presented. As a high-level language it includes a number of low level characteristics that make it a tool best-fitted for writing portable operating systems. Parallelism between central processing units and their programs on one hand, channel links and input-output programs on the other hand, has lead to a thorough formalization of input-output operatories that mainly characterize the language.

This "raw" version of the language aimed at incorporating intuitively elaborated innovations will be
later used to experiment efficiency of theoretical methods for structuring languages. This should
permit to exhibit later a "refined" and rigorous version while possibly demonstrating the impact that
should be expected from a formal approach.
## I. INTRODUCTION :

I.1. Langage pour systèmes d'exploitation.

I.2. Langage extensible.

I.3. Langage portable.

I.4. Langage pour modules adaptables.

## II. DESCRIPTION DU LANGAGE :

II.1. Notations employées pour les définitions syntaxiques.

II.2. Elements constitutifs du langage.

II.2.1. Jeu de caractères.

II.2.2. Symboles de base du langage.

II.2.3. Les identificateurs.

II.2.3.a. Variable simple.

II.2.3.b. Variable indicée.

II.2.3.c. Postfixation.

II.2.3.d. Préfixation.

II.2.4. Les nombres.

II.3. Configuration d'un programme LEX.

II.4. Types de variables, syntaxe de leurs déclarations.

II.4.1. Types de variables.

II.4.2. Déclarations.

II.4.2.1. Variable simple.

II.4.2.2. Tableau.

II.4.2.3. Sous-tableau.

II.4.3. Déclaration de champs.
<table>
  <tbody>
    <tr>
      <td>II.5.Les expressions arithmétiques en LEX.</td>
      <td>10</td>
    </tr>
    <tr>
      <td>II.5.1.Présentation.</td>
      <td>10</td>
    </tr>
    <tr>
      <td>II.5.2.Syntaxe.</td>
      <td>10</td>
    </tr>
    <tr>
      <td>II.5.3.Quelques remarques.</td>
      <td>11</td>
    </tr>
    <tr>
      <td>II.6.Les instructions de base.</td>
      <td>12</td>
    </tr>
    <tr>
      <td>II.6.1.Etiquetage.</td>
      <td>12</td>
    </tr>
    <tr>
      <td>II.6.2.Notion de bloc BEGIN, END.</td>
      <td>12</td>
    </tr>
    <tr>
      <td>II.6.3.Instruction d'affectation.</td>
      <td>12</td>
    </tr>
    <tr>
      <td>II.6.4.Instruction conditionnelle.</td>
      <td>13</td>
    </tr>
    <tr>
      <td>II.6.5.Boucle.</td>
      <td>13</td>
    </tr>
    <tr>
      <td>II.6.6.Instruction choix.</td>
      <td>14</td>
    </tr>
    <tr>
      <td>II.6.7.Instruction de branchement.</td>
      <td>14</td>
    </tr>
    <tr>
      <td>II.6.8.Instructions d'entrée/Sortie.</td>
      <td>14</td>
    </tr>
    <tr>
      <td>II.6.9.Initialisation des champs.</td>
      <td>14</td>
    </tr>
    <tr>
      <td>II.6.10.Instructions d'activation.</td>
      <td>15</td>
    </tr>
    <tr>
      <td>II.6.11.Instructions de retour.</td>
      <td>15</td>
    </tr>
    <tr>
      <td>II.6.12.Construction d'un paquet.</td>
      <td>15</td>
    </tr>
    <tr>
      <td>II.7.Entrées/Sorties :</td>
      <td>15</td>
    </tr>
    <tr>
      <td>II.7.1.Introduction.</td>
      <td>15</td>
    </tr>
    <tr>
      <td>II.7.2.Généralités.</td>
      <td>16</td>
    </tr>
    <tr>
      <td>II.7.3.Instructions d'E/S.</td>
      <td>18</td>
    </tr>
    <tr>
      <td>II.7.4.Ordres d'E/S.</td>
      <td>21</td>
    </tr>
    <tr>
      <td>II.7.4.1.Ordres de positionnement.</td>
      <td>21</td>
    </tr>
    <tr>
      <td>II.7.4.2.Ordres de transmission.</td>
      <td>25</td>
    </tr>
    <tr>
      <td>II.7.4.3.Améliorations à apporter.</td>
      <td>26</td>
    </tr>
    <tr>
      <td>II.8.Primitives, procédures et échanges.</td>
      <td>27</td>
    </tr>
    <tr>
      <td>II.8.1.Primitive.</td>
      <td>27</td>
    </tr>
    <tr>
      <td>II.8.2.Procédure.</td>
      <td>29</td>
    </tr>
    <tr>
      <td>II.8.3.Echanges.</td>
      <td>30</td>
    </tr>
  </tbody>
</table>
<table><thead><tr><th></th><th>Page :</th></tr></thead><tbody><tr><td>II.9.Le sectionnement dans LEX.</td><td>32</td></tr><tr><td>II.9.1.Faciliter l'élaboration de la maquette.</td><td>32</td></tr><tr><td>BERGSON-ASMAT.</td><td></td></tr><tr><td>II.9.2.Faciliter la description d'un système modulaire.</td><td>33</td></tr><tr><td>III.ANNEXES :</td><td>40</td></tr><tr><td>III.1.Annexe 1.Liste des caractères spéciaux.</td><td>40</td></tr><tr><td>III.2.Annexe2.Liste des mots-clés.</td><td>41</td></tr><tr><td>III.3.Annexe 3.Définition syntaxique en méta-5.</td><td>43</td></tr></tbody></table>
# I. INTRODUCTION :

Le langage LEX (Langage pour Exécutifs aussi bien que Langage Extensible) est caractérisé par ses quatre objectifs principaux [1] :

## I.1. Langage pour systèmes d'Exploitation :

LEX est doté des propriétés d'un langage de haut niveau (expressions arithmétiques branchements conditionnels) mais aussi de propriétés de bas niveau en ce qui concerne l'allocation et la gestion de la mémoire, la gestion des entrées/sorties. (cf. paragraphes II.4. et II.7). Par conséquent le langage est adapté à une description à la fois claire et efficace de systèmes d'exploitation.

## I.2. Langage extensible :

Le compilateur de LEX s'appelle BERGSON [2], il est rédigé en META-5 (L) [3]. L'ensemble des règles assurant la compilation du noyau de base de LEX s'appelle la Loi de BERGSON. Cette Loi peut se voir augmenter de DECRETS assurant la compilation des extensions ou modifications apportées au langage au fur et à mesure des nécessités de la description. Les facilités fournies par l'emploi de META-5 permettent l'adaptation rapide de BERGSON.

## I.3. Langage portable :

LEX est destiné à la description d'exécutifs portables sur une classe de minimachines. La portabilité sera accrue si la paramétrisation se fait au niveau le plus bas possible, au niveau de la phase pragmatique de la compilation.

La chaîne de traduction automatique de SPECTRE conduit de LEX aux codes machines des minicalculateurs de la classe.
<figure><img src="image_1.png" /></figure>

La paramétrisation se fait à deux niveaux :

- au niveau source la *division d'environnement* permet la description complète de la machine objet.

- au niveau pragmatique (ASSIRIA(A). [6]) la *division de configuration* permet la prise en compte effective des caractéristiques de la machine-objet visée.

ASSIRIA(A) est un langage d'assemblage portable assemblé dans BERGSON par le TIGRE (Traducteur Intégré de Gestion des Effets Réels).

La possibilité d'utiliser à l'I.R.I.A. un T.2000, machine appartenant à la classe, permet l'élaboration d'une maquette de BERGSON appelée BERGSON-ASMAT, n'ayant pas les caractéristiques définitives envisagées (la phrase pragmatique intermédiaire n'est pas implémentée, l'assemblée ASMAT du T.2000 est utilisée), posant de nouveaux problèmes (cf. le sectionnement paragraphe II.9.) mais permettant les tests et la mise au point de SPECTRE.

**I.4. Langage pour modules adaptables :**

La configuration de LEX (cf. paragraphe II.9.) permet une description claire des modules d'un système d'exploitation ainsi que des mécanismes d'interface entre ces modules. Chaque module formant une entité bien particulière doit pouvoir être modifié, adapté à de nouveaux besoins.
La description itérative d'exécutifs telle qu'elle est envisagée dans SPECTRE [4] implique la nécessité de mémoriser l'état d'avancement de l'élaboration du système en cours, c'est l'un des rôles de la division d'environnement [5]. Celle-ci comprenant une description détaillée de la machine objet visée, permettra également de vérifier l'adéquation des modules entre eux, le respect des interfaces.

LEX est adapté à la mise à jour de la division d'environnement (cf. la section- nement) donc à son utilisation rationnelle.
## II. DESCRIPTION DU LANGAGE :

### II.1. Notations employées pour les définitions syntaxiques :

Le formalisme suivant sera utilisé pour la description syntaxique du langage.

- les éléments non terminaux sont placés entre les caractères `<` et `>`.

- les symboles de base du langage apparaissent tels quels.

- le caractère | sépare deux éventualités.

- les caractères juxtaposés `::=` signifient "est défini par".

- les accolades `{` et `}` servent à encadrer plusieurs éventualités de même niveau dans une description.

- les crochets `[` et `]` spécifient que le contenu peut apparaître une ou plusieurs fois ou être omis.

### exemples :

`<lettre> ::= A|B|C|....|Y|Z`

`<chiffre> ::= 0|1|2|....|9`

`<identificateur de variable> ::= <lettre>[<lettre>|<chiffre>]`

`<valeur numérique>::= {+|-} <entier>`

`<entier>::= <chiffre> [<chiffre>]`

### II.2. Eléments constitutifs du langage :

Ces éléments comprennent :

- un jeu de caractères.

- des symboles de base.

- des identificateurs et des valeurs numériques.

#### II.2.1. Jeu de caractères :

`-lettres de l'alphabet : (26) A B C...XYZ`

utilisées pour former des identificateurs de variables, des étiquettes, des commentaires.
-<u>chiffres décimaux</u> : (10) 0 1 2...9

utilisés pour former des nombres et certains identificateurs de variables.

-<u>caractères spéciaux</u> : dont on trouvera une liste en annexe 1. Ces caractères sont utilisés pour former des opérateurs précisés également dans l'annexe 1.

## II.2.2.Symboles de base du langage :

Les instructions du langage LEX sont écrites en utilisant des mots-clés non réservés dont l'annexe 2 fournit une liste complète et la signification.

### II.2.3.Les identificateurs :

#### II.2.3.a.Variable simple :

Une variable simple est désignée par une suite de lettres et/ou de chiffres commençant toujours par une lettre et que l'on appelle identificateur. Aucune limitation n'est imposée sur le nombre de caractères.

exemples : A
PROC12
IDENTIFICATEUR1

#### II.2.3.b.Variable indicée :

Une variable indicée est constituée d'un identificateur suivi d'un indice précisé entre parenthèses.

Remarque : Aucun caractère blanc ne doit séparer l'identificateur de la parenthèse ouvrante.

Une variable indicée désigne un élément de tableau (ARRAY) ou de sous tableau (SUBARRAY).

L'indice est un nombre, une variable ou une expression arithmétique correcte (cf. paragraphe II.5.).

exemples : A(1)
TAB (PROC12)
TABRO (A*2/F)
### II.2.3.c. Postfixation :

Un identificateur de variable simple de type WORD (cf. paragraphe II.4.1.) peut être suivi d'un post fixe séparé de lui par un point. Ce postfixe est un identificateur de champ(cf.paragraphe II.4.3.) qui devra être spécifié préalablement à son utilisation (par FIELD). L'identificateur ainsi constitué par cette postfixation permet de se référer à une partie d'un mot mémoire. Le langage LEX permet par ce biais un travail au niveau du bit.

De plus amples précisions seront données par la suite sur l'utilisation des champs(cf.paragraphe II.6.9.).

### II.2.3.d. Préfixation :

Un identificateur de variable simple ou indicée peut être préfixé par l'un des caractères spéciaux ⑆ ou ⑇ que nous désignerons par la suite par "adresseur" et "indirecteur". La concaténation à gauche de l'adresseur à un identificateur de variable permet de référencer l'adresse absolue de la variable alors que l'identificateur seul fait référence au contenu du mot mémoire associé. La concaténation à gauche de l'indirecteur à un identificateur de variable permet de faire référence au contenu du mot mémoire dont l'adresse est contenue dans la variable.

### exemples :

<figure><img src="image_2.png" /></figure>

SPROC12

TABLO(A*2/F)

### II.2.4. Les nombres :

Les seules valeurs numériques utilisées sont des valeurs entières précédées ou non d'un signe (+ ou -).

**Remarque** : La valeur doit être comprise dans les limites de la représentation interne ; par conséquent, cela dépend de la machine objet.
## II.3. Configuration d'un programme en LEX :

Un programme LEX est compris entre les directives .LEX et .ENDLEX et est constitué d'un programme principal terminé par END suivi éventuellement de définitions de procédures et de déclarations de programmes d'échanges.

Le tout étant constitué d'un ensemble de phrases terminées par un ; et suivies éventuellement d'un commentaire (chaîne de caractères entre quotes).

Programme principal et procédures sont constitués de déclarations, de spécifications et d'instructions que nous allons étudier ci-dessous.

On peut insérer du code assembleur dans un programme en LEX (embedding) : si la machine objet est un T2000 le code ASMAT sera écrit, dans son format, entre les directives .ASMAT et .ENDASMAT.

## II.4. Types de variables, syntaxe de leurs déclarations :

Chaque variable doit être déclarée avant d'être utilisée, toute déclaration comporte la spécification du type de variable. Toute déclaration peut être suivie d'un commentaire.

### II.4.1. Types de variables :

Au nombre de deux, ils spécifient soit une variable destinée à contenir des valeurs numériques (type WORD) soit destinée à contenir des chaînes de caractères (type CHAR). Chaque type peut également être utilisé pour spécifier un tableau ou un sous tableau.

### II.4.2. Déclarations :

Chaque variable déclarée peut être initialisée à la déclaration ;

#### II.4.2.1. Variable simple : a) syntaxe :

```
<déclaration de variable simple> ::= <type> <identification de variable>
[<identification de variable>];
{<commentaire>|}
```
<identification de variable>::=<identificateur de variable>
{=<constante>|}

<type>::= WORD | CHAR

<constante>::=<valeur numérique> | <chaîne>

<chaîne>::= '['<lettre> | <chiffre>']'

b) **exemples** : 
WORD VAR1;
CHAR VAR2,VAR;
WORD VAR4 = 1, VAR5,VAR6 = 25;
CHAR VAR7, PROG = 'ASMAT';

c) **remarques** : -plusieurs variables de même type peuvent être regroupées en une liste.
-il n'y a pas d'initialisation par défaut.

II.4.2.2. **Tableau** : a) **syntaxe** :

<déclaration de tableau>::=<dimension><type>ARRAY
<identification de tableau>
[,<identification de tableau>]; {<commentaire>|}

<dimension>::= <entier>

<identification de tableau>::= <nom de tableau> {=<constante>
[,<constante>]|}

<nom de tableau>::=<identificateur de variable>

b) **exemples** :

20 WORD ARRAY TABLO; déclaration d'un tableau de 20 éléments.

20 WORD ARRAY TABLO=1; même déclaration, mais initialisation de tous les éléments à la valeur 1.

5 WORD ARRAY TAB=0,2,4,6,8; chaque élément prend une valeur particulière.

5 CHAR ARRAY TAB2 = 'A','E','I','O','U';

10 CHAR ARRAY T1 = '4',T2,T3 = 'FIN'; déclaration de 3 tableaux de 10 éléments de type CHAR, 2 sont initialisés.
II.4.2.3. Sous-tableau : a) Syntaxe :

<déclaration de sous tableau> ::= <dimension> <type> SUBARRAY
<identification de sous-tableau> [, <identification de sous-tableau> ];
{<commentaire> |}

<identification de sous-tableau> ::= <nom de sous tableau> AT

<nom de tableau> (<valeur numérique>)
{=<constante> [, <constante> ] |}

<nom de sous-tableau> ::= <identificateur de variable>

b) exemple :

10 WORD SUBARRAY TABLOBIS AT TABLO(4)=9;

Qn déclare ici un sous-tableau extrait du tableau déclaré ou paragraphe II.4.2.2.
Tous les éléments de ce sous-tableau sont initialisés à 9.

c) Remarques :

- le tableau référencé devra avoir été obligatoirement déclaré.

- on doit avoir dimension (sous-tableau) <
  dimension (tableau)

et même

dimension (sous-tableau) + indice de tableau

dimension de tableau.

- il est possible par ce biais de changer le type d'une partie
de tableau.

- la syntaxe actuelle permet la déclaration suivante :

10 WORD SUBARRAY TAB1 AT TABLO(2), TAB2 AT TABLO(3)=2;

C'est à dire que des éléments pourraient être redéclarés avec des noms différents et des valeurs différentes ce qui implique la nécessité de manipuler ce genre d'élément avec beaucoup de précautions.

II.4.3. Déclaration de champs :

Comme nous l'avons vu au paragraphe II.2.3.c. une variable peut être post fixée
par un champ. Ce champ devra au préalable avoir été déclaré.

a) Syntaxe :

<déclaration de champ> ::= FIELD<identification de champ> [, <identification de champ>]
; {<commentaire> |}
<identification de champ>::=<nom de champ>(<premier bit>,<dernier bit>)
<nom de champ>::= <identificateur de variable>
<premier bit>::= <entier>
<dernier bit>::= <entier>

b) Exemple :

FIELD A(0,5),B(2,2),C(0,1);
FIELD F1(0,0);

c) Utilisation :

-un champ apparaît concatené à droite (par l'intermédiaire d'un point) à une variable simple ou indicée

-il devra, préalablement à son utilisation :

-être déclaré comme nous l'avons vu ci-dessus.

-être initialisé au moyen des opérateurs SET0 ou SET1.

## II.5. Les expressions arithmétiques en LEX :

### II.5.1. Présentation :

LEX permet toutes les manipulations classiques de valeurs (contenus de mots mémoire) mais étant destiné à l'écriture d'exécutifs, il permet également la manipulation de groupes de bits (FIELD), d'adresses (par `a`) et l'utilisation de l'indirection.

### II.5.2. Syntaxe :

<expression arithémtique>::= {+|-} <terme> [{+|-} <terme>]
<terme>::= <facteur> [{*|/} <facteur>]
<facteur>::= <valeur> | <valeur>. <nom de champ>
<valeur>::= <variable simple>
| <variable indicée>
| <varad>
| <varind>
| <entier>
| (<expression arithmétique>)
```
<variable simple>::= <identificateur de variable>
<variable indicée>::= {<nom de tableau> | <nom de sous-tableau>} <indice>
<indice>::= (<expression arithmétique>)
<varad>::=<adresseur>{<variable simple> | <variable indicée>}
<varind>::= <indirecteur>{<variable simple> | <variable indicée>}
<adresseur>::= a
<indirecteur>::= #
```

### II.5.3. Quelques remarques :

- les expressions arithmétiques en LEX sont des assemblages d'opérandes reliés par des opérateurs et des parenthèses.

- les opérateurs `+ - * /` sont dits "opérateurs dyadiques" mais `+` et `-` peuvent être utilisés comme "opérateurs monadiques" en tête d'expression.

- les opérandes intervenant peuvent-être :

- des expressions arithmétiques entre parenthèses.

- des (entiers) valeurs numériques.

- des variables simples.

- des variables indicées.

- des variables simples ou indicées postfixées par des champs.

- des variables simples ou indicées préfixées par l'adresseur ou l'indirecteur.

### Remarques sur l'adresseur et l'indirecteur :

- ils sont considérés comme des opérateurs monadiques :

- `a` : VI n'a aucun sens.

- `.` : pour des chaînes d'indirections il faudra donc introduire des variables intermédiaires.

- si l'indirecteur est appliqué à une variable indicée, l'indication intervient avant l'indirection ce qui permet la manipulation de tableaux de pointeurs.
## II.6. Les instructions de base :

### II.6.1. Étiquetage :

Toute instruction peut être étiquetée. Une étiquette est un identificateur quelconque suivi du séparateur : . Toute instruction peut être suivie d'un commentaire.

#### définition syntaxique :

```
<instruction> ::= {<étiquette>: |} {<instruction composée> |
<instruction simple>} ; {<commentaire>|}

<étiquette> ::= <identificateur de variable>

<commentaire> ::= '<chaîne de caractères>'

<chaîne de caractères> ::= [<lettre>|<chiffre>|<caractère spécial>]

<instruction composée> ::= BEGIN {<commentaire>|}

<instruction simple> [<instruction simple>] END

<instruction simple> ::= <affectation> |
<instruction conditionnelle> |
<boucle> |
<instruction choix> |
<instruction de branchement> |
<initialisation des champs> |
<instruction d'entrée/sortie> |
<instruction d'activation> |
<instruction de retour> |
<construction d'un paquet>
```

### II.6.2. Notion de bloc `BEGIN`, `END` :

Un bloc en LEX est une séquence d'instructions comprise entre les crochets `BEGIN` et `END`. On définit ainsi une instruction composée ce qui permet la clarification d'un texte. Il n'y a aucun rapprochement avec la structure de bloc d'ALGOL [7] adaptée, elle, à l'allocation dynamique de la mémoire.

### II.6.3. Instruction d'affectation :

#### Syntaxe :

```
<affectation> ::= <partie gauche> = <partie droite>

<partie gauche> ::= {<variable simple> | <variable indicée>}
```
<varind>} {.<nom de champ> |}
<partie droite>::= <expression arithmétique>

### Remarques :

.l'affectation se fait par l'intermédiaire du séparateur = .

.toute variable peut-être affectée d'une valeur sauf les variables précédées de l'adresseur .

.la valeur attribuée est celle d'une expression arithmétique (on remarquera que la syntaxe d'une expression est telle qu'elle peut se limiter à un nombre ou à une variable simple).

## II.6.4. Instruction conditionnelle :

### Syntaxe :

<instruction conditionnelle>::= IF <expression relationnelle>
    THEN <instruction> {ELSE <instruction>|}
    <expression relationnelle>::= <premier membre> <opérateur relationnel>
    <second membre>
    <premier membre>::= <expression arithmétique>
    <opérateur relationnel>::= <|< = |>=|> |># =
    <second membre>::= <expression arithmétique>

### Remarques :

.l'utilisation de `BEGIN` et `END` permet ici de clarifier le texte en délimitant les alternatives.

.il est possible d'imbriquer les instructions conditionnelles.

## II.6.5. Boucle :

### Syntaxe :

<boucle>::= {FOR<variable> FROM <expression 1> TO
    <expression 2> {BY <expression 3>|}
    |WHILE <expression relationnelle>}
    DO <instruction>

### Remarques :

.les expressions 1, 2 et 3 sont des expressions arithmétiques.
.le pas peut être ommis, l'option par défaut est 1.

**Exemples :**

FOR A FROM TABLOBIS (B*2)+1 TO
TABLOBIS (25) BY 3 DO B=B+1;
WHILE TABLO(ALPHA)<o DO BEGIN
    X(B) = $ALPHA;
    ALPHA = ALPHA+1;
END;

### II.6.6. Instruction choix :

**Syntaxe :**

`<instruction choix> ::= DO <expression arithmétique>`
`CASE OF <instruction simple> [OR<instruction simple>]`

**Remarque :**

.l'instruction exécutée sera celle de la liste a, ant pour rang la valeur de
l'expression arithmétique. Il faut donc que cette valeur soit inférieure ou
égale au nombre maximum d'instructions de la liste (numérotation à partir de 1).

**exemple :**

DO N CASE OF
A=25 OR
A=ALPHA+2 OR
A=TABLOBIS(B) OR
A=$B; Si N=4 sera exécutée

l'affectation A=$B.

### II.6.7. Instruction de branchement.

**Syntaxe :**

`<instruction de branchement> ::= GOTO <étiquette>`

### II.6.8. Instructions d'entrée/sortie : Ces instructions font l'objet d'un paragraphe spécial (cf. paragraphe.II.7.).

### II.6.9. Initialisation des champs :

**Syntaxe :**

`<initialisation de champ> ::= {SETO|SET1} (<nom de champ>)`
## Remarques :

un champ déclaré par `FIELD` et spécifié par deux numéros de positions binaires doit-être initialisé avant d'être utilisable.

cette initialisation se fait au moyen des "opérateurs" `SET0` et `SET1`.

si `SET0` (resp. `SET1`) est appliqué à un champ le mot mémoire correspondant aura :

- les bits compris entre les deux limites positionnés à 0 (resp. à 1) ainsi que les bits limites.

- les autres bits positionnés à 1 (resp. à 0).

II.6.10. Instructions d'activation : font l'objet d'un paragraphe

II.6.11. Instructions de retour : spécial (cf. paragraphe.II.8).

II.6.12. Construction d'un paquet : cf. paragraphe.II.8.4.

## II.7. Entrées Sorties :

### II.7.1. Introduction :

Les Entrés-Sorties font intervenir deux processeurs :

L'unité centrale et le canal. Dans les machines évoluées, les facilités hardware les placent tous deux au même niveau d'intervention vis à vis de la mémoire centrale.

L'unité centrale fait des transferts de mémoire centrale à registres. La commande des registres se fait automatiquement dans les instructions.

Le canal fait des transferts de mémoire centrale à mémoire périphérique. Cette dernière a un mécanisme d'adressage électromécanique ; il faut donc des ordres spécifiques pour la commander.

Enfin, il faut synchroniser les deux processeurs qui se déclenchent sur des procédures, s'interrompent et communiquent.
Nous aurons donc des instructions :

- de déclenchement du canal par l'UC.

- de test du canal par l'UC.

- d'acquittement du processus d'E/S, et des ordres exécutables par les coupleurs associés aux périphériques.

## II.7.2. Généralités :

Une procédure d'E/S peut-être décomposée en 5 phases.

utilisateur {
  1) réservation de Tampon, organisation de données.
  2) demande de transfert (au résident).

Système {
  3) répartition des demandes et initialisation du transfert.
  4) déroulement du transfert.
  5) fin de transfert et contrôle de validité.

Les points 1 et 2 sont à la charge de l'utilisateur (assisté des services du moniteur d'E/S).

Les trois derniers sont destinés au système ; nous allons examiner les instructions à mettre en oeuvre pour répondre à ces besoins.

### a) Configuration périphérique (phase 3) :

Les demandes d'E/S peuvent s'adresser à un canal ou directement au coupleur du périphérique. En effet les connexions peuvent se faire ou non par l'intermédiaire d'un canal.

En ce qui nous concerne, les ordres d'entrée-sortie auront plus de généralité puisque les organes non branchés sur un canal réel sont pris en compte par un canal simulé, le fonctionnement de ce dernier est tel que la différence n'apparaisse pas au système.
b) Modes de fonctionnement (phase 4) :

Il y en a quatre :

1. le mode programmé simple.

2. le mode programmé prioritaire.

3. le mode canal en mode H.

4. le mode canal en mode F.

Les deux premiers s'expriment avec des ordres de lecture et d'écriture directs.
En (1), l'unité centrale doit boucler sur un test du périphérique pour s'assurer
que le transfert a eu lieu ; en (2), c'est le coupleur du périphérique qui
prévient l'unité centrale au moyen d'une interruption.

Dans les deux derniers modes, l'unité centrale lance le canal et lui fait
effectuer le Transfert. Le canal remplace l'unité centrale et les coupleurs
dialoguent avec lui de la même façon. En mode H, l'unité centrale doit tester
l'état de l'E/S pour savoir si le Transfert est terminé. En mode F, le canal
fait une interruption pour signaler la fin du Transfert.

Le canal peut avoir deux accès à la mémoire. *L'accès par l'intermédiaire de l'unité centrale qui effectue le passage de l'information de ou vers la mémoire.

*L'accès direct grâce auquel

le canal peut lire ou écrire en mémoire sans utiliser les services de l'unité
centrale.

Ces deux distinctions n'apparaissent pas au niveau de la programmation.

Nous écrivons en LEX les E/S comme si tous les périphériques étaient connectés
en mode canal F. C'est la division de configuration qui permettra de prendre
en compte les particularités hardware.
### c) Traitement des interruptions (phase 5) :

La diversité du hardware selon les machines impose que l'on ait un jeu d'instructions capable de réaliser par software ce qui n'est pas fait automatiquement.

Le traitement des interruptions d'E/S comporte les étapes suivantes :

- empilement du contexte interrompu.

- acquittement de l'interruption.

- mise en place d'un nouveau contexte.

- traitement proprement dit (tests divers).

- retour à :

- la tâche interrompue.

- une autre tâche.

- traitement d'une autre interruption.

Nous disposerons d'instructions :

- d'acquittement (acknowledge).

- de test { périphérique.
  canal.

Il est à noter que la répartition des cinq étapes entre le hard et le soft varie d'une machine à l'autre.

### II.7.3. Instructions d'E/S :

#### a) Initialisation et activation : START :

Pour que l'opération puisse démarrer, il faut que l'on fournisse
au canal l'adresse d'une table où il trouvera les mots de commande :

- en 10020 on met cette adresse dans le registre canal.

- en 360, on la met en mémoire fixe (CAW).

- en Mitra 15 et T2000, elle va dans l'accumulateur.

La construction de cette table est hors de notre propos, il faudra
cependant en fournir l'adresse ; - 18 -
étant donnée la diversité des architectures, nous la placerons dans l'instruction
START ; les instructions efficaces seront obtenues au stade de la paramétrisation.

Nous distinguerons deux canaux : le canal réel et le canal simulé ;
cette distinction sera faite par la division de configuration. Dans le premier
cas, les instructions générées comporteront un ordre START, dans le second,
ce sera un branchement vers le simulateur [13].

## Description syntaxique :

`<lancement d'E/S>:: = START ( <numérocanal>, <A périphérique>, <A procédure d'E/S> )`

`<numéro canal>:: = <entier>`

`<A périphérique>:: = <entier>`

`<A procédure d'E/S>:: = <identificateur>`

Le START est l'analogue du CALL d'une procédure.

Dans le START, on spécifie l'adresse du processeur ; elle est
implicite dans le CALL.

De plus, on fournit l'adresse du corps de la procédure ; dans le
CALL, elle est reconnue à la compilation (pas à l'exécution).

Enfin, par la procédure, on passe l'adresse des paramètres.

Pour le CALL, la table est construite à la compilation et non
pas comme ici à l'exécution.

## b) Acquittement : ACKNOWLEDGE :

l'instruction ACKNOWLEDGE sert à :

-faire retomber le niveau d'interruption (prise en compte).

-identifier la source de l'interruption (n°périphérique).

-identifier la cause de l'interruption par acquisition du mot d'état.

Elle ne comporte pas de paramètres.
ACKNOWLEDGE est à rapprocher de RETURN.

Cependant, ce n'est pas elle qui fait le retour effectif ; c'est l'interruption
qui fait reprendre le contrôle au moniteur d'entrée-sortie.

instructions de test { TESTDEVICE.
TESTCHANNEL.

TESTDEVICE : sert à obtenir le mot d'état du périphérique. On peut distinguer
en principe 4 états fondamentaux pour un organe périphérique :

-READY : prêt à accepter un START.

-N.O. (not operational ) : hors service.

-BUSY : en cours de travail.

-N.A. (not available) : en attente d'acquittement.

Le mot d'état sera considéré en LEX comme placé à un endroit
réservé à cet effet après les instructions START, TESTDEVICE, TESTCHANNEL, HALT.

La réalisation effective en est à la charge de la paramétrisation.

Des informations plus précises seront fournies ; on les exploitera avec les
facilités du FIELD.

<test du périphérique>:: = TESTDEVICE ( <numéro canal>,
<numéro device>)

<numéro canal>:: = <entier>

<numéro device>:: = <entier>

TESTCHANNEL : récupère le mot d'état du canal. Les remarques sont les mêmes
que pour TESDEVICE.

<test du canal>:: = TESTCHANNEL ( <numéro canal> )
Instruction d'arrêt HALT :

Stoppe l'activité de la voie de liaison activée, on reçoit le mot d'état du
canal et du périphérique.

II.7.4. Ordres d'E/S :

On peut classer les périphériques par le nombre de degrés de liberté que possède
le mécanisme d'accès :

-2 degrés et plus : Drum-Like :

disques à têtes mobiles ou fixes.

-1 degré : Tape-Like :

bandes magnétiques, imprimantes, lecteurs de cartes.

-0 degré : pas de positionnement, adressage ponctuel :

panneau de contrôle, TTY.

Il y a deux types d'ordres de positionnement par contre, il n'y a
qu'un type d'ordre de transfert.

II.7.4.1. Ordres de positionnement :

A-coordonnées à fournir :

-un disque a deux degrés de liberté.

On accède à l'enregistrement en coordonnées polaires : module et argument/
cylindre et secteur.

S'il s'agit d'un ensemble de disques superposés nous devrons spécifier
le numéro de la tête de lecture.

-un tambour est adressable en coordonnées cylindriques : côte et argument/nº de
tête et secteur.
-un dérouleur de bande n'a qu'un degré de liberté ; on lui indique donc le numéro de l'enregistrement à lire ou à écrire ; il peut parcourir la bande dans les deux sens ; c'est le seul appareil à un degré de liberté capable de le faire.

Le tableau de la page 23 résume la classification des appareils.
CLASSIFICATION DES APPAREILS D'E/S ET DE LEURS COMMANDES.

<table><thead><tr><th>Ordres de Transmission</th><th>(READ ou WRITE) ou</th><th>(READ et WRITE)</th><th>READ DIRECT WRITE DIRECT } pour l'UC.</th></tr></thead><tbody><tr><td>Types d'adressage (positionnement)</td><td>DRUM LIKE</td><td>TAPE LIKE<br>Incremental saut de blocs<br>Δ<o> Δ>o</td><td>PONCTUEL</td></tr><tr><td>Exemples</td><td>E À I</td><td>Bande magnetique<br>ARRIÈRE</td><td>Panneau de contrôle</td></tr><tr><td>Ordres de positionnement</td><td>SEARCH (lecteur)<br>SEEK (cylindre)</td><td>REWIND<br>absolu ou<br>incremental<br>JUMP ou<br>SKIP</td><td>SKIP<br>READ foreward<br>( instruction W, D, ou<br>+ inhibition de lecture)</td></tr></tbody></table>

<figure><img src="image_3.png" /></figure>

<figure><img src="image_4.png" /></figure>

<figure><img src="image_5.png" /></figure>
B-Niveau de généralité des ordres :

Les coupleurs différent tous les uns des autres en ce qui concerne
les ordres qu'ils sont capables de recevoir et d'exécuter.

Nous allons donc considérer un coupleur type capable :
-de positionner le mécanisme d'accès à un endroit voulu (coordonnées).

-de transmettre au canal le bloc lu à cet endroit (ou transmission en sens inverse).

De plus, pour l'instant, le contrôle sera rendu à l'unité centrale
à la fin de la transmission de chaque bloc.

Tout test sur les données est supposé à la charge de l'unité
centrale ; on considère que la voie de liaison n'est pas capable de faire des
test en "stand alone".

Le schéma de l'opération-type d'E/S sera :
-START (pour l'unité centrale)

-Ordre d'E/S : positionnement.

-Ordre d'E/S : transfert.

-retour à l'unité centrale : ACKNOWLEDGE et à la tâche la plus urgente qui ne sera pas nécessairement celle qui vient d'effectuer l'échange.

C'est à la phase de paramétrisation que les ordres exécutables seront
obtenus.

Ainsi, si on specifie un saut de N blocs sur un dérouleur incrémentable par 1, la séquence générée sera faite de N sauts de 1 bloc.

*Pour positionner les mécanismes à deux ou trois degrés de liberté,
nous écrivons

<positionnement 2,3> ::= POSITION ( {<numéro cylindre>,|}

<numéro tête>, <adresse enregistrement> <lien> )

<numéro cylindre> ::= CYL = <entier>

<numéro tête> ::= HEAD = <entier>

<adresse enregistrement> ::= REC = <entier>
*Pour les périphériques à 1 degré de liberté, nous avons

-un ordre pour sauter N blocs ou mettre le sticker fin de bande sous la tête.

<positionnement 1AV>::= SKIP ( {<numéro bloc>|<endfile>} <lien>)

<numéro bloc>::= <entier>

<endfile>::= ENDFILE

-un ordre pour sauter N blocs en arrière ou mettre le sticker début de bande sous la tête.

<positionnement 1AR>::= REWIND ( {<numéro bloc>|<begfile>} <lien>)

<begfile>::= BEGFILE

## II.7.4.2. Ordres de Transmission :

Tous les appareils sont supposés transférer 1 bloc ; et le canal a besoin d'en connaître la longueur. De plus, il faut préciser l'adresse du Tampon utilisé.

### A * De Mémoire centrale à périphérique :

<écriture>::= WRITE ( < tampon> , <longueur de bloc> <lien>)

< tampon> ::= <identificateur>

<longueur de bloc>::= <entier>

*De périphérique à Mémoire centrale :

<lecture>::= READ ( < tampon> , <longueur de bloc> <lien>)

Les labels Fin de Fichier seront standards pour un appareil déterminé; nous introduirons pour plus de facilité un ordre qui permet d'écrire directement ce label sans avoir à en spécifier la forme. Cet ordre peut être réalisé par écriture ordinaire ou directement par le hardware du coupleur.

<écriture fin de fichier>::= WRITEOF
B * De l'accumulateur au périphérique et inversement : adressage ponctuel

Pour les appareils à adressage ponctuel, il n'y a pas de position-
nement ; nous n'aurons que les ordres d'E/S directs, c'est à dire un transfert
d'information de l'accumulateur au périphérique et inversement.

La longueur de l'enregistrement est constante.

`<lecture directe>::= READDIRECT ( < addressed > <lien>)`

`<écriture directe>::=WRITEDIRECT (< addressed > <lien>)`

`< addressed > ::= <identificateur> | <entier>`

II.7.4.3. Améliorations à apporter :

Le canal surveillé permettra de simuler le chaînage des commandes et des données et l'enchaînement de tables de travail situées dans des endroits quelconques de la mémoire centrale.

On specifiera le chaînage des ordres d'E/S en LEX. Chaque ordre est susceptible d'être chaîné au suivant.

Nous écrivons donc :

`<lien>::= { , {<chaînage> | <concatenation>} | }`

`<chaînage>::= CC|DC`

`<concatenation>::= CCDC`

CC signifie Command Chaining.

DC signifie Data Chaining.

Quelles que soient les possibilités du hardware, le programmeur
a la possibilité d'écrire les chaînages ; ceux ci ne seront effectifs que si la
Division d'environnement les déclare licites.
## II.8. Primitives, procédures, échanges :

LEX permet la description et l'activation de trois catégories de sous programmes se distinguant par des buts différents (ils sont destinés à la description d'actions différentes) :

- les primitives.

- les procédures.

- les échanges.

La première catégorie semble la plus intéressante au niveau LEX étant spécialement adaptée à la description d'actions-système.

### II.8.1. Primitive :

C'est une action du système exécutable indépendamment comme un mécanisme hardware et en relation bijective avec les commandes opérateur.

On distingue trois types de primitives :

- primitive non interruptible.

- primitive basée (interruptible) dont le degré de réentrance est standard.

- primitive basée dont le degré de réentrance est fixé par le programmeur.

Le "basage" assure la réentrance des primitives interruptibles.

### Remarques sur la compilation des primitives basées :

Si n est le degré de réentrance, le compilateur réservera n mots mémoire pour la sauvegarde des adresses de retour correspondant aux différentes activations de la primitive basée, ainsi que n mots pour chaque variable simple et chaque élément de tableau. A chaque activation interrompue correspond une valeur d'index qui permettra de repérer exactement les données nécessaires à la réactivation et l'adresse de retour adéquate. Donc toute opération faisant référence à des données locales à la primitive sera indexée par BERGSON.

Une primitive doit-être définie préalablement à son activation. Cette définition se fait dans une *section déclarative* (cf. paragraphe II.9) qui comprend soit une seule primitive soit des primitives partageant du code.
## Syntaxe de la définition de primitive :

```
<définition de primitive>::= <entête de primitive>
    [<déclaration de variable>] [<spécification d'external>]
    <corps de primitive> <spécification de communes>
    ENDPRIMITIVE;

<entête de primitive>::= PRIMITIVE {BASED {<degré de réentrance>
    |} |} <nom de primitive> ; {<commentaire> |}

<déclaration de variable>::= <déclaration de variable simple>|  
    <déclaration de tableau>|  
    <déclaration de sous tableau>|  
    <déclaration de champ>

<spécification d'external>::= EXTERNAL <liste de variables>
    ; { <commentaire> |}

<spécification de communes>::= COMMUNES :  
    [<nom de variable>: {<liste de primitives>|<liste de sections>} ;  
        <commentaire>|}]  

<liste de primitives>::= <nom de primitive> [,<nom de primitive>]

<liste de sections>::= <nom de section> [,<nom de section>]

<degré de réentrance>::= <entier>

<corps de primitive>::= <instruction> [<instruction>]

<nom de primitive>::= <identificateur de variable>
```

Les données référencables dans une primitive sont les données locales (déclarées en tête de primitive), les données "external" (spécifiées en tête de primitive) et les données locales au module englobant (cf. paragraphe II.9). **activation**: une primitive est activable par nom. Le mot-clé JUMP est utilisé pour faciliter la compilation qui consiste en un branchement avec éventuellement passage implicite de paramètres.
### Syntaxe de l'activation :

`<activation de primitive>::= JUMP <nom de primitive>`

## II.8.2. Procédure :

C'est un sous-programme structuré en bloc dont le nom est paramétré et dont les paramètres sont passés par nom.

Une procédure est soit résidente soit non résidente, dans le premier cas elle doit être obligatoirement réentrante c'est à dire utilisable par plus d'un appelant à la fois.

Une procédure est définie en fin de module après la spécification d'interface (cf. paragraphe II.9).

### Syntaxe de la définition de procédure :

```
<définition de procédure>::= <entête de procédure>
                           [<déclaration de variable>]
                           <instruction> [<instruction>]
                           END;

<entête de procédure>::= {RESIDENT {REENTRANT|}}
                          | REENTRANT {RESIDENT|}}

PROCEDURE <nom de procédure>
    (<liste de paramètres formels>);

{<commentaire>|} [<spécification de paramètres formels>]

<nom de procédure>::= <identificateur de variable>

<liste de paramètres formels>::= <identificateur de variable>
                                 [<<identificateur de variable>]

<spécification de paramètres formels>::= {<dimension>|}

<type> <liste de paramètres formels>;

{<commentaire>|}
```
### Remarques :

* Lorsqu'une procédure est déclarée `REENTRANT PROCEDURE` la résidence est implicite.

* Les procédures résidentes sont déclarées telles dans la DIVISION d'Environnement. Les procédures non résidentes ne sont pas réen-trantes.

* Chaque paramètre formel doit être spécifié.

### Activation et retour :

L'activation se fait par `CALL`. A ce niveau le compilateur assure la création de zones de données pour le passage des paramètres (sont transmises à l'appelée les adresses des paramètres effectifs). Le retour dans l'appelant se fait par l'instruction `RETURN`.

```
<activation de procédure>::= CALL <nom de procédure>
                                ( <liste de paramètres effectifs>)
<liste de paramètres effectifs>::= <paramètre effectif>
                                     [ ,<paramètre effectif> ]
<paramètre effectif>::= <identificateur de variable> |
                          <valeur numérique>
<retour>::= RETURN
```

### II.8.3. Echanges : [14].

L'utilisateur organise ses échanges en :

- Demandes d'échange.

- Paquets d'échange formés de demandes d'échanges exécutables dans n'importe quel ordre.

- Programme distribué d'échange (PDE) formé de paquets d'échange séquentiels.

Les demandes d'échange sont fournies et remplies par la primitive `"METS DANS"` et les paramètres qu'on lui passe. On ne réserve donc pas de place pour les demandes d'échange. Il faut cependant déclarer les programmes distribués d'échange et les paquets d'échange.
*<déclaration de programme d'échange> ::= PROGECH

<nom de programme d'E/S> : <nom de paquet> [,<nom de paquet>] PUIS <action>

<nom de programme d'E/S>::= <identificateur de variable>

<nom de paquet>::= <identificateur de variable>

<action>::= <nom de primitive>

*<déclaration de paquet>::= PAQUET <nom de paquet>

Ces déclarations sont faites pour utiliser les facilités de traitement des échanges offertes par SPECTRE. Elles font donc partie des décrets, ainsi que les primitives qui permettent de les manipuler.

*Activation d'un PDE.

permet d'envoyer à HORDEX le PDE pour lancer effectivement les opérations.

<activation d'un PDE>::= LANCE <nom de programme d'E/S>

*Construction d'un paquet d'échange :

<construction d'un paquet>::= METS <definition de Demech> DANS <nom du Paquet>

<définition de Demech>::= ENTREE|SORTIE (<liste de paramètres>)

<liste de paramètres>::= <idparm>=<paref> [,<idparm>=<paref>]

<idparm>::= PERIPH|MC|ADP|MA|LG|URG

<paref>::= <typeriph> | <identificateur> | <entier>

<typeriph>::= TTY1|TTY2|LR|PR|DB|D|VISU

1. Il n'y a aucun ordre dans la liste des paramètres.

2. Un programme d'échange et les paquets le constituant sont déclarés au niveau d'un module et ne peuvent pas faire partie d'interfaces.

**Remarque** : pour faire le lien avec les définitions syntaxiques du paragraphe II.6.1. on a :

<instruction d'activation>::= <activation de primitive>|<activation de procédure>|<activation d'un PDE>

<instruction de retour>::= <retour>
## II.9. Le sectionnement dans LEX :

Le sectionnement introduit dans LEX a un double but :

### II.9.1. Faciliter l'élaboration de la maquette BERGSON-ASMAT :

La réalisation de cette maquette nécessite l'utilisation au maximum des aides à la programmation fournis avec le T2000. La maquette a pour but d'obtenir un texte symbolique accepté par l'assemblée ASMAT, à partir de programmes écrits en LEX décrivant chacun une partie de système. On trouve donc dans LEX des directives d'assemblage qui se répercutent, dans la chaîne de traduction automatique, au niveau ASSIRIA (A) puis au niveau ASMAT. Ces extensions ne seront probablement pas retenues pour la chaîne de traduction définitive (comprenant le TIGRE).

La chaîne d'assemblage T2000 ne conçoit que deux niveaux : un identificateur est soit :

-local dans la section dans laquelle il est déclaré donc réutilisable sans confusion dans les autres sections.

-global, il est alors connu de toutes les sections (il est local au programme englobant les sections) et il peut alors entrer en conflit avec un synonyme local à une section.

**Remarque** : un identificateur est ici soit un identificateur de variable, soit une étiquette,

On a donc : **-un premier sectionnement** :

programme principal partagé en sections délimitées chacune par les directives SECTION et ENDSECTION.

**-une première partition des données** :

données locales au niveau des sections et données globales ( locales au programme principal).
Ce sectionnement trouve sa justification d'une part dans l'emploi de l'assemblée
ASMAT d'autre part dans la limitation des tables de BERGSON obligeant :

- soit une limitation du nombre d'identificateurs employés.

- soit une compilation section par section ou groupe de sections
par groupe de sections.

II.9.2. Faciliter la description d'un système modulaire :

En permettant la mise à jour et l'utilisation rationnelle de la *division d'environnement*.

Un système, comme SPECTRE, peut-être élaboré en 3 étapes [8]

[9] :

1. *Spécification des modules* :

entités fonctionnelles distinctes formalisant les mécanismes de base souhaités
dans le système. Chaque module peut être considéré comme une machine abstraite
opérant sur une base de données par le moyen d'actions élémentaires.

Ces actions sont décrites en LEX et correspondent à des instructions de base,
des activations de primitives ou des appels de procédures.

Les primitives d'un module peuvent être indépendantes ou chaînées. Dans ce
dernier cas elles font partie d'un *cheminement intramodulaire* descriptible en
LEX sous forme d'une autre primitive ou sous forme de procédure.

2. Spécification des interfaces :

qui sont les mécanismes de coordination entre modules constitués de données,
primitives et cheminements intramodulaire.

3. Spécification des cheminements intermodulaires :

mécanismes coordonnant les mécanismes de base des modules.

Le langage LEX, nous l'avons vu, permet la description et l'utilisation de primitives et de procédures. Il doit également permettre la description la plus précise du système c'est à dire celle des modules et interfaces. Ce qui justifie un sectionnement particulier.
Un programme LEX comprend donc la description d'un ou de plusieurs modules, chaque module étant explicité entre les directives MODULE et ENDMODULE. A la fin de chaque module est spécifiée une zone d'interface par la pseudo INTERFACE : dans cette zone sont spécifiées les données (variables, étiquettes, primitives) auxquelles ont droit d'autres modules.

## Définition syntaxique :

`<programme principal>::= <spécification de module>`

`[<spécification de module>]`

`END; {<commentaire>|}`

`<spécification de module>::= MODULE <nom de module>;`

`{<commentaire>|}`

`[<déclaration de locales>]`

`[<rappels d'external>]`

`<corps de module>`

`<spécification d'interface>`

`[<définition de procédure>]`

`[<déclaration de programme d'échange>]`

`ENDMODULE <nom de module>;`

`<nom de procédure>::= <identificateur de variable>`

`<déclaration de locales>::= <déclaration de variables>`

`<rappels d'external>::= EXTERNAL <identificateur de variable>`

`[<identificateur de variable>];`

`{<commentaire>|}`

`<spécification d'interface>::= INTERFACE :`

`[<identificateur de variable>|`

`<nom de primitive>|`

`<étiquette>} : <liste de modules>`

`;]`

`<liste de modules>::= <nom de module> [,<nom de module>]`
## Remarques sur les déclarations et spécifications de données.

- sont déclarées en tête de module les données accessibles partout dans le module.

- sont spécifiées en EXTERNAL des données déclarées dans d'autres modules et auxquelles le module en cours de description a droit. Autrement dit ces données devront avoir été spécifiées dans les zones d'interface de leurs modules de définition.

- par conséquent après les déclarations aussi bien les données locales que celles rappelées en EXTERNAL sont référencables partout dans le module.

**notion de section** : cette notion est intimement liée aux notions de primitive et de cheminement.

On distingue deux types de sections :

- section déclarative

- section d'activation

se caractérisant par leurs fonctions différentes.

a) **section déclarative** : Il s'agit d'une section dans laquelle est déclarée et spécifiée une primitive du module. Les données locales à la primitive (resp. globales) sont alors locales à la section (resp. globales).

**communication entre sections** :

certaines primitives peuvent avoir des données communes mais non accessibles pour les autres primitives. Ces données seront spécifiées comme COMMUNES dans la primitive où elles sont déclarées et rappelées en EXTERNAL dans les primitives y ayant droit. Il est à remarquer que l'on pourrait ici remplacer primitive par section puisque la première constitue essentiellement la seconde.

Des primitives partageant du code seront placées dans une même section, les données communes aux primitives de la section sont abrs locales à la section et les spécifications de COMMUNES (à plusieurs primitives de sections différentes) choisies parmi les locales s'effectuent au niveau de la section.
**avantages de la notion de section** : les problèmes posés par les primitives basées et les variables temporaires sont résolus car la section, pouvant constituer un "incrément" d'assemblage, les données locales ou du moins leurs identificateurs peuvent être utilisés ailleurs sans problème.

b) **section d'activation** : les primitives déclarées dans un module peuvent être activées seules ou être chaînées. Leurs activations constituent avec d'autres instructions et appels de procédures des cheminements intramodulaires descriptibles au niveau des sections d'activation. Ceci revient en fait à la description d'un chemin intramodulaire par une autre primitive. Les chemins intermodulaires sont décrits également au niveau d'une section, ils font intervenir eux des données externes au module en cours de définition.

On remarque donc que la section est en fait un point d'entrée à l'intérieur d'un module.

**Syntaxe de la définition de corps de module** :

<corps de module>::= [<section déclarative>]

<section d'activation>

[<section d'activation>]

<section déclarative>::= SECTION <nom de section>;

{<commentaire>|}

[<déclaration de locales>]

[<rappels d'external>]

<définition de primitive> [<définition de primitive>]

[<spécification de COMMUNES>] ENDSECTION ;

<section d'activation>::= SECTION <nom de section>;

{<commentaire>|}

[<déclaration de locales>]

[<rappels d'external>]

[<instruction>]</
[<spécification de communes>]

ENDSECTION ;

<nom de section>::= <identificateur de variable>

<spécification de communes> ::= COMMUNES :

[<nom de variable> : {<liste de sections>|<liste de primitives>}; {<commentaire>|}]

<liste de sections>::= <nom de section> [,<nom de section> ]

<liste de primitives>::= <nom de primitive> [,<nom de primitive> ]

Le sectionnement introduit en LEX entraîne une "hiérarchie" entre les données dont les portées sont différentes. Le tableau suivant prend en compte tous les types de données référencables dans une entité (module, section, primitive, en précise la déclaration, la spécification et la portée.
<table><thead><tr><th>MODULE</th><th> locales</th><th> en tête de module</th><th> le module entier</th></tr></thead><tbody><tr><td></td><td> intramodulaires</td><td> en tête de module comme locales ou locales aux sections</td><td> en fin de module dans la zone INTERFACE</td></tr><tr><td></td><td> externes</td><td> dans d'autres modules</td><td> en tête de module en EXTERNAL</td></tr><tr><td rowspan="3"> SECTION</td><td> locales à une section d'activation</td><td> en tête de section</td><td> le module entier + les modules de définition</td></tr><tr><td> communes aux primitives de la section déclarative</td><td> en tête de section</td><td> la section</td></tr><tr><td> communes à plusieurs sections</td><td> en tête de section (ou de primitive s'il s'agit seulement de sections déclaratives comprenant chacune une seule primitive)</td><td> spécifiées en fin de section (de primitive) dans la zone COMMUNES.</td></tr><tr><td></td><td> externes</td><td> dans d'autres sections</td><td> en tête de section en EXTERNAL</td></tr><tr><td></td><td> globales</td><td> en tête de module englobant (en locales ou en external)</td><td> la section + les sections de définition</td></tr></tbody></table>
<table><thead><tr><th>Section</th><th>type de données</th><th>déclarées</th><th>spécifiées</th><th>Portée</th></tr></thead><tbody><tr><td rowspan="5">PRIMITIVE</td><td> locales</td><td> en tête de primitive</td><td></td><td> la primitive</td></tr><tr><td> partageables entre primitives d'une même section</td><td> en tête de section</td><td></td><td> les primitives (la section)</td></tr><tr><td> communes à plusieurs primitives</td><td> entête de primitive</td><td> enfin de primitive dans la zone COMMUNE</td><td> les primitives y ayant droit</td></tr><tr><td> externes</td><td> dans d'autres primitives</td><td> entête de primitive en external</td><td> les primitives y ayant droit</td></tr><tr><td> globale</td><td> entête de module (en locales)ou en external</td><td></td><td> le module donc les sections donc les primitives.</td></tr></tbody></table>
III. ANNEXES :

<figure><img src="image_6.png" /></figure>

III.1. Annexe 1 : Liste des caractères spéciaux.

+
- }
*
/

<
=
>
#

:.
;
:
"
=

{
  constituent les opérateurs arithmétiques.

{
  permettent la constitution des opérateurs relationnels

 suivants : < <= == >= > # =

{
  ensemble des séparateurs.

}

caractère blanc

(
  parenthèses
)

@
  adresseur

$
  indirecteur.
III.2. Annexe 2 : Liste des mots clés.

On distingue plusieurs types de mots clés :

- les mots de séquencement.

- les déclarateurs.

- les spécifieurs.

- les crochets.

- les opérateurs.

a) mots clés de séquencement :

GOTO

IF

THEN

ELSE

FOR

FROM

TO

BY OR

WHILE

CASE

OF

DO

b) déclarateurs :

WORD MODULE

CHAR SECTION

ARRAY PROGECH

SUBARRAY PUIS
AT PAQUET

FIELD

PROCEDURE

PRIMITIVE

c) specifiers :

<table><tr><td>INTERFACE</td><td>CC</td><td>HEAD</td><td>ADP</td></tr><tr><td>COMMUNES</td><td>DC</td><td>REC</td><td>MA</td></tr><tr><td>EXTERNAL</td><td>CCDC</td><td>ENDFILE</td><td>LG</td></tr><tr><td>RESIDENT</td><td>ENTREE</td><td>BEGFILE</td><td>URG</td></tr><tr><td>REENTRANT</td><td>SORTIE</td><td>PERIPH</td><td></td></tr><tr><td>BASED</td><td>CYL</td><td>MC</td><td></td></tr></table>

d) crochets :

BEGIN .ASMAT
END .ENDASMAT

.LEX

.ENDLEX

ENDSECTION

ENDMODULE

ENDPRIMITIVE

e) opérateurs :

<table><tr><td>CALL</td><td>POSITION</td></tr><tr><td>JUMP</td><td>SKIP</td></tr><tr><td>RETURN</td><td>REWIND</td></tr><tr><td>SETØ</td><td>WRITE</td></tr><tr><td>SET1</td><td>READ</td></tr><tr><td>START</td><td>WRITEOF</td></tr><tr><td>ACKNOWLEDGE</td><td>READDIRECT</td></tr></table>
TESTDEVICE WRITEDIRECT

TESTCHANNEL METS

HALT DANS

### III.3. Annexe 3 : Définition syntaxique en META-5.

SYNTAX = '.LEX' COMMENT PROGRAM '.ENDLEX' TER;

COMMENT = $(.STRING);

TER = ';' COMMENT;

PROGRAM = 1$ (MODULSPEC) 'END' TER;

MODULSPEC = 'MODULE' MODULNAME TER;

$DECLARATION $REXTERN

MODULBODY INTERSPEC

$(PROCEDURDEFN) $(ECHANGE)

'ENDMODULE' MODULNAME TER;

MODULNAME = .ID;

DECLARATION = (ITEMDEFN/ARRAYDEFN/SUBARRAYDEFN/FIELDDEFN);

ITEMDEFN = TYPE ILEMENTRY $(','ILEMENTRY) TER;

ILEMENTRY = ITEMNAME ('='CONSTANT)/;

TYPE = 'WORD'/'CHAR';

ITEMNAME = .ID;

CONSTANT = INTEGER/STRING;

INTEGER = .NUM;

STRING = .STRING;

ARRAYDEFN = DIM TYPE 'ARRAY' ARRAYENTRY

$(',' ARRAYENTRY) TER;
DIM = INTEGER;

ARRAYENTRY = ARRAYNAME ('=' LISTCONSTANT/);

ARRAYNAME = .ID;

LISTCONSTANT = CONSTANT $(',' CONSTANT);

SUBARRAYDEFN = DIM TYPE 'SUBARRAY' SUBARRAYENTRY
               $(',' SUBARRAYENTRY) TER;

SUBARRAYENTRY = SUBARRAYNAME 'AT' ARRAYNAME
               '('INTEGER')' ('='LISTCONSTANT/);

SUBARRAYNAME = .ID;

FIELDEFN = 'FIELD' FIELDENTRY $(',' FIELDENTRY) TER;

FIELDENTRY = FIELDNAME '(FIRSTBIT', 'LASTBIT')';

FIELDNAME = .ID;

FIRSTBIT = INTEGER;

LASTBIT = INTEGER;

REXTERN = 'EXTERNAL' VARNAME $(',' VARNAME) TER;

VARNAME = ITEMNAME/ARRAYNAME/SUBARRAYNAME;

MODULBODY = $DECLARESECTION
           1$ACTIVSECTION;

DECLARESECTION = 'SECTION' SECTIONNAME TER
               $DECLARATION $REXTERN
               1$PRIMITIVDEFN
               (SPECOMMUNES/) 'ENDSECTION' TER;

PRIMITIVDEFN = 'PRIMITIVE'
               ('BASED' ('('DEGREE')')/)
               PRIMITIVENAME
               $DECLARATION $REXTERN
               1$STATEMENT (SPECOMMUNES/)
               'ENDPRIMITIVDEFN';
PRIMITIVENAME = .ID;

DEGREE = .NUM;

SECTIONNAME = .ID;

SPECOMMUNES = 'COMMUNES' ':'
             $ (VARNAME : LISTNAME TER);

LISTNAME = NAME $ (',' NAME);

NAME = PRIMITIVENAME / SECTIONNAME;

LISTPRIM = PRIMITIVENAME $ (',' PRIMITIVENAME);

ACTIVSECTION = 'SECTION' SECTIONNAME TER

$DECLARATION $REXTERN
1 $STATEMENT SPECOMMUNES
'ENDSECTION' TER;

STATEMENT = LABEL ( 'BEGIN' 1 $SIMPLESTATEMENT 'END' / SIMPLESTATEMENT);

LABEL = (LABELNAME ':' /);

LABELNAME = .ID;

SIMPLESTATEMENT = ASSIGNEMENT/
               IF/
               FOR/
               CASEOF/
               GOTO/
               IOSTATEMENTS / IOCOMMANDS /
               PROCEDURECALL /
               PRIMITIVACTIV /
               RETURN / CREECH /
               ACTIVECH /
               INITIALIZEFIELD;

ASSIGNEMENT = LEFTPART '=' RIGHTPART TER;

LEFTPART = ITEMNAME / INDVAR / VARIND;
INDVAR = (ARRAYNAME/SUBARRAYNAME) '(' 'EXPRESSION' ')';

RIGHTPART = EXPRESSION;

EXPRESSION = ('+'/'-' ) TERM $ ( ('+'/'-' ) TERM);

TERM = FACTOR $(( '*'/'/' ) FACTOR);

FACTOR = VAR/VAR'.' FIELDNAME;

VAR = ITEMNAME/INDVAR/VARAD/VARIND/INTEGER

/('EXPRESSION')';

VARAD = ADRESSEUR (ITEMNAME/INDVAR);

VARIND = INDIRECTEUR (ITEMNAME/INDVAR);

ADRESSEUR = 'a';

INDIRECTEUR = '$';

IF = 'IF' RELATIONALEXPR 'THEN' STATEMENT

('ELSE' STATEMENT/) TER;

RELATIONALEXPR = EXPRESSION RELATIONALOP EXPRESSION;

RELATIONALOP = '<'/'<='/'='/'>=/'>'/'=#=';

FOR = ('FOR' LEFTPART 'FROM' EXPRESSION 'TO'

EXPRESSION ('BY' EXPRESSION/)

/ 'WHILE' RELATIONALEXPR ) 'DO' STATEMENT TER;

CASEOF = 'DO' (INTEGER/VARNAME) 'CASE''OF'

SIMPLESTATEMENT $('OR' SIMPLESTATEMENT)

TER;

GOTO = 'GOTO' LABELNAME TER;

IOSTATEMENTS = START/ACKNOWLEDGE /TESTDEVICE/

TESTCHANNEL/HALT;

START = 'START' '(' NCHANNEL ',' ADPERIPH ',' ADTABLE ')'; TER;

NCHANNEL = INTEGER;

ADPERIPH = INTEGER;

ADTABLE = INTEGER;

ACKNOWLEDGE = 'ACKNOWLEDGE' TER;
TESTDEVICE = 'TESTDEVICE' ' ('NCHANNEL NDEVICE')' TER;

NDEVICE = INTEGER;

TESTCHANNEL = 'TESTCHANNEL' ' ('NCHANNEL')'
TER;

HALT = 'HALT' ' ('NCHANNEL', ' NPERIPH')' TER;

IOCOMMANDS = POSITION23/POSITON1AV/POSITION1AR/
ENDFILE/BEGFILE/WRITE/READ/WRITEOF/

RD/WD;

POSITION23 = 'POSITION' '('(NUMEROCYL',')/) NUMEROTET ','
ADRENREG LINK')' TER;

NUMEROCYL = 'CYL' '=' INTEGER;

NUMEROTET = 'HEAD' '=' INTEGER;

ADRENREG = 'REC' '=' INTEGER;

POSITION1AV = 'SKIP' '('(NUMEROBLOC/ENDFILE)LINK')' TER;

NUMEROBLOC = INTEGER;

ENDFILE = 'ENDFILE';

POSITION1AR = 'REWIND' '('(NUMEROBLOC/BEGFILE)LINK')' TER;

BEGFILE = 'BEGFILE';

WRITE = 'WRITE' '('ADTAMPON', ' BLOCLENGTH LINK')' TER;

ADTAMPON = IDENTIFICATEUR;

BLOCLENGTH = INTEGER;

READ = 'READ' '('ADTAMPON', ' BLOCLENGTH LINK')' TER;

ENDFILE = 'WRITEOF' TER;

RD = 'READDIRECT' '('ADPERIPH LINK')' TER;

WD = 'WRITEDIRECT' '('ADPERIPH LINK')' TER;

ADPERIPH = IDENTIFICATEUR/INTEGER;

LINK = (','(CHAIN/CONCAT)/);

CHAIN = 'CC'/'DC';

CONCAT = 'CCDC';
PROCEDURECALL = 'CALL' PROCEDURENAME '(' LISTPARAM')' TER;

PROCEDURENAME = .ID;

LISTPARAM = VAR $(',' VAR);

PRIMITIVACTIV = 'JUMP' PRIMITIVENAME TER;

RETURN = 'RETURN' TER;

INITIALIZEFIELD = ('SETO'/'SET1') '(' FIELDNAME')' TER;

INTERSPEC = 'INTERFACE' ':'

$((VARNAME/PRIMTIVENAME):' LISTMODULE TER);

LISTMODULE = MODULNAME $(','MODULNAME);

PROCEDURDEFN = ('RESIDENT' ('REENTRANT' /)
                 /'REENTRANT' ('RESIDENT' /
                 /)'PROCEDURE' PROCEDURENAME
                 '('PARAMETERLIST')' $DECLARATION
                 1$STATEMENT 'END' ';

PARAMETERLIST = VARNAME $(','VARNAME);

ECHANGE = 'PROGECH' NECH ':';

NPAQUET $(','NPAQUET) 'PUIS' ACTION TER LISTPAQU;

NECH = .ID;

NPAQUET = .ID;

ACTION = PRIMITIVENAME;

LISTPAQU = PAQDECL $(PAQDECL);

PAQDECL = 'PAQUET' NPAQUET TER;

CREECH = 'METS' DEMECHDEFN 'DANS' NPAQUET TER;

DEMECHDEFN = ('ENTREE'/'SORTIE')

‘(‘LISTPARECH‘)‘;

LISTPARECH = IDPARECH '=' PAREF $(','IDPARECH '=' PAREF);

IDPARECH = 'PERIPH'/'MC'/'ADP'/'MA'/'LG'/'URG';

PAREF = TYPERIPH/.ID/.NUM;

TYPERIPH = 'TTY1'/'TTY2'/'LR'/'PR'/'DB'/'D'/'VISU';

ACTIVECH = 'LANCE' NECH TER;
REFERENCES ET BIBLIOGRAPHIE.

[1] M.DEPEYROT. "Spécification de définition de LEX". Etude de l'IRIA.IE/30. (Avril 1972).

[2] J.C.CAZIN, M.DEPEYROT. "BERGSON, un compilateur pour calculateurs industriels". Article de l'IRIA.IA/37. (Octobre 1972).

[3] G.NICOLAS, J.LABETOULLE. "Manuel de META-5 sous Siris-7 et compléments". Etude de l'IRIA.IE/25. (Octobre 1971).

[4] Collectif. "La conception automatique du système SPECTRE". Article de l'IRIA.IA/36. (Septembre 1972).

[5] J.F.CHALLINE. "Comment mettre quoi dans la division d'environnement". Note technique.NT/072. (à paraître).

[6] J.P.FISCHBACH. "Spécifications de définition d'ASSIRIA O". Etude de l'IRIA.IE/31. (Février 1973).

[7] L.BOLLIET, N.GASTINEL, P.J.LAURENT. "Un nouveau langage scientifique ALGOL. Manuel Pratique". HERMANN (1964).

[8] F.J.RODRIGUEZ. "Une vision intégrée de Modules et d'Interfaces". Note Technique.NT/075. (19 Février 1973).

[9] F.J.RODRIGUEZ. "Un module structuré pour la conception de systèmes". Note technique.NT/076 (5 Mars 1973).

[10] F.BANCILHON, J.C.CAZIN. "Standards de programmation et division d'environnement". Note Technique.NT/050 ter. (8 Décembre 1972).
[11] J.C.CAZIN. "Quelques extensions pour l'étude de LEX". Note Technique NT/058. (8 Décembre 1972).

[12] J.C.CAZIN. "Etat d'avancement du compilateur BERGSON". Note Technique. NT/027. (1 Juin 1972).

[13] MAISONNEUVE, "Le canal simulé". Notice d'emploi de programme. PREISSMAN. IP/212. (1973).

[14] F.BANCILHON, "Programmes d'échange et moniteur d'échanges dans SPECTRE". V.CAZIER, Etude de l'IRIA. J.LABETOULLE. IE/38. (Janvier 1973).