Sommaire Définition du langage d’expérimentation Compilateur pour le langage Z minimal Extensions du langage Z minimal
Chapitre précédent Chapitre 19 : Fichiers Chapitre suivant
19.1 Introduction
On définit une machine abstraite sur les fichiers permettant l’initiation aux structures simples de fichiers. Cette machine abstraite offre les opérations suivantes de base sur les fichiers: OUVRIR, FERMER, LIRESEQ, ECRIRESEQ, LIREDIR, ECRIREDIR, RAJOUTER, FINFICH, ENTETE, AFF_ENTETE, ALLOC_BLOC. Toutes ces fonctions ont été définies dans la partie présentation du langage Z.
La sémantique consiste à transformer ces opérations en des formes internes (quadruplets) qui permettent de faciliter leur interprétation ou génération de code. Il s’agit donc de déterminer l’emplacement des fonctions sémantiques dans les règles de grammaire ainsi que leur description en détail.
Préalablement, nous devons définir dans la phase sémantique un codage de fichiers.
19.2 Table des types (TABTYP)
Nous utilisons le codage suivant:
F pour fichier et * pour l’entête d’un fichier.
Exemples
Un fichier d’entiers est codé en FE (F pour fichier et E pour entier).
Un fichier de structures simples à trois champs (Entier, Booleen, Car) est codé en F(EBC) (F pour fichier et (EBC) pour la structure).
Un fichier de structures simples à trois champs (Entier, Booleen, Car) avec un entête contenant une chaîne de caractères et un entier est codé en F(EBC)*(SE) (F pour fichier , (EBC) pour la structure des éléments du fichier et *(SE) pour l’entête composé d’une chaîne de caractères et un entier).
La sémantique d’une déclaration de fichier consiste à former le type tel que décrit ci-dessus.
19.3 Quadruplets
Pour une déclaration de Fichier (voir grammaire), le quadruplet (‘Df’, A ,B, C ) est créé avec les paramètres suivants:
A : pointeur dans TABOB vers l’objet fichier.
B : est égal à 1 (absence de l’entête), égal à 2 (présence de l’entête).
C : pointeur dans TABOB vers la constante contenant le type de l’entête si B=2.
Remarque : le type de l’entête est évidemment ‘S’. Le champ Adresse de l’objet C dans la table TABOB contient donc le rang de la constante dans la table des constantes TABCONS.
Pour les opérations d’ouverture/fermeture, OUVRIR(F, Fichier physique, Mode) et FERMER(F) les quadruplets suivants sont à générer:
- (‘Ouvrir’,A ,B, C )
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers la constante contenant le nom du fichier physique.
C : pointeur dans TABOB vers la constante contenant le mode d’ouverture.
- (‘Fermer’,A ,B, C )
A, B non utilisés.
C : pointeur dans TABOB vers l’objet fichier.
Pour les opérations d’accès séquentiel LIRESEQ(F,Tampon), ECRIRESEQ(F, Tampon) et RAJOUTER(F, Tampon) les quadruplets suivants sont à générer:
- (‘Lireseq’,A ,B, C )
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le tampon.
- (‘Ecrireseq’, A ,B, C )
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le tampon.
- (‘Rajouter’ ,A ,B, C )
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le tampon.
Pour les opérations d’accès direct LIREDIR(F, Rang, Tampon) et ECRIREDIR(F, Rang, Tampon) les quadruplets suivant sont à générer:
- (‘Liredir’,A ,B, C )
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le tampon.
C : pointeur dans TABOB vers le rang.
- (‘Ecriredir’, A ,B, C )
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le tampon.
C : pointeur dans TABOB vers le rang.
Pour les opérations concernant l’entête de fichier ENTETE(F, Rang) et AFF_ENTETE(F, Rang, Exp) les quadruplets suivants sont à générer:
- (‘Entete’,A ,B, C )
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le rang.
C : pointeur dans TABOB vers le résultat.
- (‘Aff_entete’, A ,B, C )
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le rang.
C : pointeur dans TABOB vers le résultat à affecter.
Pour les opérations FINFICH(F) et ALLOC_BLOC(F) les quadruplets suivants sont à générer:
- (‘Finfich’,A ,B, C )
A : pointeur dans TABOB vers l’objet fichier.
B : non utilisé.
C : pointeur dans TABOB vers le résultat.
- (‘Alloc_bloc’, A ,B, C )
A : pointeur dans TABOB vers l’objet fichier.
B : non utilisé.
C : pointeur dans TABOB vers le résultat .
19.4 Syntaxe
Notre grammaire devient comme suit avec l’intégration des règles en surbrillance relatives aux fichiers:
Déclarations
<Algo Z> → [ ~Soit|Soient~ <Ps> ] Debut <Lis> Fin [;] { ~<Act> | <Fonct>~ [;] }*
<Act> → Action Idf [ ( <Li> ) ] [;] [ ~Soit|Soient~ <Ps> ] Debut <Lis> Fin
<Fonct> → Fonction Idf ( <Li> ) : <Typ> [ ~Soit|Soient~ <Ps> ] Debut <Lis> Fin
<Ps> → <S>;{ [~Soit|Soient~] <S>;}*
<S> → <Li> Sep ~<Typ>|~Action|Fonction(<Typ>)~ ~
<Li> → Idf {, Idf}*
<Typ> → Types | <Structsimple> | <Structcomplexe> |
Machine_car |
Machine_nombre |
[Pointeur vers [Sep] ] Liste
[ De ~Types | <Structsimple>~ ] |
Fichier De ~ Types | Vecteur(Cste) [De Types] |
<Structsimple> | <Structcomplexe> ~
[Entete (Types {, Types }*)] Buffer <Li> |
Tableau (<Lc>) [De~<Structsimple> | Types~ ] |
<Structsimple> → [Structure ](Types {, Types }*)
<Structcomplexe> → [Structure ]( ~ Types | Vecteur(Cste) [De Types] ~ {, ~ Types | Vecteur(Cste) [De Types] ~ }*)
<Lc> → Cste {, Cste}*
Instructions:
< Lis > → < Inst > { ; < Inst > }*
<Inst> → Idf := <Exp> |
Lire ( Idf {, Idf }* ) |
Ecrire (<Exp> {,<Exp>}* ) |
Tantque <Exp> [ : ] <Lis> Fintantque |
Si <Exp> [:] <Lis> [Sinon <Lis>] Fsi |
Pour Idf:= <Exp>,<Exp> [, <Exp>][:] <Lis> Finpour |
Appel Idf [(Exp {,<Exp>}*)] |
~Liberer| Allouer | Fermer ~ ( <Exp> ) |
~ Aff_adr|Aff_val~ ( <Exp> , <Exp> ) |
Ouvrir ((Idf, Chaine, Chaine) |
~ Creer_liste| Init_vecteur|Init_struct|Creer_mnombre ~ ( Idf , [[ ~<Exp>|[[<Exp> {, <Exp>}*]] ~ {, ~<Exp>|[[<Exp> {, <Exp>}*]]~}* ]] ) |
Aff_element ( <Exp> [[ <Exp> {, <Exp> }* ]] ,<Exp> ) |
~ Aff_struct | Aff_entete ~ (Idf, Cste, <Exp>) |
Creer_mcar (Idf, [[ Chaine ]] ) |
~Lirecar|Lirenombre~ (Idf, Idf) |
~Lireseq|Ecrireseq|Rajouter~(Idf, Idf) |
~ Liredir | Ecriredir ~ (Idf, <Exp>, Idf)
Expressions
<Exp> → <Exps>[ Opr <Exps>]
<Exps> → [Sign] <Terme> { Opa <Terme> }*
<Terme> → <Facteur>{Opm <Facteur>}*
<Facteur> → Idf [(Exp {,<Exp>}*)] | Cste | ( <Exp>) | <Fonct> | Nil | Non <Facteur> | Vrai | Faux | Chaine
<Fonct> → ~Valeur|Suivant~ ( <Fonct> ) |
Element ( <Fonct> [[ <Exp> {, <Exp> }* ]] ) |
~ Struct | Entete ~ ( Idf, Cste) |
~Nbrcar|NbrNombre | Finfich|Alloc_bloc ~ (Idf)
19.5 Fonctions sémantiques
Déclaration
<Typ> → Fichier De ~ Types F1 |
Vecteur F2 (Cste F3) [De Types F1] F4 |
<Structsimple> F5 | <Structcomplexe> F5 ~
[Entete (Types F6 {, Types F7 }*) F8 ]
Buffer <Li> F9
F1
Si Sem=’Chaine’ : Type = ‘HS’ sinon Type = ‘H’+Sem[1]; B=1 pour un fichier supposé sans entête.
F2
Type = Type +’V’.
F3
Type = Type + Sem. Sem contient la constante Cste.
F4
Si le dernier caractère de Type est un chiffre alors faire Type = Type + ‘E’.
F5
soit Type_struct le type retourné par <Structsimple> ou <Structcomplexe>. Faire Type = Type + Type_struct .
F6
Si Sem = ‘Chaine’ : Type= Type + ’*S’ sinon Type =Type + ‘*’ + Sem[1] ; B=2 pour fichier avec entête.
F7
Si Sem = ‘Chaine’ : Type= Type + ’S’ sinon Type =Type + Sem[1].
F8
Créer dans TABCONS une constante de valeur la chaîne composée des types de l’entête et la mettre dans la table des objets TABOB. Soit C son emplacement dans la table des objets.
F9
Récupérer de type le type des éléments du ficher. Soit Type_element ce type et I son indice dans la table TABTYP.
Soit L la liste produite par <Li>.
Pour chaque Idf dans L :
-- Le mettre dans la table des symboles;
-- Lui attribuer un type
-- Lui attribuer une adresse relative A et le mettre dans la table des objets (soit Pt son emplacement).
L’objet créé aura comme Statut=‘L’;Type=I; Nombre=Longueur de Type et Adresse=A.
Spécification
<S> → <Li> [ Sep <Typ> ] F1
F1
Soit L la liste produite par <Li> et soit Type le type du fichier produit par <Typ>.
Ranger Type dans TABTYP si Type n’existe pas. Soit I son indice dans cette table.
Pour chaque Idf dans L :
- Le mettre dans la table des symboles;
- Lui attribuer un type
- Lui attribuer une adresse relative A et le mettre dans la table des objets (soit Pt son emplacement).
L’objet créé aura comme Statut=‘L’;Type=I; Nombre=Longueur
de Type et Adresse=A; Générer pour chaque Idf référencé par Ptidf dans TABOB le quadruplet (‘Df’, Ptidf, B, C).
Fermer
<Inst> → Fermer ( Idf ) F1
F1
Vérifier que Idf est déclaré en tant que fichier. Soit Ptidf son indice dans la table des objets TABOB.
Générer le quadruplet (‘Fermer’, , , Ptidf).
Ouvrir
<Inst> → Ouvrir ((Idf F1 , Chaine F2 , Chaine F3 ) F4
Rappel : la première chaîne désigne le nom du fichier physique, la seconde le mode d’ouverture du fichier.Réalisation d'un compilateur pédagogique
F1
Vérifier que Idf est déclaré en tant que fichier. Soit Ptidf son indice dans la table des objets TABOB.
F2
Créer dans TABCONS une constante de valeur Chaîne et la mettre dans la table des objets TABOB. Soit Ptchaine1 son emplacement dans cette table.
F3
Créer dans TABCONS une constante de valeur Chaîne et la mettre dans la table des objets TABOB. Soit Ptchaine2 son emplacement dans cette table.
F4
Générer le quadruplet (‘Ouvrir’, Ptidf, Ptchaine1, Ptchaine2)
Aff__entete
<Inst> → Aff_entete (Idf F1 , Cste F2 ,<Exp> F3 ) F4
F1
Vérifier que Idf est déclaré en tant que fichier. Soit Ptidf son indice dans la table des objets.
F2
Vérifier que Cste est une valeur possible puis créer une constante de valeur Cste et la mettre dans la table des constantes TABCONS.
F3
Vérifier que le type de <Exp> est conforme avec le champ de rang Cste dans l’entête. Soit Temp l’emplacement de l’objet dans la table des objets contenant le résultat de <Exp>.
F4
Générer le quadruplet (‘Aff_entete’, Ptidf, Cste, Temp)
Lireseq, Ecrireseq et Rajouter
<Inst> → ~Lireseq F1 |Ecrireseq F1 |Rajouter F1 ~ (Idf F2 , Idf F3 ) F4
F1
Sauv := Sem.
F2
Vérifier que Idf est déclaré en tant que fichier. Soit Ptidf son indice dans la table des objets TABOB.
F3
Vérifier que Idf est du type du buffer du fichier. Soit Ptidf2 son indice dans la table des objets.
F4
Générer le quadruplet (Sauv, Ptidf, Ptidf2, )
Liredir, Ecriredir
<Inst> → ~ Liredir F1| Ecriredir F1 ~ (Idf F2 , <Exp> F3 , Idf F4 ) F5
F1
Sauv := Sem.
F2
Vérifier que Idf est déclaré en tant que fichier. Soit Ptidf son indice dans la table des objets TABOB.
F3
Vérifier que <Exp> est une variable entière. Soit Temp l’objet créé contenant le résultat de <Exp>.
F4
Vérifier que Idf est du type du buffer du fichier. Soit Ptidf2 son indice dans la table des objets.
F5
Générer le quadruplet (Sauv, Ptidf, Temp, Ptidf2).
Entete
<Fonct> → Entete ( Idf F1 , Cste F2 ) F3
F1
Vérifier que Idf est déclaré en tant que fichier. Soit Ptidf son indice dans la table des objets TABOB.
F2
Vérifier que Cste est une valeur possible puis créer une constante de valeur Cste et la mettre dans la table des constantes TABCONS.
F3
Soit Temp l’objet créé contenant le résultat de la fonction. Générer le quadruplet (‘Entete’, Ptidf, Cste, Temp).
Finfich et Alloc_bloc
<Fonct> → ~ Finfich F1 |Alloc_bloc F1 ~ ( Idf ) F2
F1
Sauv := Sem.
F2
Vérifier que Idf est déclaré en tant que fichier. Soit Ptidf son indice dans la table des objets TABOB. Soit Temp l’objet créé contenant le résultat de la fonction. Générer le quadruplet (Sauv, Ptidf, , Temp).
19.6 Exemple 1
Le programme suivant crée un nouveau fichier avec des données lues. Chaque élément du fichier est un enregistrement à deux champs (une chaîne de caractères et un entier). Le fichier a comme entête une chaîne de caractères (nom du fichier par exemple) et un entier (nombre d’enregistrements).
SOIT F1 UN FICHIER DE ( CHAINE , ENTIER ) ENTETE ( CHAINE , ENTIER ) BUFFER V1 ; S UNE CHAINE ; E, I :ENTIERS ; DEBUT OUVRIR ( F1 , 'f1.pas' , 'N' ) ; POUR I := 1 , 3 LIRE ( S , E ) ; AFF_STRUCT ( V1 , 1 , S ) ; AFF_STRUCT ( V1 , 2 , E ) ; ECRIRESEQ ( F1 , V1 ) ; FINPOUR ; AFF_ENTETE ( F1 , 1 , 'Z' ) ; AFF_ENTETE ( F1 , 2 , I - 1 ) ; FERMER ( F1 ) ; FIN |
La figure 37 montre les tables de compilation générées pour le programme ci-dessus.
Figure 37: Tables de compilation(Fichiers) - Exemple1
19.7 Exemple 2
Le programme ci-après ouvre un fichier existant, affiche ses caractéristiques (entête) et lit séquentiellement le fichier pour afficher ses éléments.
SOIT F1 UN FICHIER DE ( CHAINE , ENTIER ) ENTETE ( CHAINE , ENTIER ) BUFFER V1 ; DEBUT OUVRIR ( F1 , 'f1.pas' , 'A' ) ; ECRIRE ( ENTETE ( F1 , 1 ) ) ; ECRIRE ( ENTETE ( F1 , 2 ) ) ; TQ NON FINFICH ( F1 ) LIRESEQ ( F1 , V1 ) ; ECRIRE ( V1 ) FTQ ; FIN |
La figure 38 montre les tables de compilation générées pour le programme ci-dessus.
Figure 38: Tables de compilation(Fichiers) - Exemple2
19.8 Interprétation
Considérations
- Au niveau le plus bas, un fichier est considéré‚ comme un fichier d'octets.
- Au plus, 5 fichiers (Maxfich) utilisateurs peuvent être ouvert en même temps, ce qui correspond aux fichiers internes F1, F2, F3, F4 et F5.
- A tout fichier utilisateur, on associe un numéro permettant de faire l'association entre le fichier utilisateur et le fichier interne réellement implanté.
- Le fichier interne est un ensemble d'octets découpé comme suit :
<-------------------> <-------------> <------------> ......
Caractéristiques Article 1 Article 2
- Les articles de ce fichier sont de longueur fixe.
Implémentation
Le fichier est implémenté (en PASCAL) comme suit:
(Description PASCAL)
TYPE Typefichier = ^Elementfichier;
Elementfichier = RECORD
Num : BYTE; { Association fichier logique - fichier interne}
Ouvert : BOOLEAN; { Ouvert / Fermé }
Longueur : INTEGER;{ Longueur d'un article }
Longcaract : BYTE;{ Longueur de la zone des caractéristiques }
Caract : STRING[20]; { Types des caractéristiques }
Adrcaract : Pointer;{ Adresse vers zone des caractéristiques }
END;
Interprétation
A la rencontre du quadruplet (‘Df’, A ,B, C ) avec les paramètres définis comme suit::
A : pointeur dans TABOB vers l’objet fichier.
B : est égal à 1 (absence de l’entête), égal à 2 (présence de l’entête).
C : pointeur dans TABOB vers la constante contenant le type de l’entête si B=2.
les opérations suivantes sont effectuées:
Allocation d'une zone de type Elementfichier.
Affecter à Ouvert la valeur faux.
Affecter à Num la valeur 0.
Affecter à Adrcaract la valeur Nil.
Affecter à Caract le type des caractéristiques.
Affecter à Longueur la longueur des articles.
Affecter à Longcaract la longueur de la zone des caractéristiques.
A la rencontre du quadruplet (‘Ouvrir’,A ,B, C ) avec les paramètres définis comme suit:
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers la constante contenant le nom du fichier physique.
C : pointeur dans TABOB vers la constante contenant le mode d’ouverture.
Les opérations suivantes sont effectuées:
Si le fichier n'est pas ouvert
Affecter à Ouvert la valeur Vrai.
Incrémenter le nombre de fichiers ouverts.
Associer au fichier logique Flogique un fichier interne Fi.
Faire le lien entre Fi et fichier physique Fphysique.
SI Mode ='N' ouverture de Fi en écriture.
SI Mode ='A' ouverture de Fi en lecture/écriture.
Fsi
SI fichier avec caractéristique (ou entête)
SI mode='N'
- Réserver dans le fichier la zone pour les caractéristiques en recopiant des blancs.
- Allocation d'une zone contenant les adresses vers les caractéristiques.
- Affecter à Adrcaract l’adresse de cette zone.
SINON { 'A' }
S’il n’était pas ouvert :
- Allocation d'une zone contenant les adresses vers les caractéristiques.
- Affecter à Adrcaract l’adresse de cette zone.
- Récupérer les caractéristiques du fichier vers la mémoire).
FSI
FSI
A la rencontre du quadruplet (‘Fermer’,A ,B, C ) avec les paramètres définis comme suit:
A, B non utilisés.
C : pointeur dans TABOB vers l’objet fichier.
les opérations suivantes sont effectuées:
- Si le fichier n'est pas ouvert : erreur.
- Sauvegarde des caractéristiques et libération de la zone mémoire réservée pour les caractéristiques.
- Fermer le fichier interne associé.
- Affecter à Num la valeur 0.
- Affecter à Ouvert la valeur Faux.
- Décrémenter le nombre de fichiers ouverts.
A la rencontre des quadruplets (‘Ecrireseq’,A ,B, C ), (‘Ecriredir’, A ,B, C ) et (‘Rajouter’ ,A ,B, C ) avec les paramètres définis comme suit:
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le tampon.
C : pointeur dans TABOB vers la position du fichier.
les opérations suivantes sont effectuées:
- Si le fichier n'est pas ouvert : erreur.
- S'il s'agit d'une écriture directe, se positionner sur la position donnée si elle existe.
- S'il s'agit de rajouter, se positionner en fin de fichier.
- Écrire l'article dans le fichier.
Remarquons que C est non utilisé pour les quadruplets (‘Ecrireseq’,A ,B, C ) et (‘Rajouter’ ,A ,B, C ).
A la rencontre des quadruplets (‘Lireseq’,A ,B, C ) et (‘Liredir’, A ,B, C ) avec les paramètres définis comme suit:
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le tampon.
C : pointeur dans TABOB vers la position du fichier.
les suivantes sont effectuées:
- Si le fichier n'est pas ouvert : erreur.
- S'il s'agit d'une lecture directe, se positionner sur la position donnée si elle existe.
- Lire l'article du fichier.
Remarquons là aussi que C est non utilisé pour les quadruplets (‘Lireseq’,A ,B, C).
A la rencontre du quadruplet (‘Aff_entete’, A ,B, C ) avec les paramètres définis comme suit:
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le rang.
C : pointeur dans TABOB vers le résultat à affecter.
les opérations suivantes sont effectuées:
Si le fichier F n'est pas ouvert : erreur.
Affecter le résultat référencé par C comme caractéristique ayant pour le rang référencé par B.
A la rencontre du quadruplet (‘Entete’,A ,B, C ) avec les paramètres définis comme suit:
A : pointeur dans TABOB vers l’objet fichier.
B : pointeur dans TABOB vers le rang.
C : pointeur dans TABOB vers le résultat.
les opérations suivantes sont effectuées:
Si le fichier F n'est pas ouvert : erreur.
Récupérer la caractéristique ayant pour rang la valeur référencée par C.
A la rencontre du quadruplet (‘Alloc_bloc’, A ,B, C ) avec les paramètres définis comme suit:
A : pointeur dans TABOB vers l’objet fichier.
B : non utilisé.
C : pointeur dans TABOB vers le résultat .
les opérations suivantes sont effectuées:
Si le fichier F n'est pas ouvert : erreur.
Se positionner en fin de fichier et rendre cette position comme résultat de la fonction dans l’objet référencé par C.
A la rencontre du quadruplet (‘Finfich’,A ,B, C ) avec les paramètres définis comme suit:
A : pointeur dans TABOB vers l’objet fichier.
B : non utilisé.
C : pointeur dans TABOB vers le résultat.
les opérations suivantes sont effectuées:
Si le fichier F n'est pas ouvert : erreur.
Si la position est en fin de fichier, la fonction rend la valeur Vrai sinon Faux dans l’objet référencé par C.