Salome HOME
CCAR : Suppression des surcharges de methodes faites pour Eficas1.5
[tools/eficas.git] / generator / generator_python.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     Ce module contient le plugin generateur de fichier au format 
22     python pour EFICAS.
23
24 """
25 import traceback
26 import types,string,re
27
28 from Noyau import N_CR
29 from Noyau.N_utils import repr_float
30 from Accas import ETAPE,PROC_ETAPE,MACRO_ETAPE,ETAPE_NIVEAU,JDC,FORM_ETAPE
31 from Accas import MCSIMP,MCFACT,MCBLOC,MCList,EVAL
32 from Accas import GEOM,ASSD,MCNUPLET
33 from Accas import COMMENTAIRE,PARAMETRE, PARAMETRE_EVAL,COMMANDE_COMM
34 from Formatage import Formatage
35
36 def entryPoint():
37    """
38        Retourne les informations nécessaires pour le chargeur de plugins
39
40        Ces informations sont retournées dans un dictionnaire
41    """
42    return {
43         # Le nom du plugin
44           'name' : 'python',
45         # La factory pour créer une instance du plugin
46           'factory' : PythonGenerator,
47           }
48
49
50 class PythonGenerator:
51    """
52        Ce generateur parcourt un objet de type JDC et produit
53        un fichier au format python 
54
55        L'acquisition et le parcours sont réalisés par la méthode
56        generator.gener(objet_jdc,format)
57
58        L'écriture du fichier au format ini par appel de la méthode
59        generator.writefile(nom_fichier)
60
61        Ses caractéristiques principales sont exposées dans des attributs 
62        de classe :
63          - extensions : qui donne une liste d'extensions de fichier préconisées
64
65    """
66    # Les extensions de fichier préconisées
67    extensions=('.comm',)
68
69    def __init__(self,cr=None):
70       # Si l'objet compte-rendu n'est pas fourni, on utilise le compte-rendu standard
71       if cr :
72          self.cr=cr
73       else:
74          self.cr=N_CR.CR(debut='CR generateur format python pour python',
75                          fin='fin CR format python pour python')
76       # Le texte au format python est stocké dans l'attribut text
77       self.text=''
78
79    def writefile(self,filename):
80       fp=open(filename,'w')
81       fp.write(self.text)
82       fp.close()
83
84    def gener(self,obj,format='brut'):
85       """
86           Retourne une représentation du JDC obj sous une
87           forme qui est paramétrée par format.
88           Si format vaut 'brut', retourne une liste de listes de ...
89           Si format vaut 'standard', retourne un texte obtenu par concaténation de la liste
90           Si format vaut 'beautifie', retourne le meme texte beautifié
91       """
92       liste= self.generator(obj)
93       if format == 'brut':
94          self.text=liste
95       elif format == 'standard':
96          self.text=string.join(liste)
97       elif format == 'beautifie':
98          jdc_formate = Formatage(liste,mode='.py')
99          self.text=jdc_formate.formate_jdc()
100       else:
101          raise "Format pas implémenté : "+format
102       return self.text
103
104    def generator(self,obj):
105       """
106          Cette methode joue un role d'aiguillage en fonction du type de obj
107          On pourrait utiliser les méthodes accept et visitxxx à la 
108          place (dépend des gouts !!!)
109       """
110       # ATTENTION a l'ordre des tests : il peut avoir de l'importance (héritage)
111       if isinstance(obj,PROC_ETAPE):
112          return self.generPROC_ETAPE(obj)
113       elif isinstance(obj,MACRO_ETAPE):
114          return self.generMACRO_ETAPE(obj)
115       elif isinstance(obj,FORM_ETAPE):
116          return self.generFORM_ETAPE(obj)
117       elif isinstance(obj,ETAPE):
118          return self.generETAPE(obj)
119       elif isinstance(obj,MCFACT):
120          return self.generMCFACT(obj)
121       elif isinstance(obj,MCList):
122          return self.generMCList(obj)
123       elif isinstance(obj,MCBLOC):
124          return self.generMCBLOC(obj)
125       elif isinstance(obj,MCSIMP):
126          return self.generMCSIMP(obj)
127       elif isinstance(obj,ASSD):
128          return self.generASSD(obj)
129       elif isinstance(obj,ETAPE_NIVEAU):
130          return self.generETAPE_NIVEAU(obj)
131       elif isinstance(obj,COMMENTAIRE):
132          return self.generCOMMENTAIRE(obj)
133       # Attention doit etre placé avant PARAMETRE (raison : héritage)
134       elif isinstance(obj,PARAMETRE_EVAL):
135          return self.generPARAMETRE_EVAL(obj)
136       elif isinstance(obj,PARAMETRE):
137          return self.generPARAMETRE(obj)
138       elif isinstance(obj,EVAL):
139          return self.generEVAL(obj)
140       elif isinstance(obj,COMMANDE_COMM):
141          return self.generCOMMANDE_COMM(obj)
142       elif isinstance(obj,JDC):
143          return self.generJDC(obj)
144       elif isinstance(obj,MCNUPLET):
145          return self.generMCNUPLET(obj)
146       else:
147          raise "Type d'objet non prévu",obj
148
149    def generJDC(self,obj):
150       """
151          Cette méthode convertit un objet JDC en une liste de chaines de
152          caractères à la syntaxe python
153       """
154       l=[]
155       if obj.definition.l_niveaux == ():
156          # Il n'y a pas de niveaux
157          for etape in obj.etapes:
158             l.append(self.generator(etape))
159       else:
160          # Il y a des niveaux
161          for etape_niveau in obj.etapes_niveaux:
162             l.extend(self.generator(etape_niveau))
163       if l != [] :
164          # Si au moins une étape, on ajoute le retour chariot sur la dernière étape
165          if type(l[-1])==types.ListType:
166             l[-1][-1] = l[-1][-1]+'\n'
167          elif type(l[-1])==types.StringType:
168             l[-1] = l[-1]+'\n'
169       return l
170
171    def generMCNUPLET(self,obj):
172       """ 
173           Méthode générant une représentation de self permettant son ecriture
174           dans le format python
175       """
176       l=[]
177       l.append('(')
178       for v in obj.mc_liste:
179         text = re.sub(".*=","",self.generator(v))
180         l.append(text)
181       l.append('),')
182       return l
183
184    def generCOMMANDE_COMM(self,obj):
185       """
186          Cette méthode convertit un COMMANDE_COMM
187          en une liste de chaines de caractères à la syntaxe python
188       """
189       l_lignes = string.split(obj.valeur,'\n')
190       txt=''
191       for ligne in l_lignes:
192           txt = txt + '##'+ligne+'\n'
193       return txt
194
195    def generEVAL(self,obj):
196       """
197          Cette méthode convertit un EVAL
198          en une liste de chaines de caractères à la syntaxe python
199       """
200       return 'EVAL("""'+ obj.valeur +'""")'
201
202    def generCOMMENTAIRE(self,obj):
203       """
204          Cette méthode convertit un COMMENTAIRE
205          en une liste de chaines de caractères à la syntaxe python
206       """
207       # modification pour répondre à la demande de C. Durand, d'éviter
208       # l'ajout systématique d'un dièse, à la suite du commentaire
209       # Dans la chaine de caracteres obj.valeur, on supprime le dernier
210       # saut de ligne
211       sans_saut = re.sub("\n$","",obj.valeur)
212       l_lignes = string.split(sans_saut,'\n')
213       txt=''
214       for ligne in l_lignes:
215         txt = txt + '#'+ligne+'\n'
216
217       # suppression du dernier saut de ligne
218       txt = re.sub("\n$","",txt)
219       return txt
220
221    def generPARAMETRE_EVAL(self,obj):
222       """
223          Cette méthode convertit un PARAMETRE_EVAL
224          en une liste de chaines de caractères à la syntaxe python
225       """
226       if obj.valeur == None:
227          return obj.nom + ' = None ;\n'
228       else:
229          return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
230
231    def generPARAMETRE(self,obj):
232       """
233          Cette méthode convertit un PARAMETRE
234          en une liste de chaines de caractères à la syntaxe python
235       """
236       if type(obj.valeur) == types.StringType:
237         return obj.nom + " = '" + obj.valeur + "';\n"
238       else:
239         return obj.nom + ' = ' + str(obj.valeur) + ';\n'
240
241    def generETAPE_NIVEAU(self,obj):
242       """
243          Cette méthode convertit une étape niveau
244          en une liste de chaines de caractères à la syntaxe python
245       """
246       l=[]
247       if obj.etapes_niveaux == []:
248         for etape in obj.etapes:
249           l.append(self.generator(etape))
250       else:
251         for etape_niveau in obj.etapes_niveaux:
252           l.extend(self.generator(etape_niveau))
253       return l
254
255    def generETAPE(self,obj):
256       """
257          Cette méthode convertit une étape
258          en une liste de chaines de caractères à la syntaxe python
259       """
260       try:
261         sdname= self.generator(obj.sd)
262       except:
263         sdname='sansnom'
264       l=[]
265       label=sdname + '='+obj.definition.nom+'('
266       l.append(label)
267       if obj.reuse != None :
268         str = 'reuse ='+ self.generator(obj.reuse) + ','
269         l.append(str)
270       for v in obj.mc_liste:
271         if isinstance(v,MCBLOC) :
272           liste=self.generator(v)
273           for mocle in liste :
274             l.append(mocle)
275         elif isinstance(v,MCSIMP) :
276           text=self.generator(v)
277           l.append(v.nom+'='+text)
278         else:
279           # MCFACT ou MCList
280           liste=self.generator(v)
281           liste[0]=v.nom+'='+liste[0]
282           l.append(liste)
283       if len(l) == 1:
284         l[0]=label+');'
285       else :
286         l.append(');')
287       return l
288
289    def generFORM_ETAPE(self,obj):
290         """
291             Méthode particulière pour les objets de type FORMULE
292         """
293         l=[]
294         nom = obj.get_nom()
295         if nom == '' : nom = 'sansnom'
296         if len(obj.mc_liste)>0:
297             l.append(nom + ' = FORMULE(')
298             s=obj.type_retourne + ' = ' + "'''" + obj.arguments + ' = ' + obj.corps+"'''"
299             l.append(s)
300             l.append(');')
301         else:
302             l.append(nom+' = FORMULE();')
303         return l
304
305    def generMACRO_ETAPE(self,obj):
306       """
307          Cette méthode convertit une macro-étape
308          en une liste de chaines de caractères à la syntaxe python
309       """
310       if obj.definition.nom == 'FORMULE' : return self.gen_formule(obj)
311       try:
312         if obj.sd == None:
313           sdname=''
314         else:
315           sdname= self.generator(obj.sd)+'='
316       except:
317         sdname='sansnom='
318       l=[]
319       label = sdname + obj.definition.nom+'('
320       l.append(label)
321       if obj.reuse != None:
322          # XXX faut il la virgule ou pas ????
323          str = "reuse =" + self.generator(obj.reuse) + ','
324          l.append(str)
325       for v in obj.mc_liste:
326         if isinstance(v,MCBLOC) :
327           liste=self.generator(v)
328           for mocle in liste :
329             l.append(mocle)
330         elif isinstance(v,MCSIMP) :
331           text=self.generator(v)
332           l.append(v.nom+'='+text)
333         else:
334           # MCFACT ou MCList
335           liste=self.generator(v)
336           liste[0]=v.nom+'='+liste[0]
337           l.append(liste)
338
339       if len(l) == 1:
340         l[0]=label+');'
341       else :
342         l.append(');')
343       return l
344
345    def gen_formule(self,obj):
346       """
347            Méthode particuliere aux objets de type FORMULE
348       """
349       try:
350         if obj.sd == None:
351           sdname=''
352         else:
353           sdname= self.generator(obj.sd)
354       except:
355         sdname='sansnom'
356       l=[]
357       label=sdname + ' = FORMULE('
358       l.append(label)
359       for v in obj.mc_liste:
360         s=''
361         s= v.nom+':'+sdname+'('+v.valeur+')'
362         l.append(s)
363       if len(l) == 1:
364         l[0]=label+');'
365       else :
366         l.append(');')
367       return l
368
369    def generPROC_ETAPE(self,obj):
370       """
371          Cette méthode convertit une PROC étape
372          en une liste de chaines de caractères à la syntaxe python
373       """
374       l=[]
375       label=obj.definition.nom+'('
376       l.append(label)
377       for v in obj.mc_liste:
378         if isinstance(v,MCBLOC) :
379           liste=self.generator(v)
380           for mocle in liste :
381             l.append(mocle)
382         elif isinstance(v,MCSIMP) :
383           text=self.generator(v)
384           l.append(v.nom+'='+text)
385         else:
386           # MCFACT ou MCList
387           liste=self.generator(v)
388           liste[0]=v.nom+'='+liste[0]
389           l.append(liste)
390
391       if len(l) == 1:
392         l[0]=label+');'
393       else :
394         l.append(');')
395       return l
396
397    def generASSD(self,obj):
398       """
399           Convertit un objet dérivé d'ASSD en une chaine de caractères à la
400           syntaxe python
401       """
402       return obj.get_name()
403
404    def generMCFACT(self,obj):
405       """
406           Convertit un objet MCFACT en une liste de chaines de caractères à la
407           syntaxe python
408       """
409       l=[]
410       l.append('_F(')
411       for v in obj.mc_liste:
412          if not isinstance(v,MCSIMP) and not isinstance (v,MCBLOC) :
413            # on est en présence d'une entite composée : on récupère une liste
414            liste=self.generator(v)
415            liste[0]=v.nom+'='+liste[0]
416            l.append(liste)
417          elif isinstance(v,MCBLOC):
418            liste=self.generator(v)
419            for arg in liste :
420              l.append(arg)
421          else:
422            # on est en présence d'un MCSIMP : on récupère une string
423            text =self.generator(v)
424            l.append(v.nom+'='+text)
425       # il faut être plus subtil dans l'ajout de la virgule en différenciant 
426       # le cas où elle est obligatoire (si self a des frères cadets 
427       # dans self.parent) ou non
428       # (cas où self est seul ou le benjamin de self.parent)
429       l.append('),')
430       return l
431
432    def generMCList(self,obj):
433       """
434           Convertit un objet MCList en une liste de chaines de caractères à la
435           syntaxe python
436       """
437       l=[]
438       str =  '('
439       l.append(str)
440       for mcfact in obj.data:
441          l.append(self.generator(mcfact))
442       l.append('),')
443       return l
444
445    def generMCBLOC(self,obj):
446       """
447           Convertit un objet MCBLOC en une liste de chaines de caractères à la
448           syntaxe python
449       """
450       l=[]
451       for v in obj.mc_liste:
452         if isinstance(v,MCBLOC) :
453           liste=self.generator(v)
454           for mocle in liste :
455             l.append(mocle)
456         elif isinstance(v,MCList):
457           liste=self.generator(v)
458           liste[0]=v.nom+'='+liste[0]
459           for mocle in liste :
460             l.append(mocle)
461         else:
462           data=self.generator(v)
463           if type(data) == types.ListType:
464             data[0]=v.nom+'='+data[0]
465           else:
466             data=v.nom+'='+data
467           l.append(data)
468       return l
469
470    def generMCSIMP(self,obj) :
471       """
472           Convertit un objet MCSIMP en une liste de chaines de caractères à la
473           syntaxe python
474       """
475       if type(obj.valeur) in (types.TupleType,types.ListType) :
476         s = ''
477         for val in obj.valeur :
478           if type(val) == types.InstanceType :
479             if hasattr(obj.etape,'sdprods'):
480                if val in obj.etape.sdprods :
481                   s = s + "CO('"+ self.generator(val) +"')"
482                elif val.__class__.__name__ == 'CO':
483                   s = s + "CO('"+ self.generator(val) +"')"
484                else:
485                   s = s + self.generator(val)
486             elif isinstance(val,PARAMETRE):
487                # il ne faut pas prendre la string que retourne gener
488                # mais seulement le nom dans le cas d'un paramètre
489                s = s + val.nom
490             else:
491                s = s + self.generator(val)
492           elif type(val) == types.FloatType :
493             # Pour un flottant on utilise str qui a une precision de
494             # "seulement" 12 chiffres : evite les flottants du genre 0.599999999999998
495             s = s + str(val)
496           else :
497             s = s + `val`
498           s = s + ','
499         if len(obj.valeur) > 1:
500            s = '(' + s + '),'
501       else :
502         val=obj.valeur
503         if type(val) == types.InstanceType :
504           if hasattr(obj.etape,'sdprods'):
505              if val in obj.etape.sdprods :
506                 s = "CO('"+ self.generator(val) +"')"
507              elif val.__class__.__name__ == 'CO':
508                 s = "CO('"+ self.generator(val) +"')"
509              else:
510                 s = self.generator(val)
511           elif isinstance(val,PARAMETRE):
512              # il ne faut pas prendre la string que retourne gener
513              # mais seulement le nom dans le cas d'un paramètre
514              s = val.nom
515           else:
516              s = self.generator(val)
517         elif type(val) == types.FloatType :
518           #s = repr_float(val)
519           s = str(val)
520         else :
521           s = `val`
522         s= s + ','
523       return s
524
525