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