Salome HOME
200f59942a8ea5fa1b15e804c94d344f9273bc21
[tools/eficas.git] / Editeur / analyse_catalogue.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2021   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 from __future__ import absolute_import
21 from __future__ import print_function
22 try :
23     from builtins import str
24     from builtins import object
25 except :
26     pass
27
28 import re,six.moves.cPickle,os
29
30 from Extensions.i18n import tr
31 from Noyau.N_CR import CR
32
33
34 #
35 __Id__="$Id: analyseCatalogue.py,v 1.9.8.1.2.1.2.6 2014-01-23 09:14:44 pnoyret Exp $"
36 __version__="$Name:  $"
37 #
38 l_noms_commandes = ['OPER','PROC','MACRO','FORM']
39 l_noms_composes=['FACT','BLOC','NUPL','FORM']
40 l_noms_simples=['SIMP',]
41 l_noms=l_noms_composes+l_noms_simples
42
43 def elimineCommentaires(text):
44     """ Elimine les lignes de commentaires dans text
45     Attention : supprime sauvagement tous les caracteres entre # et le retour chariot ..."""
46     comments = re.compile(r'#[^\n]*')
47     return comments.sub(u'',text)
48
49 def chercheNom(text):
50     Whitespace = r'[ \f\t]*'
51     Name = r'[a-zA-Z_]\w*'
52     myexpr = '(u'+Name+')'+Whitespace+'='+Whitespace+'$'
53     a=re.search(myexpr,text)
54     return a.group(1)
55
56 def chercheArgs(text):
57     text = text.strip()
58     longueur = len(text)
59     if text[0] != '(u':
60         return 'erreur !'
61     else :
62         nbpar = 1
63         for i in range(1,longueur) :
64             if text[i] =='(u':
65                 nbpar = nbpar + 1
66             elif text[i] == ')':
67                 nbpar = nbpar - 1
68             else :
69                 continue
70             if nbpar == 0:
71                 break
72         if nbpar != 0 :
73             return tr('Erreur ! Erreur !')
74         else :
75             try :
76                 return text[1:i],text[i+1:] # on enleve les premiere et derniere parentheses
77             except :
78                 return text[1:i],''
79
80 class ENTITE(object):
81     def chercheEnfants(self):
82         try :
83             self.text = self.text.strip()
84             liste = re.split(u'=',self.text,1)
85             if len(liste)>1 :
86                 arg1=liste[0]
87                 reste=liste[1]
88                 reste = reste.strip()
89                 if reste[0:4] in l_noms :
90                     nom_mc = chercheNom(arg1+'=')
91                     arg_mc, self.text = chercheArgs(reste[4:])
92                     self.creeMc(nom_mc,arg_mc,reste[0:4])
93                 else :
94                     self.text = reste
95                 self.chercheEnfants()
96             else :
97                 # pas de = rencontre
98                 return
99         except Exception as e:
100             self.cr.fatal(tr("Erreur rencontree dans rechercheEnfants : %s", e.__str()))
101
102     def creeMc(self,nom_mc,arg_mc,test):
103         if test in l_noms_composes :
104             mc = FACT_CATA(nom_mc,arg_mc,self)
105             self.children.append(mc)
106         elif test in l_noms_simples :
107             mc = SIMP_CATA(nom_mc,self)
108             self.children.append(mc)
109         else :
110             print (tr("Erreur dans la creation du mot-cle : %s", nom_mc) )
111
112     def construitListeDico(self):
113         l=[]
114         d={}
115         if len(self.children)==0:
116             self.ordre_mc = l
117             self.entites = d
118             return
119         try :
120             for child in self.children:
121                 l.append(child.nom)
122                 d[child.nom]=child
123             self.ordre_mc = l
124             self.entites = d
125         except:
126             print (("erreur : ", self.nom,  self.__class__))
127
128 class COMMANDE_CATA(ENTITE) :
129     def __init__(self,nom,args,parent):
130         self.nom = nom
131         self.args = args
132         self.children = []
133         self.text = args
134         self.cr = CR()
135         self.cr.debut = "Debut commande %s" %self.nom
136         self.cr.fin = "Fin commande %s" %self.nom
137         self.chercheEnfants()
138         self.construitListeDico()
139         parent.cr.add(self.cr)
140
141     def affiche(self):
142         texte_cmd = '\n'
143         texte_cmd = texte_cmd + 'Commande :' + self.nom + '\n'
144         for child in self.children :
145             texte_cmd = texte_cmd + child.affiche(1)
146         return texte_cmd
147
148 class SIMP_CATA(object) :
149     def __init__(self,nom,parent):
150         self.nom = nom
151         self.cr = CR()
152         self.cr.debut = "Debut mot-cle simple %s" %self.nom
153         self.cr.fin = "Fin mot-cle simple %s" %self.nom
154         parent.cr.add(self.cr)
155
156     def affiche(self,ind):
157         sep = ' '*5
158         return sep*ind+self.nom+'\n'
159
160 class FACT_CATA(ENTITE) :
161     def __init__(self,nom,args,parent):
162         self.nom=nom
163         self.args=args
164         self.children = []
165         self.text=args
166         self.cr = CR()
167         self.cr.debut = "Debut mot-cle facteur ou bloc %s" %self.nom
168         self.cr.fin = "Fin mot-cle facteur ou bloc %s" %self.nom
169         self.chercheEnfants()
170         self.construitListeDico()
171         parent.cr.add(self.cr)
172
173     def affiche(self,ind):
174         sep = ' '*5
175         text = ''
176         text = text + sep*ind+self.nom+'\n'
177         for child in self.children :
178             text = text + child.affiche(ind+1)
179         return text
180
181 class CATALOGUE_CATA(object):
182     def __init__(self,parent,fichier):
183         self.parent = parent
184         self.fichier=fichier
185         self.cr = CR()
186         self.cr.debut = "Debut compte-rendu catalogue %s" %self.fichier
187         self.cr.fin = "Fin compte-rendu catalogue %s" %self.fichier
188         self.ouvrirFichier()
189         self.liste_commandes=[]
190         self.liste_textes_commandes=[]
191
192     def ouvrirFichier(self):
193         try :
194             with open(self.fichier) as fd:
195                 self.texte_complet=fd.read()
196         except :
197             print((tr("Impossible d'ouvrir le fichier : %s ", str(self.fichier))))
198             self.cr.fatal(tr("Impossible d'ouvrir le fichier : %s ", str(self.fichier)))
199
200     def constrListTxtCmd(self,text):
201         text = elimineCommentaires(text)
202         pattern = '\) *;'
203         liste=re.split(pattern,text)
204         for i in range(0,len(liste)-1):
205             self.liste_textes_commandes.append(liste[i]+')')
206
207     def analyseCommandeOld(self,text):
208         liste = re.split(u'OPER *\(u',text,1)
209         if len(liste) < 2 :
210             liste = re.split(u'PROC *\(u',text,1)
211         if len(liste) < 2 :
212             liste = re.split(u'MACRO *\(u',text,1)
213         if len(liste) < 2 :
214             print ((tr("le texte a analyser n'est pas celui d'une commande ou d'un operateur : "), text))
215             self.cr.fatal(tr("le texte a analyser n'est pas celui d'une commande ou \
216                              d'un operateur : %s", text))
217             return
218         debut = liste[0]
219         fin = liste[1]
220         nom_cmd = chercheNom(debut)
221         if nom_cmd == 'erreur !':
222             print((tr("Erreur dans la recherche  du nom de la commande : "), debut))
223         args_cmd,toto = chercheArgs(u'(u'+fin)
224         if args_cmd == 'erreur !':
225             print((tr("Erreur dans la recherche des  args de la commande :") , debut))
226         cmd=COMMANDE_CATA(nom_cmd,args_cmd,self)
227         self.liste_commandes.append(cmd)
228
229     def analyseCommande(self,text):
230         for nom_cmd in l_noms_commandes:
231             liste = re.split(nom_cmd+' *\(u',text,1)
232             if len(liste) == 2 : break
233         if len(liste) < 2 :
234             print((tr("le texte a analyser n'est pas celui d'une commande connue : \
235                             %(v_1)s %(v_2)s", {'v_1': str(l_noms_commandes), 'v_2': text})))
236             self.cr.fatal(tr("le texte a analyser n'est pas celui d'une commande connue : \
237                              %(v_1)s %(v_2)s", {'v_1': str(l_noms_commandes), 'v_2': text}))
238             return
239         debut = liste[0]
240         fin = liste[1]
241         nom_cmd = chercheNom(debut)
242         if nom_cmd == 'erreur !':
243             print(( tr("Erreur dans la recherche du  nom de la commande : "), debut))
244         args_cmd,toto = chercheArgs(u'(u'+fin)
245         if args_cmd == 'erreur !':
246             print(( tr("Erreur dans la recherche des args de la commande : "), debut))
247             print((tr(fin)))
248         cmd=COMMANDE_CATA(nom_cmd,args_cmd,self)
249         self.liste_commandes.append(cmd)
250
251     def analyseTexte(self,texte):
252         self.constrListTxtCmd(texte)
253         try:
254             self.parent.configure_barre(len(self.liste_textes_commandes))
255         except:
256             pass
257         for texte_commande in self.liste_textes_commandes :
258             try:
259                 self.parent.update_barre()
260             except:
261                 pass
262             self.analyseCommande(texte_commande)
263         self.construitListeDico()
264
265     def ecritLcmd(self):
266         f=open(u'U:\\EFICAS\\Accas\\cata.txt','w')
267         for cmd in self.liste_commandes :
268             f.write(cmd.affiche())
269         f.close()
270
271     def construitListeDico(self):
272         l=[]
273         d={}
274         for cmd in self.liste_commandes:
275             l.append(cmd.nom)
276             d[cmd.nom]=cmd
277         self.ordre_mc = l
278         self.entites = d
279
280     def report(self):
281         """ retourne l'objet rapport du catalogue de commande """
282         return self.cr
283
284 def analyseCatalogue(parent,nom_cata):
285     cata = CATALOGUE_CATA(parent,nom_cata)
286     cata.analyseTexte(cata.texte_complet)
287     return cata
288
289 def analyseCatalogueCommande(parent,nom_cata):
290     cata = CATALOGUE_CATA(parent,nom_cata)
291     cata.analyseCommande(cata.texte_complet)
292     cata.construitListeDico()
293     return cata
294
295
296 def makeCataPickle(ficCata):
297     """
298     Lance l'analyse de l'ordre des mots-cles dans le catalogue dont le nom
299     est passe en argument et sauvegarde ces infos dans le fichier pickle relu
300     par Eficas
301     """
302     ficCata_p = os.path.splitext(ficCata)[0]+'_pickled.py'
303     cata_ordonne = analyseCatalogue(None,ficCata)
304     f = open(ficCata_p,'w+')
305     p = six.moves.cPickle.Pickler(f)
306     p.dump(cata_ordonne.entites)
307     f.close()
308
309 if __name__ == "__main__" :
310     import profile
311     profile.run(u"analyseCatalogue(None,'U:\\EFICAS\\Cata\\cata_saturne.py')")