X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=generator%2Fgenerator_python.py;h=e49ca579150ef653b26290e4a5b5a4ab6148c921;hb=4147504b4d035ba277d39be61779ed638405c48a;hp=212efca30aa4d13c2618d957cabb85ef42931a25;hpb=757737ec737f71d6c88050a6ce0a12d6aaaac30c;p=tools%2Feficas.git diff --git a/generator/generator_python.py b/generator/generator_python.py index 212efca3..e49ca579 100644 --- a/generator/generator_python.py +++ b/generator/generator_python.py @@ -1,3 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2007-2013 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# """ Ce module contient le plugin generateur de fichier au format python pour EFICAS. @@ -8,22 +27,26 @@ import types,string,re from Noyau import N_CR from Noyau.N_utils import repr_float -from Accas import ETAPE,PROC_ETAPE,MACRO_ETAPE,ETAPE_NIVEAU,JDC,FORM_ETAPE -from Accas import MCSIMP,MCFACT,MCBLOC,MCList,EVAL -from Accas import GEOM,ASSD,MCNUPLET -from Accas import COMMENTAIRE,PARAMETRE, PARAMETRE_EVAL,COMMANDE_COMM -from Formatage import Formatage +import Accas +import Extensions +from Extensions.parametre import ITEM_PARAMETRE +from Formatage import Formatage +from Formatage import FormatageLigne +from Extensions.param2 import Formula +from Extensions.eficas_exception import EficasException +from Extensions.i18n import tr + def entryPoint(): """ - Retourne les informations nécessaires pour le chargeur de plugins + Retourne les informations necessaires pour le chargeur de plugins - Ces informations sont retournées dans un dictionnaire + Ces informations sont retournees dans un dictionnaire """ return { # Le nom du plugin 'name' : 'python', - # La factory pour créer une instance du plugin + # La factory pour creer une instance du plugin 'factory' : PythonGenerator, } @@ -33,19 +56,18 @@ class PythonGenerator: Ce generateur parcourt un objet de type JDC et produit un fichier au format python - L'acquisition et le parcours sont réalisés par la méthode + L'acquisition et le parcours sont realises par la methode generator.gener(objet_jdc,format) - L'écriture du fichier au format ini par appel de la méthode + L'ecriture du fichier au format ini par appel de la methode generator.writefile(nom_fichier) - Ses caractéristiques principales sont exposées dans des attributs + Ses caracteristiques principales sont exposees dans des attributs de classe : - - - extensions : qui donne une liste d'extensions de fichier préconisées + - extensions : qui donne une liste d'extensions de fichier preconisees """ - # Les extensions de fichier préconisées + # Les extensions de fichier preconisees extensions=('.comm',) def __init__(self,cr=None): @@ -55,22 +77,25 @@ class PythonGenerator: else: self.cr=N_CR.CR(debut='CR generateur format python pour python', fin='fin CR format python pour python') - # Le texte au format python est stocké dans l'attribut text + # Le texte au format python est stocke dans l'attribut text self.text='' + self.appli=None def writefile(self,filename): fp=open(filename,'w') fp.write(self.text) fp.close() - def gener(self,obj,format='brut'): + def gener(self,obj,format='brut',config=None,appli=None): """ - Retourne une représentation du JDC obj sous une - forme qui est paramétrée par format. + Retourne une representation du JDC obj sous une + forme qui est parametree par format. Si format vaut 'brut', retourne une liste de listes de ... - Si format vaut 'standard', retourne un texte obtenu par concaténation de la liste - Si format vaut 'beautifie', retourne le meme texte beautifié + Si format vaut 'standard', retourne un texte obtenu par concatenation de la liste + Si format vaut 'beautifie', retourne le meme texte beautifie """ + self.appli=obj.get_jdc_root().appli + #self.appli=obj.appli liste= self.generator(obj) if format == 'brut': self.text=liste @@ -79,59 +104,67 @@ class PythonGenerator: elif format == 'beautifie': jdc_formate = Formatage(liste,mode='.py') self.text=jdc_formate.formate_jdc() + elif format == 'Ligne': + jdc_formate = FormatageLigne(liste,mode='.py') + self.text=jdc_formate.formate_jdc() else: - raise "Format pas implémenté : "+format + raise EficasException(tr("Format non implemente ") +format) return self.text def generator(self,obj): """ Cette methode joue un role d'aiguillage en fonction du type de obj - On pourrait utiliser les méthodes accept et visitxxx à la - place (dépend des gouts !!!) + On pourrait utiliser les methodes accept et visitxxx a la + place (depend des gouts !!!) """ - # ATTENTION a l'ordre des tests : il peut avoir de l'importance (héritage) - if isinstance(obj,PROC_ETAPE): + # ATTENTION a l'ordre des tests : il peut avoir de l'importance (heritage) + if isinstance(obj,Accas.PROC_ETAPE): return self.generPROC_ETAPE(obj) - elif isinstance(obj,MACRO_ETAPE): - return self.generMACRO_ETAPE(obj) - elif isinstance(obj,FORM_ETAPE): + # Attention doit etre place avant MACRO (raison : heritage) + elif isinstance(obj,Accas.FORM_ETAPE): return self.generFORM_ETAPE(obj) - elif isinstance(obj,ETAPE): + elif isinstance(obj,Accas.MACRO_ETAPE): + return self.generMACRO_ETAPE(obj) + elif isinstance(obj,Accas.ETAPE): return self.generETAPE(obj) - elif isinstance(obj,MCFACT): + elif isinstance(obj,Accas.MCFACT): return self.generMCFACT(obj) - elif isinstance(obj,MCList): + elif isinstance(obj,Accas.MCList): return self.generMCList(obj) - elif isinstance(obj,MCBLOC): + elif isinstance(obj,Accas.MCBLOC): return self.generMCBLOC(obj) - elif isinstance(obj,MCSIMP): + elif isinstance(obj,Accas.MCSIMP): return self.generMCSIMP(obj) - elif isinstance(obj,ASSD): + elif isinstance(obj,Accas.ASSD): return self.generASSD(obj) - elif isinstance(obj,ETAPE_NIVEAU): + elif isinstance(obj,Accas.ETAPE_NIVEAU): return self.generETAPE_NIVEAU(obj) - elif isinstance(obj,COMMENTAIRE): + elif isinstance(obj,Accas.COMMENTAIRE): return self.generCOMMENTAIRE(obj) - # Attention doit etre placé avant PARAMETRE (raison : héritage) - elif isinstance(obj,PARAMETRE_EVAL): + # Attention doit etre place avant PARAMETRE (raison : heritage) + elif isinstance(obj,Accas.PARAMETRE_EVAL): return self.generPARAMETRE_EVAL(obj) - elif isinstance(obj,PARAMETRE): + elif isinstance(obj,Accas.PARAMETRE): return self.generPARAMETRE(obj) - elif isinstance(obj,EVAL): + elif isinstance(obj,Accas.EVAL): return self.generEVAL(obj) - elif isinstance(obj,COMMANDE_COMM): + elif isinstance(obj,Accas.COMMANDE_COMM): return self.generCOMMANDE_COMM(obj) - elif isinstance(obj,JDC): + elif isinstance(obj,Accas.JDC): return self.generJDC(obj) - elif isinstance(obj,MCNUPLET): + elif isinstance(obj,Accas.MCNUPLET): return self.generMCNUPLET(obj) + elif isinstance(obj,ITEM_PARAMETRE): + return self.generITEM_PARAMETRE(obj) + elif isinstance(obj,Formula): + return self.generFormula(obj) else: - raise "Type d'objet non prévu",obj + raise EficasException(tr("Type d'objet non prevu") +obj) def generJDC(self,obj): """ - Cette méthode convertit un objet JDC en une liste de chaines de - caractères à la syntaxe python + Cette methode convertit un objet JDC en une liste de chaines de + caracteres a la syntaxe python """ l=[] if obj.definition.l_niveaux == (): @@ -143,7 +176,7 @@ class PythonGenerator: for etape_niveau in obj.etapes_niveaux: l.extend(self.generator(etape_niveau)) if l != [] : - # Si au moins une étape, on ajoute le retour chariot sur la dernière étape + # Si au moins une etape, on ajoute le retour chariot sur la derniere etape if type(l[-1])==types.ListType: l[-1][-1] = l[-1][-1]+'\n' elif type(l[-1])==types.StringType: @@ -152,7 +185,7 @@ class PythonGenerator: def generMCNUPLET(self,obj): """ - Méthode générant une représentation de self permettant son ecriture + Methode generant une representation de self permettant son ecriture dans le format python """ l=[] @@ -165,8 +198,8 @@ class PythonGenerator: def generCOMMANDE_COMM(self,obj): """ - Cette méthode convertit un COMMANDE_COMM - en une liste de chaines de caractères à la syntaxe python + Cette methode convertit un COMMANDE_COMM + en une liste de chaines de caracteres a la syntaxe python """ l_lignes = string.split(obj.valeur,'\n') txt='' @@ -176,46 +209,64 @@ class PythonGenerator: def generEVAL(self,obj): """ - Cette méthode convertit un EVAL - en une liste de chaines de caractères à la syntaxe python + Cette methode convertit un EVAL + en une liste de chaines de caracteres a la syntaxe python """ return 'EVAL("""'+ obj.valeur +'""")' def generCOMMENTAIRE(self,obj): """ - Cette méthode convertit un COMMENTAIRE - en une liste de chaines de caractères à la syntaxe python + Cette methode convertit un COMMENTAIRE + en une liste de chaines de caracteres a la syntaxe python """ - l_lignes = string.split(obj.valeur,'\n') + # modification pour repondre a la demande de C. Durand, d'eviter + # l'ajout systematique d'un diese, a la suite du commentaire + # Dans la chaine de caracteres obj.valeur, on supprime le dernier + # saut de ligne + sans_saut = re.sub("\n$","",obj.valeur) + l_lignes = string.split(sans_saut,'\n') txt='' + i=1 for ligne in l_lignes: txt = txt + '#'+ligne+'\n' + + # suppression du dernier saut de ligne + #txt = re.sub("\n$","",txt) + # on ajoute un saut de ligne avant + pattern=re.compile(" ?\#") + m=pattern.match(txt) + if m: + txt="\n"+txt return txt def generPARAMETRE_EVAL(self,obj): """ - Cette méthode convertit un PARAMETRE_EVAL - en une liste de chaines de caractères à la syntaxe python + Cette methode convertit un PARAMETRE_EVAL + en une liste de chaines de caracteres a la syntaxe python """ if obj.valeur == None: return obj.nom + ' = None ;\n' else: return obj.nom + ' = '+ self.generator(obj.valeur) +';\n' + def generITEM_PARAMETRE(self,obj): + return repr(obj) + + def generFormula(self,obj): + #return repr(obj) + return str(obj) + def generPARAMETRE(self,obj): """ - Cette méthode convertit un PARAMETRE - en une liste de chaines de caractères à la syntaxe python + Cette methode convertit un PARAMETRE + en une liste de chaines de caracteres a la syntaxe python """ - if type(obj.valeur) == types.StringType: - return obj.nom + " = '" + obj.valeur + "';\n" - else: - return obj.nom + ' = ' + str(obj.valeur) + ';\n' + return repr(obj) + ";\n" def generETAPE_NIVEAU(self,obj): """ - Cette méthode convertit une étape niveau - en une liste de chaines de caractères à la syntaxe python + Cette methode convertit une etape niveau + en une liste de chaines de caracteres a la syntaxe python """ l=[] if obj.etapes_niveaux == []: @@ -228,11 +279,12 @@ class PythonGenerator: def generETAPE(self,obj): """ - Cette méthode convertit une étape - en une liste de chaines de caractères à la syntaxe python + Cette methode convertit une etape + en une liste de chaines de caracteres a la syntaxe python """ try: sdname= self.generator(obj.sd) + if string.find(sdname,'SD_') != -1: sdname='sansnom' except: sdname='sansnom' l=[] @@ -242,11 +294,11 @@ class PythonGenerator: str = 'reuse ='+ self.generator(obj.reuse) + ',' l.append(str) for v in obj.mc_liste: - if isinstance(v,MCBLOC) : + if isinstance(v,Accas.MCBLOC) : liste=self.generator(v) for mocle in liste : l.append(mocle) - elif isinstance(v,MCSIMP) : + elif isinstance(v,Accas.MCSIMP) : text=self.generator(v) l.append(v.nom+'='+text) else: @@ -262,26 +314,23 @@ class PythonGenerator: def generFORM_ETAPE(self,obj): """ - Méthode particulière pour les objets de type FORMULE + Methode particuliere pour les objets de type FORMULE """ l=[] nom = obj.get_nom() if nom == '' : nom = 'sansnom' - if len(obj.mc_liste)>0: - l.append(nom + ' = FORMULE(') - s=obj.type_retourne + ' = ' + "'''" + obj.arguments + ' = ' + obj.corps+"'''" - l.append(s) - l.append(');') - else: - l.append(nom+' = FORMULE();') + l.append(nom + ' = FORMULE(') + for v in obj.mc_liste: + text=self.generator(v) + l.append(v.nom+'='+text) + l.append(');') return l def generMACRO_ETAPE(self,obj): """ - Cette méthode convertit une macro-étape - en une liste de chaines de caractères à la syntaxe python + Cette methode convertit une macro-etape + en une liste de chaines de caracteres a la syntaxe python """ - if obj.definition.nom == 'FORMULE' : return self.gen_formule(obj) try: if obj.sd == None: sdname='' @@ -297,11 +346,11 @@ class PythonGenerator: str = "reuse =" + self.generator(obj.reuse) + ',' l.append(str) for v in obj.mc_liste: - if isinstance(v,MCBLOC) : + if isinstance(v,Accas.MCBLOC) : liste=self.generator(v) for mocle in liste : l.append(mocle) - elif isinstance(v,MCSIMP) : + elif isinstance(v,Accas.MCSIMP) : text=self.generator(v) l.append(v.nom+'='+text) else: @@ -316,44 +365,20 @@ class PythonGenerator: l.append(');') return l - def gen_formule(self,obj): - """ - Méthode particuliere aux objets de type FORMULE - """ - try: - if obj.sd == None: - sdname='' - else: - sdname= self.generator(obj.sd) - except: - sdname='sansnom' - l=[] - label=sdname + ' = FORMULE(' - l.append(label) - for v in obj.mc_liste: - s='' - s= v.nom+':'+sdname+'('+v.valeur+')' - l.append(s) - if len(l) == 1: - l[0]=label+');' - else : - l.append(');') - return l - def generPROC_ETAPE(self,obj): """ - Cette méthode convertit une PROC étape - en une liste de chaines de caractères à la syntaxe python + Cette methode convertit une PROC etape + en une liste de chaines de caracteres a la syntaxe python """ l=[] label=obj.definition.nom+'(' l.append(label) for v in obj.mc_liste: - if isinstance(v,MCBLOC) : + if isinstance(v,Accas.MCBLOC) : liste=self.generator(v) for mocle in liste : l.append(mocle) - elif isinstance(v,MCSIMP) : + elif isinstance(v,Accas.MCSIMP) : text=self.generator(v) l.append(v.nom+'='+text) else: @@ -370,68 +395,78 @@ class PythonGenerator: def generASSD(self,obj): """ - Convertit un objet dérivé d'ASSD en une chaine de caractères à la + Convertit un objet derive d'ASSD en une chaine de caracteres a la syntaxe python """ return obj.get_name() def generMCFACT(self,obj): """ - Convertit un objet MCFACT en une liste de chaines de caractères à la + Convertit un objet MCFACT en une liste de chaines de caracteres a la syntaxe python """ l=[] l.append('_F(') for v in obj.mc_liste: - if not isinstance(v,MCSIMP) and not isinstance (v,MCBLOC) : - # on est en présence d'une entite composée : on récupère une liste + if not isinstance(v,Accas.MCSIMP) and not isinstance (v,Accas.MCBLOC) : + # on est en presence d'une entite composee : on recupere une liste liste=self.generator(v) liste[0]=v.nom+'='+liste[0] l.append(liste) - elif isinstance(v,MCBLOC): + elif isinstance(v,Accas.MCBLOC): liste=self.generator(v) for arg in liste : l.append(arg) else: - # on a est en présence d'un MCSIMP : on récupère une string + # on est en presence d'un MCSIMP : on recupere une string text =self.generator(v) - l.append(v.nom+'='+text) - # il faut être plus subtil dans l'ajout de la virgule en différenciant - # le cas où elle est obligatoire (si self a des frères cadets + if v.nom != "Consigne" : l.append(v.nom+'='+text) + # il faut etre plus subtil dans l'ajout de la virgule en differenciant + # le cas ou elle est obligatoire (si self a des freres cadets # dans self.parent) ou non - # (cas où self est seul ou le benjamin de self.parent) + # (cas ou self est seul ou le benjamin de self.parent) l.append('),') return l def generMCList(self,obj): """ - Convertit un objet MCList en une liste de chaines de caractères à la + Convertit un objet MCList en une liste de chaines de caracteres a la syntaxe python """ - l=[] - str = '(' - l.append(str) - for mcfact in obj.data: - l.append(self.generator(mcfact)) - l.append('),') + if len(obj.data) > 1: + l=['('] + for mcfact in obj.data: l.append(self.generator(mcfact)) + l.append('),') + else: + l= self.generator(obj.data[0]) return l def generMCBLOC(self,obj): """ - Convertit un objet MCBLOC en une liste de chaines de caractères à la + Convertit un objet MCBLOC en une liste de chaines de caracteres a la syntaxe python """ l=[] for v in obj.mc_liste: - if isinstance(v,MCBLOC) : + if isinstance(v,Accas.MCBLOC) : liste=self.generator(v) for mocle in liste : l.append(mocle) - elif isinstance(v,MCList): + elif isinstance(v,Accas.MCFACT): + liste=self.generator(v) + elif isinstance(v,Accas.MCList): liste=self.generator(v) liste[0]=v.nom+'='+liste[0] - for mocle in liste : - l.append(mocle) + # PN essai de correction bug identation + if (hasattr(v,'data')) : + if (isinstance(v.data[0],Accas.MCFACT) and (len(v.data) == 1)): + l.append(liste) + else: + for mocle in liste : + l.append(mocle) + else : + for mocle in liste : + l.append(mocle) else: data=self.generator(v) if type(data) == types.ListType: @@ -441,56 +476,112 @@ class PythonGenerator: l.append(data) return l + + def format_item(self,valeur,etape,obj,vientDeListe=0): + if (type(valeur) == types.FloatType or 'R' in obj.definition.type) and not(isinstance(valeur,Accas.PARAMETRE)) : + # Pour un flottant on utilise str ou repr si on vient d une liste + # ou la notation scientifique + # On ajoute un . si il n y en a pas dans la valeur + s = str(valeur) + if vientDeListe and repr(valeur) != str(valeur) : s=repr(valeur) + if (s.find('.')== -1 and s.find('e')== -1 and s.find('E')==-1) : s=s+'.0' + clefobj=etape.get_sdname() + if self.appli.appliEficas and self.appli.appliEficas.dict_reels.has_key(clefobj): + if self.appli.appliEficas.dict_reels[clefobj].has_key(valeur): + s=self.appli.appliEficas.dict_reels[clefobj][valeur] + + elif type(valeur) == types.StringType : + if valeur.find('\n') == -1: + # pas de retour chariot, on utilise repr + s = repr(valeur) + elif valeur.find('"""') == -1: + # retour chariot mais pas de triple ", on formatte + s='"""'+valeur+'"""' + else: + s = repr(valeur) + elif isinstance(valeur,Accas.CO) or hasattr(etape,'sdprods') and valeur in etape.sdprods: + s = "CO('"+ self.generator(valeur) +"')" + elif isinstance(valeur,Accas.ASSD): + s = self.generator(valeur) + elif isinstance(valeur,Accas.PARAMETRE): + # il ne faut pas prendre la string que retourne gener + # mais seulement le nom dans le cas d'un parametre + s = valeur.nom + + #elif type(valeur) == types.InstanceType or isinstance(valeur,object): + # if valeur.__class__.__name__ == 'CO' or hasattr(etape,'sdprods') and valeur in etape.sdprods : + # s = "CO('"+ self.generator(valeur) +"')" + # elif isinstance(valeur,Accas.PARAMETRE): + # il ne faut pas prendre la string que retourne gener + # mais seulement le nom dans le cas d'un parametre + # s = valeur.nom + # else: + # s = self.generator(valeur) + + else : + # Pour les autres types on utilise repr + s = repr(valeur) + return s + def generMCSIMP(self,obj) : """ - Convertit un objet MCSIMP en une liste de chaines de caractères à la + Convertit un objet MCSIMP en une liste de chaines de caracteres a la syntaxe python """ + waitTuple=0 if type(obj.valeur) in (types.TupleType,types.ListType) : - s = '' - for val in obj.valeur : - if type(val) == types.InstanceType : - if hasattr(obj.etape,'sdprods'): - if val in obj.etape.sdprods : - s = s + "CO('"+ self.generator(val) +"')" - elif val.__class__.__name__ == 'CO': - s = s + "CO('"+ self.generator(val) +"')" - else: - s = s + self.generator(val) - elif isinstance(val,PARAMETRE): - # il ne faut pas prendre la string que retourne gener - # mais seulement le nom dans le cas d'un paramètre - s = s + val.nom - else: - s = s + self.generator(val) - else : - s = s + `val` - s = s + ',' - if len(obj.valeur) > 1: - s = '(' + s + '),' + s = '' + for ss_type in obj.definition.type: + if repr(ss_type).find('Tuple') != -1 : + waitTuple=1 + break + + if waitTuple : + #s = str(obj.valeur) +',' + #obj.valeurFormatee=obj.valeur + s = obj.GetText() +',' + obj.valeurFormatee=obj.GetText() + else : + obj.valeurFormatee=[] + for val in obj.valeur : + s =s +self.format_item(val,obj.etape,obj,1) + ',' + if obj.wait_TXM() : + obj.valeurFormatee.append(val) + else : + obj.valeurFormatee.append(self.format_item(val,obj.etape,obj)) + if len(obj.valeur) >= 1: + s = '(' + s + '),' + if obj.valeur==[] or obj.valeur==() : s="()," + if obj.nbrColonnes() : + s=self.formatColonnes(obj.nbrColonnes(),obj.valeur,obj) else : - val=obj.valeur - if type(val) == types.InstanceType : - if hasattr(obj.etape,'sdprods'): - if val in obj.etape.sdprods : - s = "CO('"+ self.generator(val) +"')" - elif val.__class__.__name__ == 'CO': - s = "CO('"+ self.generator(val) +"')" - else: - s = self.generator(val) - elif isinstance(val,PARAMETRE): - # il ne faut pas prendre la string que retourne gener - # mais seulement le nom dans le cas d'un paramètre - s = val.nom - else: - s = self.generator(val) - elif type(val) == types.FloatType : - # Pour un réel on fait un formattage spécial - # XXX bizarrement ce n'est pas fait pour une liste - s = repr_float(val) - else : - s = `val` - s= s + ',' + obj.valeurFormatee=obj.valeur + s=self.format_item(obj.valeur,obj.etape,obj) + ',' return s + def formatColonnes(self,nbrColonnes,listeValeurs,obj): + #try : + if 1 == 1 : + indice=0 + textformat="(" + while ( indice < len(listeValeurs) ) : + try : + #if 1 : + for l in range(nbrColonnes) : + texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj) + textformat=textformat+texteVariable+" ," + indice=indice+1 + textformat=textformat+"\n" + except : + #else : + while ( indice < len(listeValeurs) ) : + texteVariable=self.format_item(listeValeurs[indice],obj.etape,obj) + textformat=textformat+texteVariable+", " + indice=indice+1 + textformat=textformat+"\n" + textformat=textformat[0:-1]+"),\n" + #except : + else : + textformat=str(obj.valeur) + return textformat