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
20 import sys,string,re,tokenize
28 def set_text(self,texte):
31 def append_text(self,texte):
34 self.texte = self.texte +texte
36 class COMMENTAIRE(ENTITE_JDC):
40 Retourne une chaîne de caractères représentant self
41 sous une forme interprétable par EFICAS
44 return "COMMENTAIRE(u"+t+")\n"
46 def append_text(self,texte):
48 Ajoute texte à self.texte en enlevant le # initial
51 self.texte = self.texte+texte[1:]
53 # le dièse n'est pas sur le premier caractère
54 amont,aval = string.split(texte,'#',1) # on découpe suivant la première occurrence de #
55 self.texte = self.texte +amont + aval
57 class AFFECTATION(ENTITE_JDC):
59 def append_text(self,texte):
61 Ajoute texte à self.texte en enlevant tout retour chariot et tout point virgule
63 self.texte = self.texte+texte
67 Retourne une expression de l'affectation compréhensible par ACCAS
68 et exploitable par EFICAS
72 return "PARAMETRE(nom='"+self.name+"',valeur="+t+")"
74 class COMMANDE_COMMENTARISEE(ENTITE_JDC):
76 def append_text(self,texte):
78 Ajoute texte à self.texte en enlevant les doubles commentaires
80 texte = string.strip(texte)
81 texte = string.strip(texte[2:])
82 self.texte = self.texte+(len(self.texte)>0)*'\n'+texte
86 Retourne une expression de la commande commentarisée compréhensible par ACCAS
87 et exploitable par EFICAS
89 return "COMMANDE_COMM(texte="+repr(self.texte)+")\n"
93 next['if'] = next['elif'] = 'elif', 'else', 'end'
94 next['while'] = next['for'] = 'else', 'end'
95 next['try'] = 'except', 'finally'
96 next['except'] = 'except', 'else', 'end'
97 next['else'] = next['finally'] = next['def'] = next['class'] = 'end'
99 start = 'if', 'while', 'for', 'try', 'def', 'class'
101 class PARSEUR_PYTHON:
103 Cette classe sert à créer un objet PARSEUR_PYTHON qui réalise l'analyse d'un texte
104 représentant un JDC Python en distinguant :
105 - les commentaires inter commandes
109 # au moins 1 caractère non blanc ou non tabulation
110 #pattern_ligne_non_blanche = re.compile(r'^[\w\t]+')
111 pattern_ligne_non_blanche = re.compile(r'[^ \t]+')
113 r'^\s*(?P<kw>[a-z]+)'
114 r'(\s+(?P<id>[a-zA-Z_]\w*))?'
116 endprog = re.compile(
117 r'^\s*#?\s*end\s+(?P<kw>[a-z]+)'
118 r'(\s+(?P<id>[a-zA-Z_]\w*))?'
120 wsprog = re.compile(r'^[ \t]*')
121 optionprog=re.compile(r'#\s*parse:\s*([^\n\'"]*)$')
123 def __init__(self,texte):
124 # on verifie que le texte fourni se compile correctement
125 compile(texte,"<string>",'exec')
126 self.texte = cStringIO.StringIO(texte)
131 self.please_indent = 1
132 self.indent_list = []
136 self.indent_list=[""]
137 self.objet_courant=None
138 self.affectation_flag=1
141 self.buffer_indent=""
143 def getoptions(self):
144 m= self.optionprog.match(self.line)
148 flag=(option[0] == '+')
149 if name == "affectation": self.affectation_flag=flag
150 if name == "comment": self.comment_flag=flag
152 self.comment_flag=flag
153 self.affectation_flag=flag
156 self.line= self.texte.readline()
157 #print "line:",self.line
162 def get_texte(self,appli=None):
164 Retourne le texte issu de l'analyse
166 for tk in tokenize.generate_tokens(self.readline):
167 self.process_token(tk)
170 def process_token(self, tk):
173 ttype, tstring, spos, epos, line = tk
174 thisrow, thiscol = spos
175 #print spos, epos,tokenize.tok_name[ttype],self.lastrow, self.lastcol
177 if thisrow > self.lastrow:
178 # si plusieurs lignes (>1)
179 self.out=self.out+"\n" * (thisrow - self.lastrow - 1)
182 # if thiscol > self.lastcol :
183 # self.out=self.out+ " " * (thiscol - self.lastcol)
184 # self.please_indent = None
187 #self.nextrow, self.nextcol = epos
190 fn = getattr(self, tokenize.tok_name[ttype])
191 except AttributeError:
192 print( "No match!", tokenize.tok_name[ttype], tstring)
195 if ttype != tokenize.DEDENT and ttype != tokenize.INDENT and self.please_indent:
199 self.lastrow, self.lastcol = epos
201 def output(self,tstring):
202 #print "output",tstring
204 if self.thiscol > self.lastcol :
205 #print self.thiscol,self.lastcol
206 self.out=self.out+ " " * (self.thiscol - self.lastcol)
207 self.lastcol=self.thiscol
209 self.out=self.out+tstring
211 def output_com(self,tstring):
212 self.out=self.out+tstring
214 def update_indent(self):
215 #print "update_indent",len(self.indent_list[-1]),len(self.buffer_indent)
216 if len(self.indent_list[-1]) > len(self.buffer_indent):
217 self.out=self.out+(len(self.indent_list[-1]) - len(self.buffer_indent))*" "
218 self.buffer_indent=self.indent_list[-1]
221 #print "indentation dans do_indent",len(self.indent_list)
223 self.out=self.out+self.indent_list[-1]
224 self.buffer_indent=self.indent_list[-1]
225 if self.lastcol+len(self.indent_list[-1]) > self.thiscol:
226 self.lastcol=self.thiscol
228 self.lastcol=self.lastcol+len(self.indent_list[-1])
229 self.please_indent = None
231 def flush_buffer(self):
233 # print len(self.indent_list),self.please_indent
234 for ob in self.buffer:
235 self.out= self.out+ str(ob)
238 self.objet_courant=None
240 def NL(self, tstring):
242 if self.paren_level == 0:
243 # affectation en cours mais complète
244 self.out= self.out+ str(self.affectation_courante)
245 self.affectation_courante=None
249 # affectation en cours, on ajoute
250 if self.thiscol > self.lastcol :self.affectation_courante.append_text((self.thiscol - self.lastcol)*" ")
251 self.affectation_courante.append_text(tstring)
254 if self.objet_courant:
255 self.objet_courant=None
256 self.buffer.append(tstring)
257 # self.please_indent = None
260 self.please_indent = 1
262 def COMMENT(self, tstring):
263 liste= string.split(self.line,"##",1)
265 # On a trouve un double commentaire
268 # affectation en cours, on ignore
270 elif self.paren_level > 0:
272 elif self.comment_flag and not self.pattern_ligne_non_blanche.search(before):
273 # il s'agit d'une commande commentarisée
274 if self.objet_courant == None:
275 if not self.buffer:self.buffer_indent=self.indent_list[-1]
276 self.objet_courant=COMMANDE_COMMENTARISEE()
277 self.buffer.append(self.objet_courant)
278 self.objet_courant.append_text(tstring)
279 self.please_indent = None
280 elif isinstance(self.objet_courant,COMMENTAIRE):
281 self.objet_courant=COMMANDE_COMMENTARISEE()
282 self.buffer.append(self.objet_courant)
283 self.objet_courant.append_text(tstring)
284 self.please_indent = None
286 self.objet_courant.append_text(tstring)
287 self.please_indent = None
291 self.please_indent = 1
295 # On a un commentaire simple
296 new_line = string.split(self.line,'#')[0]
298 # affectation en cours, on ignore
300 elif self.paren_level > 0:
302 elif self.comment_flag and not self.pattern_ligne_non_blanche.search(new_line):
303 # commentaire précédé de blancs
304 if self.objet_courant == None:
305 if not self.buffer:self.buffer_indent=self.indent_list[-1]
306 self.objet_courant=COMMENTAIRE()
307 self.buffer.append(self.objet_courant)
308 self.objet_courant.append_text(tstring)
309 self.please_indent = None
310 elif isinstance(self.objet_courant,COMMANDE_COMMENTARISEE):
311 self.objet_courant=COMMENTAIRE()
312 self.buffer.append(self.objet_courant)
313 self.objet_courant.append_text(tstring)
314 self.please_indent = None
316 self.objet_courant.append_text(tstring)
317 self.please_indent = None
321 self.please_indent = 1
324 def ERRORTOKEN(self, tstring):
325 print ("ERRORTOKEN", tstring)
327 def NAME(self, tstring):
332 if self.affectation ==1:
333 # on a une expression du type NAME=NAME
334 # on ne veut pas des expressions qui commencent par NAME=NAME(NAME=
335 # on en prend le chemin : on met affectation a 3 pour le signaler
336 # on attend d'en savoir plus
337 if self.thiscol > self.lastcol :self.affectation_courante.append_text((self.thiscol - self.lastcol)*" ")
338 self.affectation_courante.append_text(tstring)
341 elif self.affectation ==4:
342 # on a une expression qui commence par NAME=NAME(NAME
343 # il s'agit tres probablement d'une commande
344 # on annule l'affectation en cours
345 if self.thiscol > self.lastcol :self.affectation_courante.append_text((self.thiscol - self.lastcol)*" ")
346 self.affectation_courante.append_text(tstring)
349 elif self.affectation == 2:
350 # affectation en cours, on ajoute
351 if self.thiscol > self.lastcol :self.affectation_courante.append_text((self.thiscol - self.lastcol)*" ")
352 self.affectation_courante.append_text(tstring)
357 if self.paren_level == 0 and self.affectation_flag:
358 # si on est en dehors de parentheses et en mode transformation d'affectation
359 # on initialise l'attribut name qui indique une affectation en cours
363 def ident(self, tstring):
368 def NUMBER(self, tstring):
370 if self.affectation>=1:
371 # affectation en cours, on ajoute
372 if self.thiscol > self.lastcol :self.affectation_courante.append_text((self.thiscol - self.lastcol)*" ")
373 self.affectation_courante.append_text(tstring)
378 def OP(self,tstring):
380 if tstring in ('(','[','{'): self.paren_level=self.paren_level+1
381 if tstring in (')',']','}'): self.paren_level=self.paren_level-1
383 if tstring == '=' and self.affectation ==5:
384 # on a une expression qui commence par NAME=NAME(NAME=)
385 # il peut s'agir d'une commande
386 # on annule l'affectation en cours
387 self.out= self.out+ self.affectation_courante.texte
388 self.affectation_courante=None
391 elif tstring == ')' and self.affectation ==4:
392 # on a une expression qui commence par NAME=NAME()
393 # il peut s'agir d'une commande
394 # on annule l'affectation en cours
395 self.out= self.out+ self.affectation_courante.texte
396 self.affectation_courante=None
398 elif tstring == '(' and self.affectation == 3:
399 # on a deja trouve NAME=NAME
400 # on passe affectation a 4
401 if self.thiscol > self.lastcol :self.affectation_courante.append_text((self.thiscol - self.lastcol)*" ")
402 self.affectation_courante.append_text(tstring)
405 elif tstring == ';' and self.affectation>=1:
406 # l'affectation est terminee
407 self.out= self.out+ str(self.affectation_courante)
408 self.affectation_courante=None
411 elif self.affectation>=1:
412 # on complete l'affectation
413 if self.thiscol > self.lastcol :self.affectation_courante.append_text((self.thiscol - self.lastcol)*" ")
414 self.affectation_courante.append_text(tstring)
419 if self.name and tstring=='=':
421 self.affectation_courante=AFFECTATION()
422 self.affectation_courante.name=self.name
428 def INDENT(self, tstring):
429 #tstring=str(len(self.indent_list))*len(tstring)
430 self.indent_list.append(tstring)
431 #print "indentation dans INDENT",len(self.indent_list),len(tstring)
437 def DEDENT(self, tstring):
438 #print "DEDENT",tstring,len(tstring)
440 self.out= self.out+ str(self.buffer[0])
441 if len(self.buffer) > 1:
442 for ob in self.buffer[1:]:
444 self.out= self.out+ str(ob)
446 self.objet_courant=None
450 self.indent_list = self.indent_list[:-1]
451 #print "indentation dans DEDENT",len(self.indent_list)
453 def STRING(self, tstring):
455 if self.affectation>=1:
456 # affectation en cours, on ajoute
457 if self.thiscol > self.lastcol :self.affectation_courante.append_text((self.thiscol - self.lastcol)*" ")
458 self.affectation_courante.append_text(tstring)
463 if __name__ == "__main__" :
480 ##toto = FORMULE(REEL='(REEL:A) = A',);
506 #qqqqqqqqqqqqqqqqqqqqqqqq
511 toto = FORMULE(REEL='(REEL:A) = A',);
512 titi = FORMULE(REEL='(REEL:A) = A',) # commentaire inline
513 tutu = FORMULE(REEL='(REEL:A) = A',) ## commentaire inline
515 TEST_TABLE( TABLE=RELV[k],
517 _F( NOM_PARA = 'QUANTITE',
518 VALE_K = 'MAXIMUM'),),
520 NOM_PARA='VMIS', # comm
521 VALE=1.9669824189084E9,
522 REFERENCE='NON_REGRESSION',
537 for k in range(1,10):
539 # Appel a GMSH pour le maillage
541 f=open("coque.geo","w")
570 fmt_raison='-'*80+'''
572 Exception erreur_Fatale interceptee
575 '''+'-'*80+'xxxxxxxxxxxxxxxx'
583 ##toto = FORMULE(REEL='(REEL:A) = A',
607 MA=LIRE_MAILLAGE(#comment
610 MA=LIRE_MAILLAGE(INFO=1)
613 MA=LIRE_MAILLAGE(#comme
616 LIRE_MAILLAGE(INFO=1)
618 TFIN = 1.790 # Temps fin pour le calcul
620 PAS = 0.001 # pas de temps du calcul
621 # parse: -affectation
628 MO=AFFE_MODELE( MAILLAGE=MA,
629 #test de validateur GEOM (typ=grma) avec grma derive de GEOM
630 AFFE=(_F(GROUP_MA = ('LI1'),
631 PHENOMENE = 'MECANIQUE',
632 MODELISATION = 'DIS_TR'),
637 DS1[k] = CREA_CHAMP( OPERATION='EXTR', TYPE_CHAM='NOEU_DEPL_R',
638 RESULTAT= MODESTA1, NUME_ORDRE=k, NOM_CHAM = 'DEPL');
640 # parse: +affectation
641 ff=23 # parametre bidon
646 ##toto = FORMULE(REEL='(REEL:A) = A',
652 ##toto = FORMULE(REEL='(REEL:A) = A',
658 ##toto = FORMULE(REEL='(REEL:A) = A',
664 ##toto = FORMULE(REEL='(REEL:A) = A',
674 sensible=[2.1E11, 0.3, 1.E-6, 1.E-6, ]
677 # parse: -affectation
682 PS[i]=DEFI_PARA_SENSI(VALE=sensible[i])
683 # parse: +affectation
685 TEST_RESU(RESU=(_F(RESULTAT = U3L,
692 REFERENCE = 'AUTRE_ASTER',
701 TEST_RESU(RESU=(_F(RESULTAT = U3L,
708 REFERENCE = 'AUTRE_ASTER',
714 titi = FORMULE(REEL='(REEL:A) = A',
715 ) # commentaire inline
716 titi = FORMULE(REEL='(REEL:A) = A',
717 ) # commentaire inline
723 for i in range(10): s=0
731 for k in range(1,10):
733 # Appel a GMSH pour le maillage
735 f=open("coque.geo","w")
803 for k in range(1,10):
805 # Appel a GMSH pour le maillage
807 f=open("coque.geo","w")
817 for k in range(1,10):
819 # Appel a GMSH pour le maillage
821 f=open("coque.geo","w")
854 SUP_=dict([(grand,0.) for grand in grand_obs])
856 for k in range(1,ns+1):
876 ########################################################################
878 ########################################################################
879 # macro commande de post-traitement (ex POST_GOUJ2E)
880 # calcul des reactions cumulees suivant les filets
882 def POST_GOUJ_ops(self,TABLE):
886 if len(sys.argv)== 2:
887 progname, input = sys.argv
893 txt = PARSEUR_PYTHON(t).get_texte()
895 compile(txt,"<string>",'exec')