1 #@ MODIF parseur_python Parsers DATE 05/09/2001 AUTEUR DURAND C.DURAND
2 # CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2001 EDF R&D WWW.CODE-ASTER.ORG
5 # SEE THE FILE "LICENSE.TERMS" FOR INFORMATION ON USAGE AND
6 # REDISTRIBUTION OF THIS FILE.
7 # ======================================================================
11 def __init__(self,pere):
13 pere.l_objets.append(self)
15 def set_text(self,texte):
18 def append_text(self,texte):
20 Ajoute texte à self.texte en mettant un retour chariot à la fin de texte
23 self.texte = self.texte +texte
25 class COMMENTAIRE(ENTITE_JDC):
29 Retourne une chaîne de caractères représentants self
30 sous une forme interprétable par EFICAS
32 s='COMMENTAIRE("""'+self.texte+'""")\n\n'
35 def append_text(self,texte):
37 Ajoute texte à self.texte en enlevant le # initial
41 self.texte = self.texte+texte[1:]
43 # le dièse n'est pas sur le premier caractère
44 amont,aval = string.split(texte,'#',1) # on découpe suivant la première occurrence de #
45 self.texte = self.texte +amont + aval
47 class COMMANDE(ENTITE_JDC):
53 return self.texte+'\n'
57 Retourne la différence entre le nombre de parenthèses ouvrantes
58 et le nombre de parenthèses fermantes présentes dans self.texte
59 Peut donc retourner un entier négatif
61 # faire attention aux commentaires contenus dans self.texte
62 # qui peuvent eux-mêmes contenir des parenthèses !!!!
63 l_lignes = string.split(self.texte,'\n')
65 for ligne in l_lignes:
66 ligne = string.split(ligne,'#')[0]
67 nb = nb + (string.count(ligne,'(')-string.count(ligne,')'))
70 class AFFECTATION(ENTITE_JDC):
72 def append_text(self,texte):
74 Ajoute texte à self.texte en enlevant tout retour chariot et tout point virgule
76 if texte[-1] == '\n' : texte = string.strip(texte[0:-1])
\r
77 if texte[-1] == ';' : texte = string.strip(texte[0:-1])
78 self.texte = self.texte+texte
82 Retourne une expression de l'affectation compréhensible par ACCAS
83 et exploitable par EFICAS
85 nom,valeur = string.split(self.texte,'=',1)
86 nom = string.strip(nom)
87 if valeur[-1] == '\n': valeur = valeur[:-1]
88 valeur = string.strip(valeur)
89 return nom+' = PARAMETRE(nom=\''+nom+'\',valeur="'+valeur+'")\n\n'
91 class COMMANDE_COMMENTARISEE(ENTITE_JDC):
93 def append_text(self,texte):
95 Ajoute texte à self.texte en enlevant les doubles commentaires
97 texte = string.strip(texte)
98 texte = string.strip(texte[2:])
99 self.texte = self.texte+(len(self.texte)>0)*'\n'+texte
103 Retourne une expression de la commande commentarisée compréhensible par ACCAS
104 et exploitable par EFICAS
106 return "COMMANDE_COMM(texte='''"+self.texte+"''')\n"
108 class AFFECTATION_EVAL(ENTITE_JDC):
110 def append_text(self,texte):
112 Ajoute texte à self.texte en enlevant tout retour chariot
114 if texte[-1] == '\n' : texte = texte[1:-1]
115 self.texte = self.texte+texte
119 Retourne une expression du paramètre EVAL compréhensible par ACCAS
120 et exploitable par EFICAS
122 nom,valeur = string.split(self.texte,'=',1)
123 nom = string.strip(nom)
124 if valeur[-1] == '\n': valeur = valeur[:-1]
125 valeur = string.strip(valeur)
126 return nom+' = PARAMETRE_EVAL(nom=\''+nom+'\',valeur=\''+valeur+'\')\n\n'
128 class PARSEUR_PYTHON:
130 Cette classe sert à générer un objet PARSEUR_PYTHON qui réalise l'analyse d'un texte
131 représentant un JDC Python en distinguant :
132 - les commentaires inter commandes
136 pattern_commande = re.compile(r'^([A-Z][A-Z0-9_]+)([ \t\r\f\v]*)\(([\w\W]*)')
137 pattern_eval = re.compile(r'^(EVAL)([ \t\r\f\v]*)\(([\w\W]*)')
138 pattern_ligne_vide = re.compile(r'^[\t\r\f\v\n]+')
140 def __init__(self,texte):
144 def is_affectation(self,texte):
146 Méthode booléenne qui retourne 1 si le texte est celui d'une affectation dans un jeu de commandes
149 if '=' not in texte : return 0
150 if self.pattern_commande.match(texte):
151 # cas d'une procédure ...
153 amont,aval = string.split(texte,'=',1)
154 aval = string.strip(aval)
155 if self.pattern_commande.match(aval):
160 def is_eval(self,texte):
162 Méthode booléenne qui retourne 1 si le texte est celui d'une affectation de type EVAL
163 dans un jeu de commandes Aster, 0 sinon
165 if '=' not in texte : return 0
166 if self.pattern_commande.match(texte):
167 # cas d'une procédure ...
169 amont,aval = string.split(texte,'=',1)
170 aval = string.strip(aval)
171 if not self.pattern_commande.match(aval) : return 0
172 if self.pattern_eval.match(aval):
177 def is_commande(self,texte):
179 Méthode booléenne qui retourne 1 si le texte est celui d'une commande dans un jeu de commandes
182 if self.pattern_commande.match(texte):
183 # cas d'une procédure ...
185 # A ce stade il faut avoir un OPER ou une MACRO, bref un '=' !
186 if '=' not in texte : return 0
187 # on a un texte de la forme xxxx = yyyyy
188 # --> reste à analyser yyyy
189 amont,aval = string.split(texte,'=',1)
190 aval = string.strip(aval)
191 if self.pattern_commande.match(aval):
198 Transforme dans self.fichier les commentaires Python (#...) par un objet
199 commentaire qui pourra donc être interprété par EFICAS.
200 Stocke le résultat dans self.texte
202 #l_lignes = open(self.fichier,'r').readlines()
203 l_lignes = string.split(self.texte,'\n')
204 commentaire_courant = None
205 commande_courante = None
206 affectation_courante = None
207 commande_commentarisee_courante = None
210 for ligne in l_lignes :
212 if string.strip(ligne) == '':
213 # il s'agit d'un saut de ligne
217 liste = string.split(ligne,'##',1)
219 # on a trouvé un double commentaire dans la ligne
221 if string.strip(before) == '':
222 # il s'agit d'une commande commentarisée
223 if commentaire_courant :
224 commentaire_courant = None
225 elif commande_courante :
226 # on a un objet commentarisé à l'intérieur d'une commande
227 # --> non traité pour l'instant
228 commande_courante.append_text(ligne)
229 elif commande_commentarisee_courante :
230 # commande_commentarisee en cours : on ajoute la ligne
231 commande_commentarisee_courante.append_text(ligne)
233 # on crée un objet commande_commentarisee_courante
234 commande_commentarisee_courante = COMMANDE_COMMENTARISEE(self)
235 commande_commentarisee_courante.append_text(ligne)
238 # on a un double commentaire en fin de ligne
239 # --> pour l'instant on ne fait rien
241 new_ligne = string.split(ligne,'#')[0] # on enlève toute la partie commentaire de la ligne
242 new_ligne = string.strip(new_ligne)
244 # la ligne n'est qu'un commentaire précédé d'éventuels blancs
245 if commande_courante :
246 # il s'agit d'un commentaire à l'intérieur d'une commande --> on ne fait rien
247 commande_courante.append_text(ligne)
248 elif commentaire_courant :
249 # il s'agit de la nième ligne d'un commentaire entre deux commandes
250 # --> on ajoute cette ligne au commentaire courant
251 commentaire_courant.append_text(ligne)
253 # il s'agit d'un commentaire entre deux commandes
254 # --> on le crée et il devient le commentaire courant
255 commentaire_courant = COMMENTAIRE(self)
256 commentaire_courant.append_text(ligne)
258 # la ligne contient des données autre qu'un éventuel commentaire
259 if commentaire_courant :
260 # on clôt un éventuel commentaire courant
261 commentaire_courant = None
262 if commande_courante :
263 commande_courante.append_text(ligne)
264 if commande_courante.get_nb_par() == 0:
265 # la commande courante est terminée (autant de parenthèses fermantes qu'ouvrantes)
266 commande_courante = None
268 # il peut s'agir d'une commande ou d'une affectation ...
269 # ou de la poursuite d'une affectation !!!!!
271 if self.is_eval(new_ligne):
272 # --> affectation de type EVAL
273 if affectation_courante : affectation_courante = None
274 affectation = AFFECTATION_EVAL(self)
275 affectation.append_text(ligne)
276 elif self.is_affectation(new_ligne):
278 affectation_courante = AFFECTATION(self)
279 affectation_courante.append_text(ligne)
280 elif self.is_commande(new_ligne):
282 commande_courante = COMMANDE(self)
283 commande_courante.append_text(ligne)
284 affectation_courante = None
285 if commande_courante.get_nb_par() == 0:
286 # la commande courante est terminée (autant de parenthèses fermantes qu'ouvrantes)
287 commande_courante = None
289 #--> poursuite d'une affectation
290 affectation_courante.append_text(ligne)
294 Retourne le texte issu de l'analyse
296 if not self.l_objets : self.analyse()
298 for obj in self.l_objets:
302 if __name__ == "__main__" :
303 #fichier = 'D:/Eficas_dev/Tests/zzzz100a.comm'
304 fichier = 'U:/Eficas_dev/Tests/test_eval.comm'
305 texte = open(fichier,'r').read()
306 txt = PARSEUR_PYTHON(texte).get_texte()