# -*- coding: utf-8 -*-
-# Copyright (C) 2007-2013 EDF R&D
+# Copyright (C) 2007-2017 EDF R&D
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+from __future__ import absolute_import
+from __future__ import print_function
+try :
+ from builtins import str
+ from builtins import range
+ from builtins import object
+except :
+ pass
import sys,string,re
import traceback
from Extensions.i18n import tr
+from six.moves import range
escapedQuotesRE = re.compile(r"(\\\\|\\\"|\\\')")
stringsAndCommentsRE = \
re.compile(u"(\"\"\".*?\"\"\"|'''.*?'''|\"[^\"]*\"|\'[^\']*\'|#.*?\n)", re.DOTALL)
#stringsAndCommentsRE = \
# re.compile(u"(\"\"\".*\"\"\"|'''.*'''|\"[^\"]*\"|\'[^\']*\'|#.*\n)", re.DOTALL)
-allchars = string.maketrans(u"", "")
-allcharsExceptNewline = allchars[: allchars.index('\n')]+allchars[allchars.index('\n')+1:]
-allcharsExceptNewlineTranstable = string.maketrans(allcharsExceptNewline, '*'*len(allcharsExceptNewline))
+import six
+if six.PY2 :
+ allchars = string.maketrans(u"", "")
+ allcharsExceptNewline = allchars[: allchars.index('\n')]+allchars[allchars.index('\n')+1:]
+ allcharsExceptNewlineTranstable = string.maketrans(allcharsExceptNewline, '*'*len(allcharsExceptNewline))
+else :
+ allchars=bytes.maketrans(b"",b"")
+ allcharsExceptNewline = allchars[: allchars.index(b'\n')]+allchars[allchars.index(b'\n')+1:]
+ allcharsExceptNewlineTranstable = bytes.maketrans(allcharsExceptNewline, b'*'*len(allcharsExceptNewline))
#if sys.platform[0:5]=="linux" :
# allcharsExceptNewlineTranstable = string.maketrans(allcharsExceptNewline, '*'*len(allcharsExceptNewline))
# supprime toutes les chaines ou commentaires ,y compris multiligne i
# entre 3 ou 1 simples ou doubles quotes (ouvrantes fermantes) ou #
# laisse les non fermantes ou non ouvrantes
- #src = escapedQuotesRE.sub(u"**", src)
- # le u met le bazar dans le translate
+# on prend 1 sur 2 en raison du split qui donne python, commentaire, python, commentaire...
+
src = escapedQuotesRE.sub("**", src)
allstrings = stringsAndCommentsRE.split(src)
- # every odd element is a string or comment
- for i in xrange(1, len(allstrings), 2):
+
+ # on a une liste d elements constituee successivement de (string, comment)
+ for i in range(1, len(allstrings), 2):
if allstrings[i].startswith(u"'''")or allstrings[i].startswith('"""'):
allstrings[i] = allstrings[i][:3]+ \
allstrings[i][3:-3].translate(allcharsExceptNewlineTranstable)+ \
linecontinueRE = re.compile(r"\\\s*(#.*)?$")
emptyHangingBraces = [0,0,0,0,0]
-class ParserException(Exception): pass
+class parserException(Exception): pass
class FatalError(Exception): pass
#commentaire double precede d'un nombre quelconque de blancs (pas multiligne)
)
""",re.VERBOSE|re.MULTILINE)
-def construit_genea(texte,liste_mc):
+def construitGenea(texte,listeMc):
"""
Retourne un dictionnaire dont les cles sont des reels et les valeurs sont leurs representations textuelles.
Realise un filtrage sur les reels :
- Ne garde que les reels pour lesquels str ne donne pas une bonne representation.
- - Ne garde que les reels derriere un argument keyword dont le nom est dans liste_mc
+ - Ne garde que les reels derriere un argument keyword dont le nom est dans listeMc
>>> 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),
... #POMPE_PRIMA._BOUCLE_N._2_ELEMENT_NUMERO:0239
... h=_F(x=34.6,y=-1)'''
- >>> construit_genea(s,['a','x'])
+ >>> construitGenea(s,['a','x'])
{0.000213: '21.3e-5'}
"""
d={}
#argument keyword
mot=m[:-1]
else:
- if mot not in liste_mc:continue
+ if mot not in listeMc:continue
#valeur
key=eval(m)
if str(key) != m: d[key]=m
return d
-class ENTITE_JDC :
- """Classe de base pour tous les objets créés lors de la conversion
- Tout objet dérivé est enregistré aupres de son pere a sa création
+class ENTITE_JDC(object) :
+ """Classe de base pour tous les objets crees lors de la conversion
+ Tout objet derive est enregistre aupres de son pere a sa creation
"""
def __init__(self,pere):
self.texte = ''
pere.l_objets.append(self)
- def set_text(self,texte):
+ def setText(self,texte):
self.texte = texte
- def append_text(self,texte):
+ def appendText(self,texte):
"""
Ajoute texte a self.texte en mettant un retour chariot a la fin de texte
"""
def __str__(self):
"""
- Retourne une chaine de caracteres représentants self
- sous une forme interprétable par EFICAS
+ Retourne une chaine de caracteres representants self
+ sous une forme interpretable par EFICAS
"""
t=repr(self.texte)
return "COMMENTAIRE(u"+t+")\n"
#s='COMMENTAIRE(u"""'+self.texte+'""")\n\n'
#return s
- def append_text(self,texte):
+ def appendText(self,texte):
"""
Ajoute texte a self.texte en enlevant le # initial
"""
self.texte = self.texte+texte[1:]
else:
# le diese n'est pas sur le premier caractere
- amont,aval = string.split(texte,'#',1) # on découpe suivant la premiere occurrence de #
+ amont,aval = texte.split('#',1) # on decoupe suivant la premiere occurrence de #
self.texte = self.texte +amont + aval
class COMMANDE(ENTITE_JDC):
"""
return self.texte+'\n'
- def get_nb_par(self):
+ def getNbPar(self):
"""
- Retourne la différence entre le nombre de parentheses ouvrantes
- et le nombre de parentheses fermantes présentes dans self.texte
- Peut donc retourner un entier négatif
+ Retourne la difference entre le nombre de parentheses ouvrantes
+ et le nombre de parentheses fermantes presentes dans self.texte
+ Peut donc retourner un entier negatif
"""
# faire attention aux commentaires contenus dans self.texte
# qui peuvent eux-memes contenir des parentheses !!!!
- l_lignes = string.split(self.texte,'\n')
+ l_lignes = self.texte.split('\n')
nb = 0
for ligne in l_lignes:
- ligne = string.split(ligne,'#')[0]
- nb = nb + (string.count(ligne,'(')-string.count(ligne,')'))
+ ligne = ligne.split('#')[0]
+ #nb = nb + (string.count(ligne,'(')-string.count(ligne,')'))
+
+ nb = nb + ( ligne.count('(') - ligne.count(')') )
return nb
class AFFECTATION(ENTITE_JDC):
- def append_text(self,texte):
+ def appendText(self,texte):
"""
Ajoute texte a self.texte en enlevant tout retour chariot et tout point virgule
PN et tout commentaire
"""
- if texte[-1] == '\n' : texte = string.rstrip(texte[0:-1])
- if texte[-1] == ';' : texte = string.rstrip(texte[0:-1])
+ if texte[-1] == '\n' : texte = texte[0:-1].rstrip()
+ if texte[-1] == ';' : texte = texte[0:-1].rstrip()
self.texte = self.texte+texte+'\n'
def __str__(self):
"""
- Retourne une expression de l'affectation compréhensible par ACCAS
+ Retourne une expression de l'affectation comprehensible par ACCAS
et exploitable par EFICAS
"""
- nom,valeur = string.split(self.texte,'=',1)
- n = string.rstrip(nom)
- nom = string.lstrip(n)
+ nom,valeur = self.texte.split('=',1)
+ n = nom.rstrip()
+ nom = n.lstrip()
if valeur[-1] == '\n': valeur = valeur[:-1]
return n + ' = PARAMETRE(nom=\''+nom+'\',valeur='+valeur+')\n'
class COMMANDE_COMMENTARISEE(ENTITE_JDC):
- def append_text(self,texte):
+ def appendText(self,texte):
"""
Ajoute texte a self.texte en enlevant les doubles commentaires
"""
- texte = string.strip(texte)
- texte = string.strip(texte[2:])
+ texte = texte.strip()
+ texte = texte[2:].strip()
self.texte = self.texte+(len(self.texte)>0)*'\n'+texte
def __str__(self):
"""
- Retourne une expression de la commande commentarisée compréhensible par ACCAS
+ Retourne une expression de la commande commentarisee comprehensible par ACCAS
et exploitable par EFICAS
"""
return "COMMANDE_COMM(texte="+repr(self.texte)+")\n"
class AFFECTATION_EVAL(ENTITE_JDC):
- def append_text(self,texte):
+ def appendText(self,texte):
"""
Ajoute texte a self.texte en enlevant tout retour chariot
"""
def __str__(self):
"""
- Retourne une expression du parametre EVAL compréhensible par ACCAS
+ Retourne une expression du parametre EVAL comprehensible par ACCAS
et exploitable par EFICAS
"""
- nom,valeur = string.split(self.texte,'=',1)
- nom = string.strip(nom)
+ nom,valeur = self.texte.split('=',1)
+ nom = nom.strip()
if valeur[-1] == '\n': valeur = valeur[:-1]
- valeur = string.strip(valeur)
+ valeur = valeur.strip()
return nom+' = PARAMETRE_EVAL(nom=\''+nom+'\',valeur=\''+valeur+'\')\n\n'
-class PARSEUR_PYTHON:
+class PARSEUR_PYTHON(object):
"""
- Cette classe sert a générer un objet PARSEUR_PYTHON qui réalise l'analyse d'un texte
- représentant un JDC Python en distinguant :
+ Cette classe sert a generer un objet PARSEUR_PYTHON qui realise l'analyse d'un texte
+ representant un JDC Python en distinguant :
- les commentaires inter commandes
- les affectations
- les commandes
"""
- pattern_commande = re.compile(r'^([A-Z][A-Z0-9_]+)([ \t\r\f\v]*)\(([\w\W]*)')
+ pattern_commande = re.compile(r'^([A-Z][a-zA-Z0-9_]+)([ \t\r\f\v]*)\(([\w\W]*)')
pattern_eval = re.compile(r'^(EVAL)([ \t\r\f\v]*)\(([\w\W]*)')
pattern_ligne_vide = re.compile(r'^[\t\r\f\v\n]+')
pattern_name = re.compile(r'[a-zA-Z_]\w*')
self.l_objets=None
self.appli=None
- def is_affectation(self,texte):
+ def isAffectation(self,texte):
"""
- Méthode booléenne qui retourne 1 si le texte est celui d'une affectation dans un jeu de commandes
+ Methode booleenne qui retourne 1 si le texte est celui d'une affectation dans un jeu de commandes
Aster, 0 sinon
"""
if '=' not in texte : return 0
if self.pattern_commande.match(texte):
- # cas d'une procédure ...
+ # cas d'une procedure ...
return 0
- amont,aval = string.split(texte,'=',1)
- aval = string.strip(aval)
+ amont,aval = texte.split('=',1)
+ aval = aval.strip()
+
+
if self.pattern_commande.match(aval):
return 0
else:
- s= string.strip(amont)
+ s= amont.strip()
m= self.pattern_name.match(s)
if m is None : return 0
if m.start() != 0 :return 0
if m.end() != len(s):return 0
return 1
- def is_eval(self,texte):
+ def isEval(self,texte):
"""
- Méthode booléenne qui retourne 1 si le texte est celui d'une affectation de type EVAL
+ Methode booleenne qui retourne 1 si le texte est celui d'une affectation de type EVAL
dans un jeu de commandes Aster, 0 sinon
"""
if '=' not in texte : return 0
if self.pattern_commande.match(texte):
- # cas d'une procédure ...
+ # cas d'une procedure ...
return 0
- amont,aval = string.split(texte,'=',1)
- aval = string.strip(aval)
+ amont,aval = texte.split('=',1)
+ aval = aval.strip()
if not self.pattern_commande.match(aval) : return 0
if self.pattern_eval.match(aval):
return 1
else:
return 0
- def is_commande(self,texte):
+ def isCommande(self,texte):
"""
- Méthode booléenne qui retourne 1 si le texte est celui d'une commande dans un jeu de commandes
+ Methode booleenne qui retourne 1 si le texte est celui d'une commande dans un jeu de commandes
Aster, 0 sinon
"""
if self.pattern_commande.match(texte):
- # cas d'une procédure ...
+ # cas d'une procedure ...
return 1
# A ce stade il faut avoir un OPER ou une MACRO, bref un '=' !
if '=' not in texte : return 0
# on a un texte de la forme xxxx = yyyyy
# --> reste a analyser yyyy
- amont,aval = string.split(texte,'=',1)
- aval = string.strip(aval)
+ amont,aval = texte.split('=',1)
+ aval = aval.strip()
if self.pattern_commande.match(aval):
return 1
else:
return 0
- def is_modification_catalogue(self,texte) :
+ def isModificationCatalogue(self,texte) :
if self.pattern_commande.match(texte):
return 1
def analyse(self):
"""
Eclate la chaine self.texte en self.l_objets une liste lignes d'instructions
- et de commentaires (parmi lesquels des instructions "commentarisées").
+ et de commentaires (parmi lesquels des instructions "commentarisees").
"""
- l_lignes = string.split(self.texte,'\n')
+ l_lignes = self.texte.split('\n')
commentaire_courant = None
commande_courante = None
affectation_courante = None
hangingComments ^= line.count(u"'''") % 2
#print (hangingComments,hangingBraces)
if hangingBraces[0] < 0 or hangingBraces[1] < 0 or hangingBraces[2] < 0:
- raise ParserException()
+ raise parserException()
- if string.strip(ligne) == '':
+ if ligne.strip() == '':
# il s'agit d'un saut de ligne
# --> on l'ignore
continue
if pattern_2comments.match(ligne):
- #on a trouvé une commande commentarisée : double commentaire sans rien devant a part des blancs
+ #on a trouve une commande commentarisee : double commentaire sans rien devant a part des blancs
if commentaire_courant:
#Si un commentaire ordinaire est en cours on le termine
commentaire_courant = None
if commande_courante :
- # on a un objet commentarisé a l'intérieur d'une commande
- # --> non traité pour l'instant : on l'ajoute simplement a la commande courante comme
+ # on a un objet commentarise a l'interieur d'une commande
+ # --> non traite pour l'instant : on l'ajoute simplement a la commande courante comme
# un commentaire ordinaire
- commande_courante.append_text(ligne)
+ commande_courante.appendText(ligne)
elif commande_commentarisee_courante :
# commande_commentarisee en cours : on ajoute la ligne
- commande_commentarisee_courante.append_text(ligne)
- # on a 2 commandes commentarisées de suite
+ commande_commentarisee_courante.appendText(ligne)
+ # on a 2 commandes commentarisees de suite
if pattern_finComments.match(ligne) :
commande_commentarisee_courante = None
else:
- # debut de commande commentarisée : on crée un objet commande_commentarisee_courante
+ # debut de commande commentarisee : on cree un objet commande_commentarisee_courante
commande_commentarisee_courante = COMMANDE_COMMENTARISEE(self)
- commande_commentarisee_courante.append_text(ligne)
+ commande_commentarisee_courante.appendText(ligne)
#on passe a la ligne suivante
continue
commande_commentarisee_courante = None
if commande_courante :
- # il s'agit d'un commentaire a l'intérieur d'une commande --> on ne fait rien de special
+ # il s'agit d'un commentaire a l'interieur d'une commande --> on ne fait rien de special
#on l'ajoute au texte de la commande
- commande_courante.append_text(ligne)
+ commande_courante.appendText(ligne)
elif commentaire_courant :
# il s'agit de la nieme ligne d'un commentaire entre deux commandes
# --> on ajoute cette ligne au commentaire courant
- commentaire_courant.append_text(ligne)
+ commentaire_courant.appendText(ligne)
else :
# il s'agit d'un nouveau commentaire entre deux commandes
- # --> on le crée et il devient le commentaire courant
+ # --> on le cree et il devient le commentaire courant
commentaire_courant = COMMENTAIRE(self)
- commentaire_courant.append_text(ligne)
+ commentaire_courant.appendText(ligne)
#on passe a la ligne suivante
continue
- # la ligne contient des données autre qu'un éventuel commentaire
+ # la ligne contient des donnees autre qu'un eventuel commentaire
if commentaire_courant :
- # on clot un éventuel commentaire courant
+ # on clot un eventuel commentaire courant
commentaire_courant = None
if commande_commentarisee_courante :
- # on clot une éventuelle commande commentarisee courante
+ # on clot une eventuelle commande commentarisee courante
commande_commentarisee_courante = None
if commande_courante :
#on a une commande en cours. On l'enrichit ou on la termine
- commande_courante.append_text(ligne)
+ commande_courante.appendText(ligne)
if not linecontinueRE.search(line) \
and (hangingBraces == emptyHangingBraces) \
and not hangingComments:
- #la commande est terminée
- self.analyse_reel(commande_courante.texte)
+ #la commande est terminee
+ self.analyseReel(commande_courante.texte)
commande_courante = None
#on passe a la ligne suivante
if affectation_courante != None :
#poursuite d'une affectation
- affectation_courante.append_text(ligne)
+ affectation_courante.appendText(ligne)
if not linecontinueRE.search(line) \
and (hangingBraces == emptyHangingBraces) \
and not hangingComments:
- #L'affectation est terminée
+ #L'affectation est terminee
affectation_courante=None
#on passe a la ligne suivante
continue
# il peut s'agir d'une commande ou d'une affectation ...
# ou d'un EVAL !!!
- if self.is_eval(ligne):
+ if self.isEval(ligne):
# --> affectation de type EVAL
if affectation_courante : affectation_courante = None
affectation = AFFECTATION_EVAL(self)
- affectation.append_text(ligne)
+ affectation.appendText(ligne)
#on passe a la ligne suivante
continue
- if self.is_affectation(ligne):
- # --> affectation
+ if self.isAffectation(ligne):
+ #print( '--> affectation')
text=ligne
#traitement des commentaires en fin de ligne
compos=line.find(u"#")
if compos > 2:
#commentaire en fin de ligne
#on cree un nouveau commentaire avant le parametre
- COMMENTAIRE(self).append_text(ligne[compos:])
+ COMMENTAIRE(self).appendText(ligne[compos:])
text=ligne[:compos]
#si plusieurs instructions separees par des ; sur la meme ligne
inspos=line.find(u";")
if inspos > 2:
#on garde seulement la premiere partie de la ligne
#si on a que des blancs apres le point virgule
- if string.strip(text[inspos:]) == ";":
+ if text[inspos:].strip() == ";":
text=text[:inspos]
else:
raise FatalError(tr("Eficas ne peut pas traiter plusieurs instructions \
sur la meme ligne : %s", ligne))
affectation_courante = AFFECTATION(self)
- affectation_courante.append_text(text)
+ affectation_courante.appendText(text)
if not linecontinueRE.search(line) \
and (hangingBraces == emptyHangingBraces) \
and not hangingComments:
- #L'affectation est terminée
+ #L'affectation est terminee
affectation_courante=None
#on passe a la ligne suivante
continue
- if self.is_commande(ligne):
+ if self.isCommande(ligne):
# --> nouvelle commande
affectation_courante = None
commande_courante = COMMANDE(self)
- commande_courante.append_text(ligne)
+ commande_courante.appendText(ligne)
#si la commande est complete, on la termine
if not linecontinueRE.search(line) \
and (hangingBraces == emptyHangingBraces) \
and not hangingComments:
#la commande est terminee
- self.analyse_reel(commande_courante.texte)
+ self.analyseReel(commande_courante.texte)
commande_courante = None
#on passe a la ligne suivante
continue
i=i+1
return chaine
- def construit_genea(self,texte):
+ def construitGenea(self,texte):
indiceC=0
mot=""
dict_reel_concept={}
# c est un ;
return dict_reel_concept
- def analyse_reel(self,commande) :
+ def analyseReel(self,commande) :
nomConcept=None
# On verifie qu on a bien un OPER
# et pas une MACRO
#nomConcept=epure1.split(u"=")[0]
#index=epure1.find(u"=")
#epure2=epure1[index+1:len(epure1)].replace(u"_F(u","(u")
- #dict_reel_concept=self.construit_genea(epure2)
+ #dict_reel_concept=self.construitGenea(epure2)
if self.appli:
- dict_reel_concept=construit_genea(epure2,self.appli.liste_simp_reel)
+ dict_reel_concept=construitGenea(epure2,self.appli.liste_simp_reel)
else:
dict_reel_concept={}
if nomConcept == "sansnom" :
if len(dict_reel_concept) != 0:
self.appli.dict_reels[nomConcept]=dict_reel_concept
- def get_texte(self,appli=None):
+ def getTexte(self,appli=None):
"""
Retourne le texte issu de l'analyse
"""
for obj in self.l_objets:
txt = txt+str(obj)
#else :
- except ParserException:
+ except parserException:
#Impossible de convertir le texte, on le retourne tel que
txt=self.texte
return txt
def test():
- import parseur_python
+ #import parseur_python
import doctest
doctest.testmod(parseur_python)
if __name__ == "__main__" :
import time
#fichier = 'D:/Eficas_dev/Tests/zzzz100a.comm'
- fichier = 'U:/Eficas_dev/Tests/test_eval.comm'
- fichier = '/local/chris/ASTER/Eficas/Eficas1_10/EficasV1/Tests/testcomm/b.comm'
- fichier = '/local/chris/ASTER/instals/STA8.2/astest/forma12c.comm'
- fichier = 'titi.comm'
- fichier = '../Aster/sdls300a.comm'
- fichier = '../Aster/az.comm'
+ #fichier = 'U:/Eficas_dev/Tests/test_eval.comm'
texte = open(fichier,'r').read()
- class appli:
+ class appli(object):
dict_reels={}
liste_simp_reel=["VALE","VALE_C","GROUP_MA","RAYON"]
a=appli()
compile(txt, '<string>', 'exec')
- print (a.dict_reels)
+ print((a.dict_reels))