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