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