]> SALOME platform Git repositories - tools/eficas.git/blob - generator/generator_python.py
Salome HOME
Fiche ay_dieses
[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       # modification pour répondre à la demande de C. Durand, d'éviter
209       # l'ajout systématique d'un dièse, à la suite du commentaire
210       # Dans la chaine de caracteres obj.valeur, on supprime le dernier
211       # saut de ligne
212       sans_saut = re.sub("\n$","",obj.valeur)
213       l_lignes = string.split(sans_saut,'\n')
214       txt=''
215       for ligne in l_lignes:
216         txt = txt + '#'+ligne+'\n'
217
218       # suppression du dernier saut de ligne
219       txt = re.sub("\n$","",txt)
220       return txt
221
222    def generPARAMETRE_EVAL(self,obj):
223       """
224          Cette méthode convertit un PARAMETRE_EVAL
225          en une liste de chaines de caractères à la syntaxe python
226       """
227       if obj.valeur == None:
228          return obj.nom + ' = None ;\n'
229       else:
230          return obj.nom + ' = '+ self.generator(obj.valeur) +';\n'
231
232    def generPARAMETRE(self,obj):
233       """
234          Cette méthode convertit un PARAMETRE
235          en une liste de chaines de caractères à la syntaxe python
236       """
237       if type(obj.valeur) == types.StringType:
238         return obj.nom + " = '" + obj.valeur + "';\n"
239       else:
240         return obj.nom + ' = ' + str(obj.valeur) + ';\n'
241
242    def generETAPE_NIVEAU(self,obj):
243       """
244          Cette méthode convertit une étape niveau
245          en une liste de chaines de caractères à la syntaxe python
246       """
247       l=[]
248       if obj.etapes_niveaux == []:
249         for etape in obj.etapes:
250           l.append(self.generator(etape))
251       else:
252         for etape_niveau in obj.etapes_niveaux:
253           l.extend(self.generator(etape_niveau))
254       return l
255
256    def generETAPE(self,obj):
257       """
258          Cette méthode convertit une étape
259          en une liste de chaines de caractères à la syntaxe python
260       """
261       try:
262         sdname= self.generator(obj.sd)
263       except:
264         sdname='sansnom'
265       l=[]
266       label=sdname + '='+obj.definition.nom+'('
267       l.append(label)
268       if obj.reuse != None :
269         str = 'reuse ='+ self.generator(obj.reuse) + ','
270         l.append(str)
271       for v in obj.mc_liste:
272         if isinstance(v,MCBLOC) :
273           liste=self.generator(v)
274           for mocle in liste :
275             l.append(mocle)
276         elif isinstance(v,MCSIMP) :
277           text=self.generator(v)
278           l.append(v.nom+'='+text)
279         else:
280           # MCFACT ou MCList
281           liste=self.generator(v)
282           liste[0]=v.nom+'='+liste[0]
283           l.append(liste)
284       if len(l) == 1:
285         l[0]=label+');'
286       else :
287         l.append(');')
288       return l
289
290    def generFORM_ETAPE(self,obj):
291         """
292             Méthode particulière pour les objets de type FORMULE
293         """
294         l=[]
295         nom = obj.get_nom()
296         if nom == '' : nom = 'sansnom'
297         if len(obj.mc_liste)>0:
298             l.append(nom + ' = FORMULE(')
299             s=obj.type_retourne + ' = ' + "'''" + obj.arguments + ' = ' + obj.corps+"'''"
300             l.append(s)
301             l.append(');')
302         else:
303             l.append(nom+' = FORMULE();')
304         return l
305
306    def generMACRO_ETAPE(self,obj):
307       """
308          Cette méthode convertit une macro-étape
309          en une liste de chaines de caractères à la syntaxe python
310       """
311       if obj.definition.nom == 'FORMULE' : return self.gen_formule(obj)
312       try:
313         if obj.sd == None:
314           sdname=''
315         else:
316           sdname= self.generator(obj.sd)+'='
317       except:
318         sdname='sansnom='
319       l=[]
320       label = sdname + obj.definition.nom+'('
321       l.append(label)
322       if obj.reuse != None:
323          # XXX faut il la virgule ou pas ????
324          str = "reuse =" + self.generator(obj.reuse) + ','
325          l.append(str)
326       for v in obj.mc_liste:
327         if isinstance(v,MCBLOC) :
328           liste=self.generator(v)
329           for mocle in liste :
330             l.append(mocle)
331         elif isinstance(v,MCSIMP) :
332           text=self.generator(v)
333           l.append(v.nom+'='+text)
334         else:
335           # MCFACT ou MCList
336           liste=self.generator(v)
337           liste[0]=v.nom+'='+liste[0]
338           l.append(liste)
339
340       if len(l) == 1:
341         l[0]=label+');'
342       else :
343         l.append(');')
344       return l
345
346    def gen_formule(self,obj):
347       """
348            Méthode particuliere aux objets de type FORMULE
349       """
350       try:
351         if obj.sd == None:
352           sdname=''
353         else:
354           sdname= self.generator(obj.sd)
355       except:
356         sdname='sansnom'
357       l=[]
358       label=sdname + ' = FORMULE('
359       l.append(label)
360       for v in obj.mc_liste:
361         s=''
362         s= v.nom+':'+sdname+'('+v.valeur+')'
363         l.append(s)
364       if len(l) == 1:
365         l[0]=label+');'
366       else :
367         l.append(');')
368       return l
369
370    def generPROC_ETAPE(self,obj):
371       """
372          Cette méthode convertit une PROC étape
373          en une liste de chaines de caractères à la syntaxe python
374       """
375       l=[]
376       label=obj.definition.nom+'('
377       l.append(label)
378       for v in obj.mc_liste:
379         if isinstance(v,MCBLOC) :
380           liste=self.generator(v)
381           for mocle in liste :
382             l.append(mocle)
383         elif isinstance(v,MCSIMP) :
384           text=self.generator(v)
385           l.append(v.nom+'='+text)
386         else:
387           # MCFACT ou MCList
388           liste=self.generator(v)
389           liste[0]=v.nom+'='+liste[0]
390           l.append(liste)
391
392       if len(l) == 1:
393         l[0]=label+');'
394       else :
395         l.append(');')
396       return l
397
398    def generASSD(self,obj):
399       """
400           Convertit un objet dérivé d'ASSD en une chaine de caractères à la
401           syntaxe python
402       """
403       return obj.get_name()
404
405    def generMCFACT(self,obj):
406       """
407           Convertit un objet MCFACT en une liste de chaines de caractères à la
408           syntaxe python
409       """
410       l=[]
411       l.append('_F(')
412       for v in obj.mc_liste:
413          if not isinstance(v,MCSIMP) and not isinstance (v,MCBLOC) :
414            # on est en présence d'une entite composée : on récupère une liste
415            liste=self.generator(v)
416            liste[0]=v.nom+'='+liste[0]
417            l.append(liste)
418          elif isinstance(v,MCBLOC):
419            liste=self.generator(v)
420            for arg in liste :
421              l.append(arg)
422          else:
423            # on est en présence d'un MCSIMP : on récupère une string
424            text =self.generator(v)
425            l.append(v.nom+'='+text)
426       # il faut être plus subtil dans l'ajout de la virgule en différenciant 
427       # le cas où elle est obligatoire (si self a des frères cadets 
428       # dans self.parent) ou non
429       # (cas où self est seul ou le benjamin de self.parent)
430       l.append('),')
431       return l
432
433    def generMCList(self,obj):
434       """
435           Convertit un objet MCList en une liste de chaines de caractères à la
436           syntaxe python
437       """
438       l=[]
439       str =  '('
440       l.append(str)
441       for mcfact in obj.data:
442          l.append(self.generator(mcfact))
443       l.append('),')
444       return l
445
446    def generMCBLOC(self,obj):
447       """
448           Convertit un objet MCBLOC en une liste de chaines de caractères à la
449           syntaxe python
450       """
451       l=[]
452       for v in obj.mc_liste:
453         if isinstance(v,MCBLOC) :
454           liste=self.generator(v)
455           for mocle in liste :
456             l.append(mocle)
457         elif isinstance(v,MCList):
458           liste=self.generator(v)
459           liste[0]=v.nom+'='+liste[0]
460           for mocle in liste :
461             l.append(mocle)
462         else:
463           data=self.generator(v)
464           if type(data) == types.ListType:
465             data[0]=v.nom+'='+data[0]
466           else:
467             data=v.nom+'='+data
468           l.append(data)
469       return l
470
471    def generMCSIMP(self,obj) :
472       """
473           Convertit un objet MCSIMP en une liste de chaines de caractères à la
474           syntaxe python
475       """
476       if type(obj.valeur) in (types.TupleType,types.ListType) :
477         s = ''
478         for val in obj.valeur :
479           if type(val) == types.InstanceType :
480             if hasattr(obj.etape,'sdprods'):
481                if val in obj.etape.sdprods :
482                   s = s + "CO('"+ self.generator(val) +"')"
483                elif val.__class__.__name__ == 'CO':
484                   s = s + "CO('"+ self.generator(val) +"')"
485                else:
486                   s = s + self.generator(val)
487             elif isinstance(val,PARAMETRE):
488                # il ne faut pas prendre la string que retourne gener
489                # mais seulement le nom dans le cas d'un paramètre
490                s = s + val.nom
491             else:
492                s = s + self.generator(val)
493           elif type(val) == types.FloatType :
494             # Pour un flottant on utilise str qui a une precision de
495             # "seulement" 12 chiffres : evite les flottants du genre 0.599999999999998
496             s = s + str(val)
497           else :
498             s = s + `val`
499           s = s + ','
500         if len(obj.valeur) > 1:
501            s = '(' + s + '),'
502       else :
503         val=obj.valeur
504         if type(val) == types.InstanceType :
505           if hasattr(obj.etape,'sdprods'):
506              if val in obj.etape.sdprods :
507                 s = "CO('"+ self.generator(val) +"')"
508              elif val.__class__.__name__ == 'CO':
509                 s = "CO('"+ self.generator(val) +"')"
510              else:
511                 s = self.generator(val)
512           elif isinstance(val,PARAMETRE):
513              # il ne faut pas prendre la string que retourne gener
514              # mais seulement le nom dans le cas d'un paramètre
515              s = val.nom
516           else:
517              s = self.generator(val)
518         elif type(val) == types.FloatType :
519           #s = repr_float(val)
520           s = str(val)
521         else :
522           s = `val`
523         s= s + ','
524       return s
525
526