1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013 EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 from Extensions.i18n import tr
25 # mot cles a traiter : Discretisations_In_Space
26 from enumTelemac import dicoEnum
28 escapedQuotesRE = re.compile(r"(\\\\|\\\"|\\\')")
29 stringsAndCommentsRE = \
30 re.compile(u"(\"\"\".*?\"\"\"|'''.*?'''|\"[^\"]*\"|\'[^\']*\'|#.*?\n)", re.DOTALL)
31 allchars = string.maketrans(u"", "")
32 allcharsExceptNewline = allchars[: allchars.index('\n')]+allchars[allchars.index('\n')+1:]
33 allcharsExceptNewlineTranstable = string.maketrans(allcharsExceptNewline, '*'*len(allcharsExceptNewline))
35 ordreEtapes=('INITIALIZATION', 'TIDE_PARAMETERS', 'INITIAL_STATE', 'NUMERICAL_PARAMETERS', 'PHYSICAL_PARAMETERS',)
37 def maskStringsAndComments(src):
38 """Masque tous les caracteres de src contenus dans des commentaires ou des strings multilignes (triples
40 Le masquage est realise en remplacant les caracteres par des *
41 Attention : cette fonction doit etre utilisee sur un texte complet et pas ligne par ligne
43 src = escapedQuotesRE.sub(u"**", src)
44 allstrings = stringsAndCommentsRE.split(src)
45 # every odd element is a string or comment
46 for i in xrange(1, len(allstrings), 2):
47 if allstrings[i].startswith(u"'''")or allstrings[i].startswith('"""'):
48 allstrings[i] = allstrings[i][:3]+ \
49 allstrings[i][3:-3].translate(allcharsExceptNewlineTranstable)+ \
52 allstrings[i] = allstrings[i][0]+ \
53 allstrings[i][1:-1].translate(allcharsExceptNewlineTranstable)+ \
56 return "".join(allstrings)
59 implicitContinuationChars = (('(', ')'), ('[', ']'), ('{', '}'))
60 linecontinueRE = re.compile(r"\\\s*(#.*)?$")
61 emptyHangingBraces = [0,0,0,0,0]
63 class ParserException(Exception): pass
64 class FatalError(Exception): pass
66 # ligne commençant par /
67 pattern_commentaireTelemac = re.compile(r"^\s*/.*")
68 # ligne commençant par &
69 pattern_eperluetteTelemac = re.compile(r"^&.*")
70 #commentaire double precede d'un nombre quelconque de blancs (pas multiligne)
71 pattern_2comments = re.compile(r"^\s*##.*")
72 #commentaire standard precede d'un nombre quelconque de blancs (pas multiligne)
73 pattern_comment = re.compile(r"^\s*#.*")
74 #fin de ligne ; suivi d'un nombre quelconque de blancs (pas multiligne)
75 pattern_fin = re.compile(r"; *$")
76 #pattern pour supprimer les blancs, tabulations et fins de ligne
77 pattern_blancs = re.compile(r"[ \t\r\f\v]")
78 #pattern_blancs = re.compile(r"[\s\n]")
79 number_kw_pattern=re.compile(r"""
81 #groupe nombre decimal
83 #signe : on ignore le signe +
85 #groupe (avec ?: n'apparait pas en tant que groupe dans le resultat)
87 #mantisse forme entiere.fractionnaire
90 #ou forme .fractionnaire
99 """,re.VERBOSE|re.MULTILINE)
101 def construit_genea(texte,liste_mc):
103 Retourne un dictionnaire dont les cles sont des reels et les valeurs sont leurs representations textuelles.
105 Realise un filtrage sur les reels :
107 - Ne garde que les reels pour lesquels str ne donne pas une bonne representation.
108 - Ne garde que les reels derriere un argument keyword dont le nom est dans liste_mc
110 >>> s = '''a=+21.3e-5*85,b=-.1234,c=81.6 , d= -8 , e=_F(x=342.67,y=-1), f=+1.1, g=(1.3,-5,1.54E-3),
111 ... #POMPE_PRIMA._BOUCLE_N._2_ELEMENT_NUMERO:0239
112 ... h=_F(x=34.6,y=-1)'''
113 >>> construit_genea(s,['a','x'])
114 {0.000213: '21.3e-5'}
118 #on masque les strings et commentaires pour ne pas identifier de faux reels
119 for m in number_kw_pattern.findall(maskStringsAndComments(texte)):
124 if mot not in liste_mc:continue
127 if str(key) != m: d[key]=m
131 ListeMCAExclure=("Computation_Continued",)
132 DicoMCAExclureSiValeur={"Computation_Continued" : "NO"}
133 ListeMCARecalculer=('tt',)
134 DicoMCARecalculerSiValeur={"Computation_Continued" : "YES"}
135 DicoMCAReformater = {"Variables_For_Graphic_Printouts": "texteEnListe", \
136 "Solver" : "remplaceEnum" }
137 DicoPlusieursMC = {"Type_Of_Advection": "decoupeAdvection" ,\
143 pattern_ligne_vide = re.compile(r'^[\t\r\f\v\n]+')
145 def __init__(self,texte):
150 def get_texte(self,appli=None):
152 Retourne le texte issu de l'analyse
155 self.dicoInverse=self.appli.readercata.dicoInverse
160 except ParserException:
161 #Impossible de convertir le texte, on le retourne tel que
167 Eclate la chaine self.texte en self.l_objets une liste lignes d'instructions
168 et de commentaires (parmi lesquels des instructions "commentarisées").
170 l_lignes = string.split(self.texte,'\n')
171 affectation_courante = None
174 #Masquage des commentaires et strings multilignes
175 #srcMasked=maskStringsAndComments('\n'.join(l_lignes))
177 #masked_lines=srcMasked.split('\n')
180 self.listeNomValeur=[]
181 for ligne in l_lignes :
182 #line=masked_lines[lineno]
185 if string.strip(ligne) == '': continue
186 if pattern_commentaireTelemac.match(ligne) : continue
187 if pattern_eperluetteTelemac.match(ligne) : continue
188 # On remplace les : par un =
189 # On s assure que les = soient entoures d espace
190 # On remplace les espaces successifs par un seul
191 # On enleve les blancs en debut et fin de ligne
192 # On remplace les ' ; ' par des ;
193 ligne=ligne.replace(':','=')
194 ligne=ligne.replace('=',' = ')
195 ligne=re.sub(r';\s*',';',ligne)
196 ligne=re.sub(r'\s*;',';',ligne)
197 ligne=re.sub(r' \s*',' ',ligne)
198 ligne=re.sub(r'^\s','',ligne)
199 ligne=re.sub(r'\s$','',ligne)
200 listeMot=ligne.split(" ")
201 while listeMot != [] :
202 nom,listeMot = self.construitNom(listeMot)
203 valeur,listeMot = self.construitValeur(listeMot)
204 bTraite, nom, valeur =self.verifieNom(nom,valeur)
205 if bTraite : self.listeNomValeur.append((nom, valeur))
206 self.construitTexteFinal()
209 def construitNom(self,liste):
214 if mot in (":","=") : break
215 motE=mot[0].upper()+mot[1:].lower()
217 nouveauNom=nomEficas[0:-1].replace('-','_')
218 nouvelleListe=liste[index:]
219 return nouveauNom,nouvelleListe
221 def construitValeur(self,liste):
223 if liste[0][0]=="'" :
231 elif liste[0].find(';') > -1 :
232 valeur=liste[0].split(';')
237 nouvelleListe=liste[index:]
238 return valeur,nouvelleListe
241 def verifieNom(self,nom,valeur):
242 if nom in ListeMCAExclure : return (False, nom, valeur)
243 if nom in DicoMCAExclureSiValeur.keys() :
244 if valeur != DicoMCAExclureSiValeur[nom] : print "prevoir Traitement pour ", nom, valeur
245 return (False, nom, valeur)
248 if nom in DicoMCAReformater.keys() :
249 bTrue,nom,valeur=apply(PARSEUR_CAS.__dict__[DicoMCAReformater[nom]],(self,nom,valeur))
250 if nom in DicoPlusieursMC.keys() :
251 bTrue,nom,valeur=apply(PARSEUR_CAS.__dict__[DicoPlusieursMC[nom]],(self,nom,valeur))
252 return (bTrue,nom,valeur)
253 if nom not in self.dicoInverse.keys() :
254 print "******** ", nom, " non encore connu ***********"
256 return (bTrue, nom, valeur)
258 def remplaceEnum(self,nom,valeur):
259 newValeur=dicoEnum[nom][valeur]
260 return (True,nom,newValeur)
264 def texteEnListe(self,nom,valeur):
265 print "je passe dans decoupeEnListe pour ", nom,valeur
266 v1=re.sub(r'^\'','',valeur)
267 v2=re.sub(r'\'$','',v1)
268 newValeur=v2.split(',')
269 return (True,nom,newValeur)
271 def decoupeAdvection(self,nom,valeur):
272 # on met a jour la liste des valeurs ici : il y a plusieurs MC calcule
273 print "je passe dans decoupeAdvection pour",nom,valeur
274 self.listeNomValeur.append(('Advection_Of_U_And_V',True))
275 v=dicoEnum['Type_Of_Advection'][valeur[0]]
276 self.listeNomValeur.append(('Type_Of_Advection_U_And_V',v) )
277 if len(valeur)==1: return (False,nom,valeur)
279 self.listeNomValeur.append(('Advection_Of_H',True))
280 v=dicoEnum['Type_Of_Advection'][valeur[1]]
281 self.listeNomValeur.append(('Type_Of_Advection_H',v))
282 if len(valeur)==2: return (False,nom,valeur)
284 self.listeNomValeur.append(('Advection_Of_Tracers',True))
285 v=dicoEnum['Type_Of_Advection'][valeur[2]]
286 self.listeNomValeur.append(('Type_Of_Advection_Tracers',v))
287 if len(valeur)==3: return (False,nom,valeur)
289 self.listeNomValeur.append(('Advection_Of_K_And_Epsilon',True))
290 v=dicoEnum['Type_Of_Advection'][valeur[3]]
291 self.listeNomValeur.append(('Type_Of_Advection_K_And_Epsilon',v))
292 # on retourne False, l append est deja fait
293 return (False,nom,valeur)
295 def construitTexteFinal(self):
298 print self.listeNomValeur
299 for nomMC,valeur in self.listeNomValeur:
300 mc,objmc=self.dicoInverse[nomMC][0]
301 if nomMC=="Solver_Option" : print self.dicoInverse[nomMC][0]
302 self.dicoNature[mc]=objmc
303 liste=self.dicoInverse[nomMC][1:]
306 for (nom,obj) in liste:
307 if isinstance(obj,Accas.A_BLOC.BLOC) :
309 self.dicoNature[nom]=obj
310 if not(isinstance(obj,Accas.A_PROC.PROC)) and not(isinstance(obj,Accas.A_FACT.FACT)) :
311 print "******** ", nom,obj, "********"
313 if not nom in dico.keys(): dico[nom]={}
317 for etape in ordreEtapes :
319 if etape in self.dicoTexte.keys():
320 self.texteComm+=etape+"("
321 self.traiteEtape(self.dicoTexte[etape])
322 self.texteComm+=");\n"
325 def traiteEtape(self,dico):
326 for mc in dico.keys() :
328 if isinstance(self.dicoNature[mc],Accas.A_SIMP.SIMP):
329 if 'TXM' in self.dicoNature[mc].type and valeur[0] !="'" : valeur="'"+valeur
330 if 'TXM' in self.dicoNature[mc].type and valeur[-1] !="'" : valeur=valeur+"'"
331 if 'Fichier' in self.dicoNature[mc].type and valeur[0] !="'" : valeur="'"+valeur
332 if 'Fichier' in self.dicoNature[mc].type and valeur[-1] !="'" : valeur=valeur+"'"
333 if 'Repertoire' in self.dicoNature[mc].type and valeur[0] !="'" : valeur="'"+valeur
334 if 'Repertoire' in self.dicoNature[mc].type and valeur[-1] !="'" : valeur=valeur+"'"
335 print self.dicoNature[mc].type
336 #self.texteComm+=mc+" = '"+str(valeur)+"',"
337 #else : self.texteComm+=mc+" = "+str(valeur)+","
338 self.texteComm+=mc+" = "+str(valeur)+","
340 self.texteComm+=mc+"=_F("
341 self.traiteEtape(valeur)
342 self.texteComm+="),\n"