Salome HOME
*** empty log message ***
[tools/eficas.git] / convert / parseur_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 import sys,string,re
22 import traceback
23
24 escapedQuotesRE = re.compile(r"(\\\\|\\\"|\\\')")
25 stringsAndCommentsRE =  \
26       re.compile("(\"\"\".*?\"\"\"|'''.*?'''|\"[^\"]*\"|\'[^\']*\'|#.*?\n)", re.DOTALL)
27 allchars = string.maketrans("", "")
28 allcharsExceptNewline = allchars[: allchars.index('\n')]+allchars[allchars.index('\n')+1:]
29 allcharsExceptNewlineTranstable = string.maketrans(allcharsExceptNewline, '*'*len(allcharsExceptNewline))
30
31 def maskStringsAndComments(src):
32     """Masque tous les caracteres de src contenus dans des commentaires ou des strings multilignes (triples
33        quotes et guillemets.
34        Le masquage est realise en remplacant les caracteres par des * 
35        Attention : cette fonction doit etre utilisee sur un texte complet et pas ligne par ligne
36     """
37     src = escapedQuotesRE.sub("**", src)
38     allstrings = stringsAndCommentsRE.split(src)
39     # every odd element is a string or comment
40     for i in xrange(1, len(allstrings), 2):
41         if allstrings[i].startswith("'''")or allstrings[i].startswith('"""'):
42             allstrings[i] = allstrings[i][:3]+ \
43                            allstrings[i][3:-3].translate(allcharsExceptNewlineTranstable)+ \
44                            allstrings[i][-3:]
45         else:
46             allstrings[i] = allstrings[i][0]+ \
47                            allstrings[i][1:-1].translate(allcharsExceptNewlineTranstable)+ \
48                            allstrings[i][-1]
49
50     return "".join(allstrings)
51
52 implicitContinuationChars = (('(', ')'), ('[', ']'), ('{', '}'))
53 linecontinueRE = re.compile(r"\\\s*(#.*)?$")
54 emptyHangingBraces = [0,0,0,0,0]
55
56 class ParserException(Exception): pass
57 class FatalError(Exception): pass
58
59 #commentaire double precede d'un nombre quelconque de blancs (pas multiligne)
60 pattern_2comments   = re.compile(r"^\s*##.*")
61 #commentaire standard precede d'un nombre quelconque de blancs (pas multiligne)
62 pattern_comment   = re.compile(r"^\s*#.*")
63 #fin de ligne ; suivi d'un nombre quelconque de blancs (pas multiligne)
64 pattern_fin   = re.compile(r"; *$")
65 #pattern pour supprimer les blancs, tabulations et fins de ligne
66 pattern_blancs = re.compile(r"[ \t\r\f\v]")
67 #pattern_blancs = re.compile(r"[\s\n]")
68 number_kw_pattern=re.compile(r"""
69 (
70     #groupe nombre decimal
71     (?:
72         #signe : on ignore le signe +
73         [-]?
74         #groupe (avec ?: n'apparait pas en tant que groupe dans le resultat)
75         (?:
76             #mantisse forme entiere.fractionnaire
77             \d+(?:\.\d*)?
78             |
79             #ou forme .fractionnaire
80             \.\d+
81         )
82         (?:[eE][+-]?\d+)?
83     )
84     |
85     #argument keyword
86     [a-zA-Z_]\w*=
87 )
88 """,re.VERBOSE|re.MULTILINE)
89
90 def construit_genea(texte,liste_mc):
91     """
92        Retourne un dictionnaire dont les cles sont des reels et les valeurs sont leurs representations textuelles.
93
94        Realise un filtrage sur les reels :
95
96          - Ne garde que les reels pour lesquels str ne donne pas une bonne representation.
97          - Ne garde que les reels derriere un argument keyword dont le nom est dans liste_mc
98
99        >>> 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),
100        ... #POMPE_PRIMA._BOUCLE_N._2_ELEMENT_NUMERO:0239
101        ... h=_F(x=34.6,y=-1)'''
102        >>> construit_genea(s,['a','x'])
103        {0.000213: '21.3e-5'}
104     """
105     d={}
106     mot=""
107     #on masque les strings et commentaires pour ne pas identifier de faux reels
108     for m in number_kw_pattern.findall(maskStringsAndComments(texte)):
109         if m[-1] == '=':
110             #argument keyword
111             mot=m[:-1]
112         else:
113             if mot not in liste_mc:continue
114             #valeur
115             key=eval(m)
116             if str(key) != m: d[key]=m
117     return d
118
119
120 class ENTITE_JDC :
121     """Classe de base pour tous les objets créés lors de la conversion
122        Tout objet dérivé est enregistré auprès de son père à sa création
123     """
124     def __init__(self,pere):
125         self.texte = ''
126         pere.l_objets.append(self)
127
128     def set_text(self,texte):
129         self.texte = texte
130
131     def append_text(self,texte):
132         """
133         Ajoute texte à self.texte en mettant un retour chariot à la fin de texte
134         """
135         texte = texte+'\n'
136         self.texte = self.texte +texte
137
138     def __str__(self):
139         return self.texte
140
141 class COMMENTAIRE(ENTITE_JDC):
142
143     def __str__(self):
144         """
145         Retourne une chaîne de caractères représentants self
146         sous une forme interprétable par EFICAS
147         """
148         t=repr(self.texte)
149         return "COMMENTAIRE("+t+")\n"
150
151         #s='COMMENTAIRE("""'+self.texte+'""")\n\n'
152         #return s
153
154     def append_text(self,texte):
155         """
156         Ajoute texte à self.texte en enlevant le # initial
157         """
158         texte = texte+'\n'
159         if texte[0] == '#':
160             self.texte = self.texte+texte[1:]
161         else:
162             # le dièse n'est pas sur le premier caractère
163             amont,aval = string.split(texte,'#',1) # on découpe suivant la première occurrence de #
164             self.texte = self.texte +amont + aval
165         
166 class COMMANDE(ENTITE_JDC):
167
168     def __str__(self):
169         """
170         Retourne self.texte
171         """
172         return self.texte+'\n'
173         
174     def get_nb_par(self):
175         """
176         Retourne la différence entre le nombre de parenthèses ouvrantes
177         et le nombre de parenthèses fermantes présentes dans self.texte
178         Peut donc retourner un entier négatif
179         """
180         # faire attention aux commentaires contenus dans self.texte
181         # qui peuvent eux-mêmes contenir des parenthèses !!!!
182         l_lignes = string.split(self.texte,'\n')
183         nb = 0
184         for ligne in l_lignes:
185             ligne = string.split(ligne,'#')[0]
186             nb = nb + (string.count(ligne,'(')-string.count(ligne,')'))
187         return nb
188
189 class AFFECTATION(ENTITE_JDC):
190
191     def append_text(self,texte):
192         """
193         Ajoute texte à self.texte en enlevant tout retour chariot et tout point virgule
194         PN et tout commentaire
195         """
196         if texte[-1] == '\n' : texte = string.rstrip(texte[0:-1])
197         if texte[-1] == ';' : texte = string.rstrip(texte[0:-1])
198         self.texte = self.texte+texte+'\n'
199         
200     def __str__(self):
201         """
202         Retourne une expression de l'affectation compréhensible par ACCAS
203         et exploitable par EFICAS
204         """
205         nom,valeur = string.split(self.texte,'=',1)
206         n = string.rstrip(nom)
207         nom = string.lstrip(n)
208         if valeur[-1] == '\n': valeur = valeur[:-1]
209         return n + ' = PARAMETRE(nom=\''+nom+'\',valeur='+valeur+')\n'
210
211 class COMMANDE_COMMENTARISEE(ENTITE_JDC):
212
213     def append_text(self,texte):
214         """
215         Ajoute texte à self.texte en enlevant les doubles commentaires
216         """
217         texte = string.strip(texte)
218         texte = string.strip(texte[2:])
219         self.texte = self.texte+(len(self.texte)>0)*'\n'+texte
220
221     def __str__(self):
222         """
223         Retourne une expression de la commande commentarisée compréhensible par ACCAS
224         et exploitable par EFICAS
225         """
226         return "COMMANDE_COMM(texte="+repr(self.texte)+")\n"
227         #return "COMMANDE_COMM(texte='''"+self.texte+"''')\n"
228
229 class AFFECTATION_EVAL(ENTITE_JDC):
230
231     def append_text(self,texte):
232         """
233         Ajoute texte à self.texte en enlevant tout retour chariot
234         """
235         if texte[-1] == '\n' : texte = texte[1:-1]
236         self.texte = self.texte+texte
237         
238     def __str__(self):
239         """
240         Retourne une expression du paramètre EVAL compréhensible par ACCAS
241         et exploitable par EFICAS
242         """
243         nom,valeur = string.split(self.texte,'=',1)
244         nom = string.strip(nom)
245         if valeur[-1] == '\n': valeur = valeur[:-1]
246         valeur = string.strip(valeur)
247         return nom+' = PARAMETRE_EVAL(nom=\''+nom+'\',valeur=\''+valeur+'\')\n\n'
248         
249 class PARSEUR_PYTHON:
250     """
251     Cette classe sert à générer un objet PARSEUR_PYTHON qui réalise l'analyse d'un texte 
252     représentant un JDC Python en distinguant :
253       - les commentaires inter commandes
254       - les affectations
255       - les commandes
256     """
257     pattern_commande   = re.compile(r'^([A-Z][A-Z0-9_]+)([ \t\r\f\v]*)\(([\w\W]*)')
258     pattern_eval       = re.compile(r'^(EVAL)([ \t\r\f\v]*)\(([\w\W]*)')
259     pattern_ligne_vide = re.compile(r'^[\t\r\f\v\n]+')
260     pattern_name       = re.compile(r'[a-zA-Z_]\w*')
261     
262     def __init__(self,texte):
263         self.texte = texte
264         self.l_objets=None
265         self.appli=None
266
267     def is_affectation(self,texte):
268         """
269         Méthode booléenne qui retourne 1 si le texte est celui d'une affectation dans un jeu de commandes
270         Aster, 0 sinon
271         """
272         if '=' not in texte : return 0
273         if self.pattern_commande.match(texte):
274             # cas d'une procédure ...
275             return 0
276         amont,aval = string.split(texte,'=',1)
277         aval = string.strip(aval)
278         if self.pattern_commande.match(aval):
279             return 0
280         else:
281             s= string.strip(amont)
282             m= self.pattern_name.match(s)
283             if m is None : return 0
284             if m.start() != 0 :return 0
285             if m.end() != len(s):return 0
286             #print texte,amont,aval
287             return 1
288
289     def is_eval(self,texte):
290         """
291         Méthode booléenne qui retourne 1 si le texte est celui d'une affectation de type EVAL
292         dans un jeu de commandes Aster, 0 sinon
293         """
294         if '=' not in texte : return 0
295         if self.pattern_commande.match(texte):
296             # cas d'une procédure ...
297             return 0
298         amont,aval = string.split(texte,'=',1)
299         aval = string.strip(aval)
300         if not self.pattern_commande.match(aval) : return 0
301         if self.pattern_eval.match(aval):
302             return 1
303         else:
304             return 0
305             
306     def is_commande(self,texte):
307         """
308         Méthode booléenne qui retourne 1 si le texte est celui d'une commande dans un jeu de commandes
309         Aster, 0 sinon
310         """
311         if self.pattern_commande.match(texte):
312             # cas d'une procédure ...
313             return 1
314         # A ce stade il faut avoir un OPER ou une MACRO, bref un '=' !
315         if '=' not in texte : return 0
316         # on a un texte de la forme xxxx = yyyyy
317         # --> reste à analyser yyyy
318         amont,aval = string.split(texte,'=',1)
319         aval = string.strip(aval)
320         if self.pattern_commande.match(aval):
321             return 1
322         else:
323             return 0
324
325     def analyse(self):
326         """
327         Eclate la chaine self.texte en self.l_objets une liste lignes d'instructions
328         et de commentaires (parmi lesquels des instructions "commentarisées").
329         """
330         l_lignes = string.split(self.texte,'\n')
331         commentaire_courant             = None
332         commande_courante               = None
333         affectation_courante            = None
334         commande_commentarisee_courante = None
335         self.l_objets = []
336
337         #initialisation du nombre de parentheses non fermees et de commentaires non termines
338         #Attention a reinitialiser en fin de ligne logique
339         #Une ligne logique peut s'etendre sur plusieurs lignes physiques avec des caracteres de continuation
340         #explicites ou implicites
341         hangingBraces = list(emptyHangingBraces)
342         hangingComments = 0
343
344         #Masquage des commentaires et strings multilignes
345         srcMasked=maskStringsAndComments('\n'.join(l_lignes))
346         #print srcMasked
347         masked_lines=srcMasked.split('\n')
348         lineno=0
349
350         for ligne in l_lignes :
351             line=masked_lines[lineno]
352             lineno=lineno+1
353             #print "ligne:",line
354             # mise a jour du nombre total de parentheses ouvertes (non fermees)
355             # et du nombre de commentaires non termines
356             for i in range(len(implicitContinuationChars)):
357                 contchar = implicitContinuationChars[i]
358                 numHanging = hangingBraces[i]
359                 hangingBraces[i] = numHanging+line.count(contchar[0]) - line.count(contchar[1])
360
361             hangingComments ^= line.count('"""') % 2
362             hangingComments ^= line.count("'''") % 2
363             #print hangingComments,hangingBraces
364             if hangingBraces[0] < 0 or hangingBraces[1] < 0 or hangingBraces[2] < 0: 
365                 raise ParserException()
366
367             if string.strip(ligne) == '':
368                 # il s'agit d'un saut de ligne
369                 # --> on l'ignore
370                 continue
371
372             if pattern_2comments.match(ligne):
373                 #on a trouvé une commande commentarisée : double commentaire sans rien devant à part des blancs
374                 if commentaire_courant:
375                     #Si un commentaire ordinaire est en cours on le termine
376                     commentaire_courant = None
377
378                 if commande_courante :
379                     # on a un objet commentarisé à l'intérieur d'une commande
380                     # --> non traité pour l'instant : on l'ajoute simplement a la commande courante comme
381                     # un commentaire ordinaire
382                     commande_courante.append_text(ligne)
383                 elif commande_commentarisee_courante :
384                     # commande_commentarisee en cours : on ajoute la ligne
385                     commande_commentarisee_courante.append_text(ligne)
386                 else:
387                     # debut de commande commentarisée : on crée un objet commande_commentarisee_courante
388                     commande_commentarisee_courante = COMMANDE_COMMENTARISEE(self)
389                     commande_commentarisee_courante.append_text(ligne)
390
391                 #on passe à la ligne suivante
392                 continue
393
394             if pattern_comment.match(ligne):
395                 #commentaire ordinaire avec seulement des blancs devant
396                 if commande_commentarisee_courante :
397                     # commande_commentarisee en cours : on la clot
398                     commande_commentarisee_courante = None
399
400                 if commande_courante :
401                     # il s'agit d'un commentaire à l'intérieur d'une commande --> on ne fait rien de special
402                     #on l'ajoute au texte de la commande 
403                     commande_courante.append_text(ligne)
404                 elif commentaire_courant :
405                     # il s'agit de la nième ligne d'un commentaire entre deux commandes
406                     # --> on ajoute cette ligne au commentaire courant
407                     commentaire_courant.append_text(ligne)
408                 else :
409                     # il s'agit d'un nouveau commentaire entre deux commandes
410                     # --> on le crée et il devient le commentaire courant
411                     commentaire_courant = COMMENTAIRE(self)
412                     commentaire_courant.append_text(ligne)
413
414                 #on passe à la ligne suivante
415                 continue
416
417             # la ligne contient des données autre qu'un éventuel commentaire
418             if commentaire_courant :
419                 # on clôt un éventuel commentaire courant
420                 commentaire_courant = None
421
422             if commande_commentarisee_courante :
423                 # on clôt une éventuelle commande commentarisee courante
424                 commande_commentarisee_courante = None
425
426             if commande_courante :
427                 #on a une commande en cours. On l'enrichit ou on la termine
428                 commande_courante.append_text(ligne)
429                 if not linecontinueRE.search(line) \
430                    and (hangingBraces == emptyHangingBraces) \
431                    and not hangingComments:
432                     #la commande est terminée 
433                     #print "fin de commande"
434                     self.analyse_reel(commande_courante.texte)
435                     commande_courante = None
436
437                 #on passe à la ligne suivante
438                 continue
439
440             if affectation_courante != None :
441                 #poursuite d'une affectation
442                 affectation_courante.append_text(ligne)
443                 if not linecontinueRE.search(line) \
444                    and (hangingBraces == emptyHangingBraces) \
445                    and not hangingComments:
446                     #L'affectation est terminée
447                     affectation_courante=None
448                 #on passe à la ligne suivante
449                 continue
450
451             # il peut s'agir d'une commande ou d'une affectation ...
452             # ou d'un EVAL !!!
453             if self.is_eval(ligne):
454                 # --> affectation de type EVAL
455                 if affectation_courante : affectation_courante = None
456                 affectation = AFFECTATION_EVAL(self)
457                 affectation.append_text(ligne)
458                 #on passe à la ligne suivante
459                 continue
460
461             if self.is_affectation(ligne):
462                 # --> affectation
463                 text=ligne
464                 #traitement des commentaires en fin de ligne
465                 compos=line.find("#")
466                 if compos > 2:
467                     #commentaire en fin de ligne
468                     #on cree un nouveau commentaire avant le parametre
469                     COMMENTAIRE(self).append_text(ligne[compos:])
470                     text=ligne[:compos]
471                 #si plusieurs instructions separees par des ; sur la meme ligne
472                 inspos=line.find(";")
473                 if inspos > 2:
474                     #on garde seulement la premiere partie de la ligne
475                     #si on a que des blancs apres le point virgule
476                     if string.strip(text[inspos:]) == ";":
477                         text=text[:inspos]
478                     else:
479                         raise FatalError("Eficas ne peut pas traiter plusieurs instructions sur la meme ligne : %s" % ligne)
480
481                 affectation_courante = AFFECTATION(self)
482                 affectation_courante.append_text(text)
483                 if not linecontinueRE.search(line) \
484                    and (hangingBraces == emptyHangingBraces) \
485                    and not hangingComments:
486                     #L'affectation est terminée
487                     affectation_courante=None
488                 #on passe à la ligne suivante
489                 continue
490
491             if self.is_commande(ligne):
492                 # --> nouvelle commande
493                 affectation_courante = None
494                 commande_courante = COMMANDE(self)
495                 commande_courante.append_text(ligne)
496                 #si la commande est complète, on la termine
497                 if not linecontinueRE.search(line) \
498                    and (hangingBraces == emptyHangingBraces) \
499                    and not hangingComments:
500                     #la commande est terminée 
501                     #print "fin de commande"
502                     self.analyse_reel(commande_courante.texte)
503                     commande_courante = None
504                 #on passe à la ligne suivante
505                 continue
506
507     def enleve (self,texte) :
508         """Supprime de texte tous les caracteres blancs, fins de ligne, tabulations
509            Le nouveau texte est retourné
510         """
511         i=0
512         chaine=""
513         while (i<len(texte)):
514           if (texte[i] == " " or texte[i] == "\n" or texte[i] == "\t") :
515              i=i+1
516           else :
517              chaine=chaine+texte[i]
518              i=i+1
519         return chaine 
520             
521     def construit_genea(self,texte):
522         indiceC=0
523         mot=""
524         dict_reel_concept={}
525
526         # traitement pour chaque caractere
527         while (indiceC < len(texte)): 
528            c=texte[indiceC]
529            if ( c == "," or c == "(" or c == ")"):
530               mot=""
531            elif ( c== "="):
532               #on doit trouver derriere soit une valeur soit une parenthese
533               valeur=""
534               nouvelindice=indiceC+1
535               if texte[nouvelindice] != "(":
536                  #pas de parenthese ouvrante derriere un signe =, on a une valeur.
537                  while ( texte[nouvelindice] != "," and texte[nouvelindice] != ")"):
538                     valeur=valeur+texte[nouvelindice]
539                     nouvelindice=nouvelindice+1
540                     if nouvelindice == len(texte) :
541                         nouvelindice=nouvelindice -1
542                         break
543                  if mot in self.appli.liste_simp_reel:
544                     if valeur[0] != "'":
545                        try :
546                          clef=eval(valeur)
547                          if str(clef) != str(valeur) :
548                             dict_reel_concept[clef]=valeur
549                        except :
550                          pass
551                  mot=""
552                  indiceC=nouvelindice
553               else:
554                  #parenthese ouvrante derriere un signe =, on a un tuple de valeur ou de mots cles facteurs.
555                  # s agit -il d un tuple 
556                  if texte[nouvelindice+1] != "(":
557                     #le suivant n'est pas une parenthese ouvrante : on a un tuple de valeurs ou un mot cle facteur
558                     tuple=False
559                     #on avance jusqu'a la fin du tuple de valeurs ou jusqu'a la fin du premier mot cle simple
560                     #contenu dans le mot cle facteur
561                     while ( texte[nouvelindice] != "="):
562                        if texte[nouvelindice] == ")" :
563                           tuple=True
564                           break
565                        else :
566                           nouvelindice=nouvelindice+1
567                           if nouvelindice == len(texte) :
568                              nouvelindice=nouvelindice -1
569                              break
570                     if tuple :
571                        #cas du tuple de valeurs
572                        valeur=texte[indiceC+1:nouvelindice+1]
573                        indiceC=nouvelindice+1 
574                        if mot in self.appli.liste_simp_reel:
575                           valeur=valeur[1:-1]
576                           for val in valeur.split(',') :
577                           # Attention la derniere valeur est""
578                              try :
579                                 if val[0] != "'":
580                                   clef=eval(val)
581                                   if str(clef) != str(val) :
582                                      dict_reel_concept[clef]=val
583                              except :
584                                   pass
585                        mot=""
586                # ou de ( imbriqueés
587                  else :
588                     #cas du mocle facteur simple ou 
589                     mot=""
590            else :
591               mot=mot+texte[indiceC]
592            indiceC=indiceC+1
593         # traitement du dernier inutile
594         # c est un ; 
595         return dict_reel_concept
596
597     def analyse_reel(self,commande) :
598         nomConcept=None
599         # On verifie qu on a bien un OPER
600         # et pas une MACRO
601         if commande.find("=") > commande.find("(") :
602            return
603         if commande.find("=") > 0:
604            #epure1=self.enleve(commande)
605            epure1=pattern_blancs.sub("",commande)
606            nomConcept,corps=epure1.split("=",1)
607            epure2=corps.replace("_F(","(")
608            #nomConcept=epure1.split("=")[0]
609            #index=epure1.find("=")
610            #epure2=epure1[index+1:len(epure1)].replace("_F(","(")
611            #dict_reel_concept=self.construit_genea(epure2)
612            if self.appli:
613              dict_reel_concept=construit_genea(epure2,self.appli.liste_simp_reel)
614            else:
615              dict_reel_concept={}
616         if nomConcept !=None :
617            if len(dict_reel_concept) != 0:
618               self.appli.dict_reels[nomConcept]=dict_reel_concept
619
620     def get_texte(self,appli=None):
621         """
622         Retourne le texte issu de l'analyse
623         """
624         self.appli=appli
625         try:
626             if not self.l_objets : self.analyse()
627             txt=''
628             for obj in self.l_objets:
629                 txt = txt+str(obj)
630         except ParserException:
631             #Impossible de convertir le texte, on le retourne tel que
632             txt=self.texte
633         return txt
634
635 def test():
636   import parseur_python
637   import doctest
638   doctest.testmod(parseur_python)
639
640
641 if __name__ == "__main__" :
642     import time
643     #fichier = 'D:/Eficas_dev/Tests/zzzz100a.comm'
644     fichier = 'U:/Eficas_dev/Tests/test_eval.comm'
645     fichier = '/local/chris/ASTER/Eficas/Eficas1_10/EficasV1/Tests/testcomm/b.comm'
646     fichier = '/local/chris/ASTER/instals/STA8.2/astest/forma12c.comm'
647     fichier = 'titi.comm'
648     fichier = '../Aster/sdls300a.comm'
649     fichier = '../Aster/az.comm'
650     texte = open(fichier,'r').read()
651     class appli:
652        dict_reels={}
653        liste_simp_reel=["VALE","VALE_C","GROUP_MA","RAYON"]
654     a=appli()
655
656     if 1:
657         t0=time.clock()
658         txt = PARSEUR_PYTHON(texte).get_texte(a)
659         print t0,time.clock()-t0
660     else:
661         import hotshot, hotshot.stats
662         prof = hotshot.Profile("stones.prof")
663         txt = prof.runcall(PARSEUR_PYTHON(texte).get_texte,a)
664         prof.close()
665         stats = hotshot.stats.load("stones.prof")
666         stats.strip_dirs()
667         stats.sort_stats('time', 'calls')
668         stats.print_stats(20)
669
670     print txt
671     compile(txt, '<string>', 'exec')
672     print a.dict_reels