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