TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Interprete_bloc.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Interprete_bloc.h>
17#include <Type_Verifie.h>
18
19// `export <Type> <name>` is a TRUST-specific prefix on forward
20// declarations — it tells Interprete_bloc::lire to add the resulting
21// object to the parent Interprete_bloc's scope instead of the local
22// one, so the name survives Read_file's sub-block destruction. There
23// is no dedicated C++ class for it; the parsing is inlined below.
24// trustify recognises the `export` keyword directly in
25// Dataset_Parser.ReadFromTokens — it treats `export <Type> <name>`
26// as a regular forward declaration and stashes the `export` token on
27// the resulting Declaration_Parser for round-trip emission.
28
29Implemente_instanciable_sans_constructeur_ni_destructeur(Interprete_bloc,"Interprete_bloc",Liste_bloc);
30
31// Voir Interprete_bloc::interprete_courant()
32static OBS_PTR(Interprete_bloc) interprete_courant_;
33
34/*! @brief renvoie l'interprete_bloc en train d'etre lu dans le jeu de donnees.
35 *
36 * On change d'interprete courant
37 * quand on cree et on detruit un objet de type Interprete_bloc
38 * (par exemple quand on entre ou qu'on sort d'un bloc { })
39 *
40 */
42{
43 return interprete_courant_.valeur();
44}
45
46Interprete_bloc::Interprete_bloc()
47{
48 // S'il existe un interprete courant, il devient le pere
49 // de l'interprete en cours de construction:
50 if (interprete_courant_) pere_ = interprete_courant_;
51
52 interprete_courant_ = *this;
53}
54
55Interprete_bloc::~Interprete_bloc()
56{
57 // Restaure la valeur de l'interprete courant precedent
58 interprete_courant_ = pere_;
59}
60
62{
64 return os;
65}
66
68{
70 return is;
71}
72
73/*! @brief Interpretation d'un bloc d'instructions prises dans l'entree is.
74 *
75 * Si le bloc commence par {, on suppose que l'accolade a deja ete lue.
76 * Le bloc se termine soit par }, soit par la fin du fichier, soit par
77 * le mot FIN en fonction de bloc_type (voir mon_main.cpp par exemple)
78 * Si verifie_sans_interpreter!=0, on ne cree aucun objet et on ne
79 * lance aucun interprete, on se contente de verifier la coherence des
80 * accolades (meme nombre de { que de }).
81 *
82 */
83Entree& Interprete_bloc::interpreter_bloc(Entree& is, Bloc_Type bloc_type, int verifie_sans_interpreter)
84{
85 // Le niveau de sortie des messages journal
86 const int jlevel = 3;
87 Journal(jlevel) << "Interprete_bloc::interpreter_bloc bloc_type=" << (int) bloc_type << finl;
88 Motcle motlu;
89 is >> motlu;
90 while (1)
91 {
92 // Est-ce qu'on est a la fin du bloc ?
93 if (is.eof())
94 {
95 // Certains fichiers .data ne se terminent pas par FIN, on accepte aussi d'arriver a eof
96 // sans avoir trouve "FIN".
97 if (bloc_type == BLOC_EOF || bloc_type == FIN)
98 {
99 Journal(jlevel) << "Interprete_bloc: end of file => end of bloc" << finl;
100 break;
101 }
102 else
103 {
104 Cerr << "Error in Interprete_bloc: unexpected end of file\n" << "check for missig \"}\" or missing FIN keyword" << finl;
106 }
107 }
108 // Autres fins possibles:
109 if (motlu == "}" || motlu == "FIN|END")
110 {
111 if ((motlu == "}" && bloc_type == ACCOLADE) || (motlu == "FIN|END" && bloc_type == FIN))
112 {
113 Journal(jlevel) << "Interprete_bloc: reading " << motlu << " => end of bloc" << finl;
114 break;
115 }
116 else
117 {
118 if (motlu == "}")
119 Cerr << "Error in Interprete_bloc: extra \"}\" in data file" << finl;
120 else
121 Cerr << "Error in Interprete_bloc: unexpected FIN, check for missing \"}\"" << finl;
123 }
124 }
125
126 // Est-ce que c'est un commentaire ?
127 if (motlu == "#")
128 {
129 Nom commentaire("# ");
130 Nom nom_lu;
131 int countleft = 8; // On retient les 8 premiers mots du commentaire
132 do
133 {
134 is >> nom_lu;
135 if (is.eof())
136 break;
137 if ((countleft--) > 0)
138 {
139 commentaire += nom_lu;
140 commentaire += " ";
141 }
142 }
143 while (nom_lu != "#");
144 if (is.eof())
145 {
146 Cerr << "Error in Interprete_bloc: end of file while reading a comment :\n" << commentaire << "..." << finl;
147 }
148 // Prochain mot a interpreter:
149 motlu = nom_lu;
150 }
151 else if (motlu == "{")
152 {
153 Journal(jlevel) << "Interprete_bloc: reading { => creating new Interprete_bloc" << finl;
154 // Est-ce que c'est un debut de bloc ?
155 // Nouvel interprete:
156 Interprete_bloc inter;
157 inter.interpreter_bloc(is, ACCOLADE, verifie_sans_interpreter);
158 }
159 else
160 {
161 if (verifie_sans_interpreter)
162 {
163 // Si on veut seulement verifier le nombre d'accolades,
164 // il suffit d'ignorer le motcle... on ouvre recursivement
165 // de nouveaux interprete si on rencontre { et on les ferme
166 // si on trouve }. S'il manque une } a la fin, on obtiendra le message
167 // "check for missing }" et s'il y en a une en trop on aura
168 // le message "extra }"
169 Journal(jlevel) << "Interprete_bloc: just checking {} => ignore keyword " << motlu << finl;
170 verifie(motlu);
171 }
172 else
173 {
174 // Dans le bloc suivant, s'il y a une erreur de lecture sur is, c'est une erreur:
176 int export_object = 0;
177 if (motlu == "export")
178 {
179 Journal(jlevel) << "Exporting object, reading object type..." << finl;
180 export_object = 1;
181 is >> motlu;
182 }
183 // Le mot cle doit etre un type d'objet instanciable
184 Journal(jlevel) << "Interprete_bloc: reading " << motlu << " => trying to instanciate object" << finl;
185 DerObjU objet;
186 objet.typer(motlu);
187
188 if (sub_type(Interprete, objet.valeur()))
189 {
190 // Si c'est un interprete, on appelle la methode interprete de l'objet:
191 Journal(jlevel) << " Calling object.interpreter()" << finl;
192 Interprete& inter = ref_cast(Interprete, objet.valeur());
193 inter.interpreter(is);
194 }
195 else
196 {
197 // Ce n'est pas un interprete, on lit le nom de l'objet et on le stocke
198 Journal(jlevel) << " Reading object name" << finl;
199 Nom nom_objet;
200 is >> nom_objet;
201 Journal(jlevel) << " Storing object " << nom_objet << " of type " << motlu << finl;
202 if (!export_object || !pere_)
203 ajouter(nom_objet, objet);
204 else
205 pere_->ajouter(nom_objet, objet);
206 }
208 }
209 }
210 is >> motlu;
211 }
212 return is;
213}
214
215/*! @brief Renvoie l'Objet_U correspondant a nom contenu dans cet interprete_bloc Si l'objet n'existe pas, exit() (on ne cherche pas dans le pere).
216 *
217 */
219{
220 const int i = les_noms_.search(nom);
221 if (i < 0)
222 {
223 Cerr << "Internal error in Interprete::objet_local() : object '" << nom << "' does not exist" << finl;
225 }
226 return operator[](i);
227}
228
229/*! @brief renvoie un drapeau indiquant si un objet de ce nom est enregistre dans cet inteprete (ne teste pas le pere).
230 *
231 */
233{
234 const int i = les_noms_.search(nom);
235 return (i >= 0);
236}
237
238/*! @brief Ajoute l'objet ob a la liste des objets de l'interprete, et nomme l'objet avec nom.
239 *
240 * Si l'objet existe deja, exit()
241 *
242 */
243Objet_U& Interprete_bloc::ajouter(const Nom& nom, DerObjU& ob)
244{
245 Journal(3) << "Interprete::ajouter(" << nom << ") de type " << ob->que_suis_je() << finl;
246 if (les_noms_.search(nom) >= 0)
247 {
248 Cerr << "Error in Interprete::ajouter: object " << nom << " already exists." << finl;
250 }
251 les_noms_.add(nom);
252 Objet_U& obu = add_deplace(ob);
253 obu.nommer(nom);
254 return obu;
255}
256
257/*! @brief cherche l'objet demande dans l'Interprete_bloc courant (Interprete_bloc::interprete_courant()) et dans tous
258 *
259 * ses peres successifs. Si l'objet n'existe pas, exit()
260 *
261 */
263{
265 while (ptr)
266 {
267 Interprete_bloc& interp = ptr.valeur();
268 if (interp.objet_local_existant(nom))
269 {
270 Objet_U& objet = interp.objet_local(nom);
271 return objet;
272 }
273 ptr = interp.pere_;
274 }
275 // Objet non trouve !
276 Cerr << "Error in Interprete::objet: object " << nom << " does not exist." << finl;
278 return objet_global(nom); // Pour le compilo
279}
280
281/*! @brief renvoie un drapeau indiquant si un objet de ce nom existe dans inteprete_courant() ou l'un de ses parents.
282 *
283 */
285{
287 while (ptr)
288 {
289 Interprete_bloc& interp = ptr.valeur();
290 if (interp.objet_local_existant(nom))
291 return 1;
292 ptr = interp.pere_;
293 }
294 // Objet non trouve !
295 return 0;
296}
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
@ ERROR_EXIT
Definition Entree.h:93
@ ERROR_CONTINUE
Definition Entree.h:93
virtual void set_error_action(Error_Action)
Change le comportement en cas d'erreur de l'entree, voir error_handle_() et get_error_action().
Definition Entree.cpp:382
virtual int eof()
Definition Entree.cpp:256
Interprete un bloc d'instructions dans le jeu de donnees.
OBS_PTR(Interprete_bloc) pere_
Objet_U & ajouter(const Nom &nom, DerObjU &object_to_add)
Ajoute l'objet ob a la liste des objets de l'interprete, et nomme l'objet avec nom.
Entree & interpreter_bloc(Entree &is, Bloc_Type bloc_type, int verifier_sans_interpreter)
Interpretation d'un bloc d'instructions prises dans l'entree is.
static int objet_global_existant(const Nom &nom)
renvoie un drapeau indiquant si un objet de ce nom existe dans inteprete_courant() ou l'un de ses par...
Objet_U & objet_local(const Nom &nom)
Renvoie l'Objet_U correspondant a nom contenu dans cet interprete_bloc Si l'objet n'existe pas,...
static Interprete_bloc & interprete_courant()
renvoie l'interprete_bloc en train d'etre lu dans le jeu de donnees.
int objet_local_existant(const Nom &nom)
renvoie un drapeau indiquant si un objet de ce nom est enregistre dans cet inteprete (ne teste pas le...
static Objet_U & objet_global(const Nom &nom)
cherche l'objet demande dans l'Interprete_bloc courant (Interprete_bloc::interprete_courant()) et dan...
Classe de base des objets "interprete".
Definition Interprete.h:38
virtual Entree & interpreter(Entree &)=0
La classe Liste_bloc et Liste_bloc_curseur represente une liste de Deriv<Objet_U> et un curseur assoc...
Definition Liste_bloc.h:25
Objet_U & operator[](int)
Operateur d'acces au ieme element de la liste.
Objet_U & valeur()
Definition Liste_bloc.h:32
Objet_U & add_deplace(DerObjU &)
Ajout d'un Objet_U a la liste to_add est libere en sortie.
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
Objet_U * typer(const char *nom_type)
Essaie de creer une instance du type "type".
friend class Entree
Definition Objet_U.h:76
virtual void nommer(const Nom &)
Donne un nom a l'Objet_U Methode virtuelle a surcharger.
Definition Objet_U.cpp:329
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
Objet_U()
Constructeur par defaut : attribue un numero d'identifiant unique a l'objet (object_id_),...
Definition Objet_U.cpp:55
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
Definition Process.cpp:588
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
const Objet_U & valeur() const