Salome HOME
CCAR : quelques modifs sur convertisseur python (liste de MCFACT)
[tools/eficas.git] / Aster / Cata / pre74 / FORM.py
1 #            CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
19 # ======================================================================
20 """
21 """
22 import string,traceback
23
24 from Accas import MACRO_ETAPE,MACRO
25 from Extensions import interpreteur_formule
26
27
28 class FORM_ETAPE(MACRO_ETAPE):
29
30     interpreteur = interpreteur_formule.Interpreteur_Formule
31
32     def McBuild(self):
33         self.mc_liste=self.build_mc()
34         # on crée la liste des types autorisés (liste des noms de mots-clés
35         # simples dans le catalogue de FORMULE)
36         self.l_types_autorises = self.definition.entites.keys()
37         # en plus de la construction traditionnelle des fils de self
38         # il faut pour les FORMULE décortiquer l'expression ...
39         self.type_retourne,self.arguments,self.corps = self.analyse_formule()
40
41     def analyse_formule(self):
42         """
43         Cette méthode décortique l'expression de la FORMULE.
44         Elle retourne 3 valeurs:
45             - le type retourné par la FORMULE
46             - les arguments de la FORMULE
47             - le corps de la FORMULE, cad son expression
48         """
49         if len(self.mc_liste) == 0:
50             # pas de fils pour self --> la FORMULE est incomplète
51             return None,None,None
52         child = self.mc_liste[0] # child est un MCSIMP
53         type_retourne = child.definition.nom
54         valeur = child.getval()
55         # c'est dans valeur que se trouvent la liste des arguments et le corps de la fonction
56         try:
57             l_args,corps = string.split(valeur,'=',1)
58         except:
59             # pas de signe = --> la formule est fausse
60             return type_retourne,None,None
61         l_args = string.strip(l_args)
62         corps = string.strip(corps)
63         return type_retourne,l_args,corps
64
65     def get_nom(self):
66         """
67         Retourne le nom de la FORMULE, cad le nom de la SD si elle existe,
68         la string vide sinon
69         """
70         if self.sd :
71             return self.sd.get_name()
72         else:
73             return ''
74
75     def get_formule(self):
76         """
77         Retourne un tuple décrivant la formule :
78         (nom,type_retourne,arguments,corps)
79         """
80         t,a,c = self.analyse_formule()
81         n = self.get_nom()
82         return (n,t,a,c)
83
84     def verif_arguments(self,arguments = None):
85         """
86         Vérifie si les arguments passés en argument (si aucun prend les arguments courants)
87         sont des arguments valide pour une FORMULE.
88         Retourne :
89             - un booléen, qui vaut 1 si arguments licites, 0 sinon
90             - un message d'erreurs ('' si illicites)
91         """
92         if not arguments :
93             arguments = self.arguments
94         if not arguments :
95             return 0,"Une formule doit avoir au minimum un argument"
96         # il faut au préalable enlever les parenthèses ouvrantes et fermantes
97         # encadrant les arguments
98         arguments = string.strip(arguments)
99         if arguments[0] != '(':
100             return 0,"La liste des arguments d'une formule doit être entre parenthèses : parenthèse ouvrante manquante"
101         if arguments[-1] != ')':
102             return 0,"La liste des arguments d'une formule doit être entre parenthèses : parenthèse fermante manquante"
103         # on peut tester la syntaxe de chaque argument maintenant
104         erreur=''
105         test = 1
106         arguments = arguments[1:-1] # on enlève les parenthèses ouvrante et fermante
107         l_arguments = string.split(arguments,',')
108         for argument in l_arguments:
109             argument = string.strip(argument)
110             try:
111                 typ,nom = string.split(argument,':')
112                 # pas de vérification sur le nom de l'argument
113                 # vérification du type de l'argument
114                 typ = string.strip(typ)
115                 if typ not in self.l_types_autorises :
116                     test = 0
117                     erreur = erreur + "Le type "+typ+" n'est pas un type permis pour "+nom+'\n'
118             except:
119                 # l'argument ne respecte pas la syntaxe : typ_arg : nom_arg
120                 test = 0
121                 erreur = erreur+"Syntaxe argument non valide : "+argument+'\n'
122         return test,erreur
123
124     def verif_corps(self,corps=None,arguments=None):
125         """
126         Cette méthode a pour but de vérifier si le corps de la FORMULE
127         est syntaxiquement correct.
128         Retourne :
129             - un booléen, qui vaut 1 si corps de FORMULE licite, 0 sinon
130             - un message d'erreurs ('' si illicite)
131         """
132         if not corps :
133             corps = self.corps
134         if not arguments :
135             arguments = self.arguments
136         formule=(self.get_nom(),self.type_retourne,arguments,corps)
137         # on récupère la liste des constantes et des autres fonctions prédéfinies
138         # et qui peuvent être utilisées dans le corps de la formule courante
139         l_ctes,l_form = self.jdc.get_parametres_fonctions_avant_etape(self)
140         # on crée un objet vérificateur
141         try:
142             verificateur = self.interpreteur(formule=formule,
143                                              constantes = l_ctes,
144                                              fonctions = l_form)
145         except :
146             traceback.print_exc()
147             return 0,"Impossible de réaliser la vérification de la formule"
148         return verificateur.isvalid(),verificateur.report()
149
150     def verif_nom(self,nom=None):
151         """
152         Vérifie si le nom passé en argument (si aucun prend le nom courant)
153         est un nom valide pour une FORMULE.
154         Retourne :
155             - un booléen, qui vaut 1 si nom licite, 0 sinon
156             - un message d'erreurs ('' si illicite)
157         """
158         if not nom :
159             nom = self.get_nom()
160         if nom == "" :
161             return 0,"Pas de nom donné à la FORMULE"
162         if len(nom) > 8 :
163             return 0,"Un nom de FORMULE ne peut dépasser 8 caractères"
164         sd = self.parent.get_sd_autour_etape(nom,self)
165         if sd :
166             return 0,"Un concept de nom %s existe déjà !" %nom
167         return 1,''
168
169     def verif_type(self,type=None):
170         """
171         Vérifie si le type passé en argument (si aucun prend le type courant)
172         est un type valide pour une FORMULE.
173         Retourne :
174             - un booléen, qui vaut 1 si type licite, 0 sinon
175             - un message d'erreurs ('' si illicite)
176         """
177         if not type:
178             type = self.type_retourne
179         if not type :
180             return 0,"Le type de la valeur retournée n'est pas spécifié"
181         if type not in self.l_types_autorises:
182             return 0,"Une formule ne peut retourner une valeur de type : %s" %type
183         return 1,''
184
185     def verif_formule(self,formule=None):
186         """
187         Vérifie la validité de la formule passée en argument.
188         Cette nouvelle formule est passée sous la forme d'un tuple : (nom,type_retourne,arguments,corps)
189         Si aucune formule passée, prend les valeurs courantes de la formule
190         Retourne :
191             - un booléen, qui vaut 1 si formule licite, 0 sinon
192             - un message d'erreurs ('' si illicite)
193         """
194         if not formule :
195             formule = (None,None,None,None)
196         test_nom,erreur_nom = self.verif_nom(formule[0])
197         test_type,erreur_type = self.verif_type(formule[1])
198         if formule[2]:
199             args = '('+formule[2]+')'
200         else:
201             args = None
202         test_arguments,erreur_arguments = self.verif_arguments(args)
203         test_corps,erreur_corps = self.verif_corps(corps = formule[3], arguments = args)
204         # test global = produit des tests partiels
205         test = test_nom*test_type*test_arguments*test_corps
206         # message d'erreurs global = concaténation des messages partiels
207         erreur = ''
208         if not test :
209             for mess in (erreur_nom,erreur_type,erreur_arguments,erreur_corps):
210                 erreur = erreur+(len(mess) > 0)*'\n'+mess
211         return test,erreur
212
213     def update(self,formule):
214         """
215         Méthode externe.
216         Met à jour les champs nom, type_retourne,arguments et corps de la FORMULE
217         par les nouvelles valeurs passées dans le tuple formule.
218         On stocke les valeurs SANS vérifications.
219         """
220         self.init_modif()
221         self.type_retourne = formule[1]
222         self.arguments = '('+formule[2]+')'
223         self.corps = formule[3]
224         # il faut ajouter le mot-clé simple correspondant dans mc_liste
225         # pour cela on utilise la méthode générale build_mc
226         # du coup on est obligé de modifier le dictionnaire valeur de self ...
227         self.valeur = {}
228         self.valeur[self.type_retourne] = self.arguments+' = ' + self.corps
229         self.McBuild()
230         sd = self.get_sd_prod()
231         if sd:
232             sd.nom = formule[0]
233
234     def active(self):
235         """
236         Rend l'etape courante active.
237         Il faut ajouter la formule au contexte global du JDC
238         """
239         self.actif = 1
240         nom = self.get_nom()
241         if nom == '' : return
242         try:
243             self.jdc.append_fonction(self.sd)
244         except:
245             pass
246
247     def inactive(self):
248         """
249         Rend l'etape courante inactive
250         Il faut supprimer la formule du contexte global du JDC
251         """
252         self.actif = 0
253         if not self.sd : return
254         self.jdc.del_fonction(self.sd)
255
256     def delete_concept(self,sd):
257         """ 
258          Inputs :
259            - sd=concept detruit
260          Fonction :
261          Mettre a jour les mots cles de l etape et eventuellement le concept produit si reuse
262          suite à la disparition du concept sd
263          Seuls les mots cles simples MCSIMP font un traitement autre que de transmettre aux fils,
264          sauf les objets FORM_ETAPE qui doivent vérifier que le concept détruit n'est pas 
265          utilisé dans le corps de la fonction
266         """
267         self.init_modif()
268          
269     def replace_concept(self,old_sd,sd):
270         """
271          Inputs :
272            - old_sd=concept remplace
273            - sd = nouveau concept
274          Fonction :
275          Les objets FORM_ETAPE devraient vérifier que le concept remplacé n'est pas
276          utilisé dans le corps de la fonction
277         """
278         self.init_modif()
279
280 class FORM(MACRO):
281    class_instance=FORM_ETAPE
282