--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+"""
+ Ce package contient tous les convertisseurs de formats d'entree
+ en objets comprehensibles par EFICAS.
+
+ Ces convertisseurs sont implementes sous forme de plugins
+"""
+
+from __future__ import absolute_import
+from Extensions import pluginloader
+
+import convert
+
+plugins=pluginloader.PluginLoader(convert)
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+from __future__ import absolute_import
+from __future__ import print_function
+try :
+ from future import standard_library
+ standard_library.install_aliases()
+except :
+ pass
+try :
+ from builtins import str
+except :
+ pass
+from builtins import object
+import sys,re,tokenize
+import io
+
+
+class ENTITE_JDC(object) :
+ def __init__(self):
+ self.texte = ''
+
+ def setText(self,texte):
+ self.texte = texte
+
+ def appendText(self,texte):
+ """
+ """
+ self.texte = self.texte +texte
+
+class COMMENTAIRE(ENTITE_JDC):
+
+ def __str__(self):
+ """
+ Retourne une chaine de caracteres representant self
+ sous une forme interpretable par EFICAS
+ """
+ t=repr(self.texte)
+ return "COMMENTAIRE(u"+t+")\n"
+
+ def appendText(self,texte):
+ """
+ Ajoute texte a self.texte en enlevant le # initial
+ """
+ if texte[0] == '#':
+ self.texte = self.texte+texte[1:]
+ else:
+ # le diese n'est pas sur le premier caractere
+ amont,aval = texte.split('#',1) # on decoupe suivant la premiere occurrence de #
+ self.texte = self.texte +amont + aval
+
+class AFFECTATION(ENTITE_JDC):
+
+ def appendText(self,texte):
+ """
+ Ajoute texte a self.texte en enlevant tout retour chariot et tout point virgule
+ """
+ self.texte = self.texte+texte
+
+ def __str__(self):
+ """
+ Retourne une expression de l'affectation comprehensible par ACCAS
+ et exploitable par EFICAS
+ """
+ #t=repr(self.texte)
+ t=self.texte
+ return "PARAMETRE(nom='"+self.name+"',valeur="+t+")"
+
+class COMMANDE_COMMENTARISEE(ENTITE_JDC):
+
+ def appendText(self,texte):
+ """
+ Ajoute texte a self.texte en enlevant les doubles commentaires
+ """
+ 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 commentarisee comprehensible par ACCAS
+ et exploitable par EFICAS
+ """
+ return "COMMANDE_COMM(texte="+repr(self.texte)+")\n"
+
+
+next = {}
+next['if'] = next['elif'] = 'elif', 'else', 'end'
+next['while'] = next['for'] = 'else', 'end'
+next['try'] = 'except', 'finally'
+next['except'] = 'except', 'else', 'end'
+next['else'] = next['finally'] = next['def'] = next['class'] = 'end'
+next['end'] = ()
+start = 'if', 'while', 'for', 'try', 'def', 'class'
+
+class PARSEUR_PYTHON(object):
+ """
+ Cette classe sert a creer 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
+ """
+ # au moins 1 caractere non blanc ou non tabulation
+ #pattern_ligne_non_blanche = re.compile(r'^[\w\t]+')
+ pattern_ligne_non_blanche = re.compile(r'[^ \t]+')
+ kwprog = re.compile(
+ r'^\s*(?P<kw>[a-z]+)'
+ r'(\s+(?P<id>[a-zA-Z_]\w*))?'
+ r'[^\w]')
+ endprog = re.compile(
+ r'^\s*#?\s*end\s+(?P<kw>[a-z]+)'
+ r'(\s+(?P<id>[a-zA-Z_]\w*))?'
+ r'[^\w]')
+ wsprog = re.compile(r'^[ \t]*')
+ optionprog=re.compile(r'#\s*parse:\s*([^\n\'"]*)$')
+
+ def __init__(self,texte):
+ # on verifie que le texte fourni se compile correctement
+ compile(texte,"<string>",'exec')
+ self.texte = io.StringIO(texte)
+ self.line=''
+ self.out=""
+ self.lastcol = 0
+ self.lastrow = 1
+ self.please_indent = 1
+ self.indent_list = []
+ self.indentation=0
+ self.paren_level=0
+ self.affectation=0
+ self.indent_list=[""]
+ self.objet_courant=None
+ self.affectation_flag=1
+ self.comment_flag=1
+ self.buffer=[]
+ self.buffer_indent=""
+
+ def getOptions(self):
+ m= self.optionprog.match(self.line)
+ if m:
+ option=m.group(1)
+ name=option[1:]
+ flag=(option[0] == '+')
+ if name == "affectation": self.affectation_flag=flag
+ if name == "comment": self.comment_flag=flag
+ if name == "all":
+ self.comment_flag=flag
+ self.affectation_flag=flag
+
+ def readline(self):
+ self.line= self.texte.readline()
+ #print "line:",self.line
+ # option ?
+ self.getOptions()
+ return self.line
+
+ def getTexte(self,appliEficas=None):
+ """
+ Retourne le texte issu de l'analyse
+ """
+ for tk in tokenize.generate_tokens(self.readline):
+ self.processToken(tk)
+ return self.out
+
+ def processToken(self, tk):
+ """
+ """
+ ttype, tstring, spos, epos, line = tk
+ thisrow, thiscol = spos
+ #print spos, epos,tokenize.tok_name[ttype],self.lastrow, self.lastcol
+
+ if thisrow > self.lastrow:
+ # si plusieurs lignes (>1)
+ self.out=self.out+"\n" * (thisrow - self.lastrow - 1)
+ self.lastcol = 0
+
+# if thiscol > self.lastcol :
+# self.out=self.out+ " " * (thiscol - self.lastcol)
+# self.please_indent = None
+
+ self.thiscol=thiscol
+ #self.nextrow, self.nextcol = epos
+
+ try:
+ fn = getattr(self, tokenize.tok_name[ttype])
+ except AttributeError:
+ print( "No match!", tokenize.tok_name[ttype], tstring)
+ return
+
+ if ttype != tokenize.DEDENT and ttype != tokenize.INDENT and self.please_indent:
+ self.doIndent()
+
+ fn(tstring)
+ self.lastrow, self.lastcol = epos
+
+ def output(self,tstring):
+ #print "output",tstring
+
+ if self.thiscol > self.lastcol :
+ #print self.thiscol,self.lastcol
+ self.out=self.out+ " " * (self.thiscol - self.lastcol)
+ self.lastcol=self.thiscol
+
+ self.out=self.out+tstring
+
+ def outputCom(self,tstring):
+ self.out=self.out+tstring
+
+ def updateIndent(self):
+ #print "updateIndent",len(self.indent_list[-1]),len(self.buffer_indent)
+ if len(self.indent_list[-1]) > len(self.buffer_indent):
+ self.out=self.out+(len(self.indent_list[-1]) - len(self.buffer_indent))*" "
+ self.buffer_indent=self.indent_list[-1]
+
+ def doIndent(self):
+ #print "indentation dans doIndent",len(self.indent_list)
+
+ self.out=self.out+self.indent_list[-1]
+ self.buffer_indent=self.indent_list[-1]
+ if self.lastcol+len(self.indent_list[-1]) > self.thiscol:
+ self.lastcol=self.thiscol
+ else:
+ self.lastcol=self.lastcol+len(self.indent_list[-1])
+ self.please_indent = None
+
+ def flush_buffer(self):
+ #if self.buffer:
+ # print len(self.indent_list),self.please_indent
+ for ob in self.buffer:
+ self.out= self.out+ str(ob)
+ self.doIndent()
+ self.buffer=[]
+ self.objet_courant=None
+
+ def NL(self, tstring):
+ if self.affectation:
+ if self.paren_level == 0:
+ # affectation en cours mais complete
+ self.out= self.out+ str(self.affectation_courante)
+ self.affectation_courante=None
+ self.please_indent=1
+ self.affectation=0
+ else:
+ # affectation en cours, on ajoute
+ if self.thiscol > self.lastcol :self.affectation_courante.appendText((self.thiscol - self.lastcol)*" ")
+ self.affectation_courante.appendText(tstring)
+ return
+
+ if self.objet_courant:
+ self.objet_courant=None
+ self.buffer.append(tstring)
+ # self.please_indent = None
+ return
+ self.output(tstring)
+ self.please_indent = 1
+
+ def COMMENT(self, tstring):
+ liste= string.split(self.line,"##",1)
+ if len(liste) > 1:
+ # On a trouve un double commentaire
+ before,after=liste
+ if self.affectation:
+ # affectation en cours, on ignore
+ pass
+ elif self.paren_level > 0:
+ self.output(tstring)
+ elif self.comment_flag and not self.pattern_ligne_non_blanche.search(before):
+ # il s'agit d'une commande commentarisee
+ if self.objet_courant == None:
+ if not self.buffer:self.buffer_indent=self.indent_list[-1]
+ self.objet_courant=COMMANDE_COMMENTARISEE()
+ self.buffer.append(self.objet_courant)
+ self.objet_courant.appendText(tstring)
+ self.please_indent = None
+ elif isinstance(self.objet_courant,COMMENTAIRE):
+ self.objet_courant=COMMANDE_COMMENTARISEE()
+ self.buffer.append(self.objet_courant)
+ self.objet_courant.appendText(tstring)
+ self.please_indent = None
+ else:
+ self.objet_courant.appendText(tstring)
+ self.please_indent = None
+ else:
+ # commentaire inline
+ self.output(tstring)
+ self.please_indent = 1
+ return
+
+ else:
+ # On a un commentaire simple
+ new_line = self.line.split('#')[0]
+ if self.affectation:
+ # affectation en cours, on ignore
+ pass
+ elif self.paren_level > 0:
+ self.output(tstring)
+ elif self.comment_flag and not self.pattern_ligne_non_blanche.search(new_line):
+ # commentaire precede de blancs
+ if self.objet_courant == None:
+ if not self.buffer:self.buffer_indent=self.indent_list[-1]
+ self.objet_courant=COMMENTAIRE()
+ self.buffer.append(self.objet_courant)
+ self.objet_courant.appendText(tstring)
+ self.please_indent = None
+ elif isinstance(self.objet_courant,COMMANDE_COMMENTARISEE):
+ self.objet_courant=COMMENTAIRE()
+ self.buffer.append(self.objet_courant)
+ self.objet_courant.appendText(tstring)
+ self.please_indent = None
+ else:
+ self.objet_courant.appendText(tstring)
+ self.please_indent = None
+ else:
+ # commentaire inline
+ self.output(tstring)
+ self.please_indent = 1
+ return
+
+ def ERRORTOKEN(self, tstring):
+ print("ERRORTOKEN", tstring)
+
+ def NAME(self, tstring):
+ if self.buffer:
+ self.updateIndent()
+ self.flush_buffer()
+
+ if self.affectation ==1:
+ # on a une expression du type NAME=NAME
+ # on ne veut pas des expressions qui commencent par NAME=NAME(NAME=
+ # on en prend le chemin : on met affectation a 3 pour le signaler
+ # on attend d'en savoir plus
+ if self.thiscol > self.lastcol :self.affectation_courante.appendText((self.thiscol - self.lastcol)*" ")
+ self.affectation_courante.appendText(tstring)
+ self.affectation=3
+ return
+ elif self.affectation ==4:
+ # on a une expression qui commence par NAME=NAME(NAME
+ # il s'agit tres probablement d'une commande
+ # on annule l'affectation en cours
+ if self.thiscol > self.lastcol :self.affectation_courante.appendText((self.thiscol - self.lastcol)*" ")
+ self.affectation_courante.appendText(tstring)
+ self.affectation=5
+ return
+ elif self.affectation == 2:
+ # affectation en cours, on ajoute
+ if self.thiscol > self.lastcol :self.affectation_courante.appendText((self.thiscol - self.lastcol)*" ")
+ self.affectation_courante.appendText(tstring)
+ self.affectation=2
+ return
+ self.affectation=0
+ self.name=None
+ if self.paren_level == 0 and self.affectation_flag:
+ # si on est en dehors de parentheses et en mode transformation d'affectation
+ # on initialise l'attribut name qui indique une affectation en cours
+ self.name=tstring
+ self.output(tstring)
+
+ def ident(self, tstring):
+ self.flush_buffer()
+ self.affectation=0
+ self.output(tstring)
+
+ def NUMBER(self, tstring):
+ self.flush_buffer()
+ if self.affectation>=1:
+ # affectation en cours, on ajoute
+ if self.thiscol > self.lastcol :self.affectation_courante.appendText((self.thiscol - self.lastcol)*" ")
+ self.affectation_courante.appendText(tstring)
+ self.affectation=2
+ return
+ self.output(tstring)
+
+ def OP(self,tstring):
+ self.flush_buffer()
+ if tstring in ('(','[','{'): self.paren_level=self.paren_level+1
+ if tstring in (')',']','}'): self.paren_level=self.paren_level-1
+
+ if tstring == '=' and self.affectation ==5:
+ # on a une expression qui commence par NAME=NAME(NAME=)
+ # il peut s'agir d'une commande
+ # on annule l'affectation en cours
+ self.out= self.out+ self.affectation_courante.texte
+ self.affectation_courante=None
+ self.name=None
+ self.affectation=0
+ elif tstring == ')' and self.affectation ==4:
+ # on a une expression qui commence par NAME=NAME()
+ # il peut s'agir d'une commande
+ # on annule l'affectation en cours
+ self.out= self.out+ self.affectation_courante.texte
+ self.affectation_courante=None
+ self.affectation=0
+ elif tstring == '(' and self.affectation == 3:
+ # on a deja trouve NAME=NAME
+ # on passe affectation a 4
+ if self.thiscol > self.lastcol :self.affectation_courante.appendText((self.thiscol - self.lastcol)*" ")
+ self.affectation_courante.appendText(tstring)
+ self.affectation=4
+ return
+ elif tstring == ';' and self.affectation>=1:
+ # l'affectation est terminee
+ self.out= self.out+ str(self.affectation_courante)
+ self.affectation_courante=None
+ self.please_indent=1
+ self.affectation=0
+ elif self.affectation>=1:
+ # on complete l'affectation
+ if self.thiscol > self.lastcol :self.affectation_courante.appendText((self.thiscol - self.lastcol)*" ")
+ self.affectation_courante.appendText(tstring)
+ self.affectation=2
+ return
+
+ self.affectation=0
+ if self.name and tstring=='=':
+ self.affectation=1
+ self.affectation_courante=AFFECTATION()
+ self.affectation_courante.name=self.name
+ self.output(tstring)
+
+ ENDMARKER = ident
+ NEWLINE=NL
+
+ def INDENT(self, tstring):
+ #tstring=str(len(self.indent_list))*len(tstring)
+ self.indent_list.append(tstring)
+ #print "indentation dans INDENT",len(self.indent_list),len(tstring)
+ self.affectation=0
+ if self.buffer:
+ self.updateIndent()
+ self.flush_buffer()
+
+ def DEDENT(self, tstring):
+ #print "DEDENT",tstring,len(tstring)
+ if self.buffer:
+ self.out= self.out+ str(self.buffer[0])
+ if len(self.buffer) > 1:
+ for ob in self.buffer[1:]:
+ self.doIndent()
+ self.out= self.out+ str(ob)
+ self.buffer=[]
+ self.objet_courant=None
+ self.please_indent=1
+
+ self.affectation=0
+ self.indent_list = self.indent_list[:-1]
+ #print "indentation dans DEDENT",len(self.indent_list)
+
+ def STRING(self, tstring):
+ self.flush_buffer()
+ if self.affectation>=1:
+ # affectation en cours, on ajoute
+ if self.thiscol > self.lastcol :self.affectation_courante.appendText((self.thiscol - self.lastcol)*" ")
+ self.affectation_courante.appendText(tstring)
+ self.affectation=2
+ return
+ self.output(tstring)
+
+if __name__ == "__main__" :
+ import sys
+ import io
+ text="""
+#
+# comment
+# comment
+# comment
+#
+
+import sys,os
+
+# commentaire
+# commentaire
+# commentaire
+
+DEBUT();
+##toto = FORMULE(REEL='(REEL:A) = A',);
+
+x=2*cos(90.)/34.
+
+a=1.
+if a != 0:
+ a=+1
+
+b=2.
+c=a+b
+#if 1:
+# d=3
+# e=5
+#try:
+# a=1/2
+#except KeyError:
+# pass
+
+if 1:
+ a=2
+ b=3
+ # commenta
+else:
+ # commen
+ # commen
+ a=3
+ #qqqqqqqqqqqqqqqqqqqqqqqq
+ c=5
+
+b=5
+ # commentaire
+toto = FORMULE(REEL='(REEL:A) = A',);
+titi = FORMULE(REEL='(REEL:A) = A',) # commentaire inline
+tutu = FORMULE(REEL='(REEL:A) = A',) ## commentaire inline
+
+TEST_TABLE( TABLE=RELV[k],
+ FILTRE=(
+ _F( NOM_PARA = 'QUANTITE',
+ VALE_K = 'MAXIMUM'),),
+ # commentaire
+ NOM_PARA='VMIS', # comm
+ VALE=1.9669824189084E9,
+ REFERENCE='NON_REGRESSION',
+ VERSION='8.1.0' )
+
+if 1:
+ a=fff(a=1,
+ b=2)
+if 1:
+ a=2
+ b=3
+ # commenta
+else:
+ # commen
+ # commen
+ a=3
+
+for k in range(1,10):
+
+ # Appel a GMSH pour le maillage
+
+ f=open("coque.geo","w")
+
+
+a = 1.
+b=3
+c= 3 * 5
+d= 4 + \
+ 5 \
+ -4
+e=toto(a=1)
+x=(1,2)
+y=[3,
+#comme
+4]
+z="a"
+zz='v'
+u='''aaaa
+bbbb'''
+if 1:
+ a=45
+else:
+ a=5.6
+d={"a":0}
+e={"a":0,
+#comme
+"d":4}
+a==1
+x=a==1
+s="-"*80
+fmt_raison='-'*80+'''
+
+ Exception erreur_Fatale interceptee
+ Raison : %s
+
+'''+'-'*80+'xxxxxxxxxxxxxxxx'
+q=30*cos(12)
+f=cos(12)
+#commen'''
+#commen'''
+y=a[1]
+y=["x"]*10
+
+##toto = FORMULE(REEL='(REEL:A) = A',
+## X=2
+## );
+#
+# comment
+# comment
+# comment
+#
+zz=8.9;
+zz=8.9;aa=10
+P1 = 9.8;
+
+P2 = 8.8;
+
+P3 = 7;
+
+P5 = P3*P1;
+
+P6 = P1-3;
+
+P4 = [2,3,4];
+
+P7=P4[1]
+MA=LIRE_MAILLAGE()
+MA=LIRE_MAILLAGE(#comment
+)
+xyz=cos(10)
+MA=LIRE_MAILLAGE(INFO=1)
+MA=LIRE_MAILLAGE(
+ NFO=1)
+MA=LIRE_MAILLAGE(#comme
+ NFO=1)
+MA=\
+LIRE_MAILLAGE(INFO=1)
+MA= LIRE_MAILLAGE()
+TFIN = 1.790 # Temps fin pour le calcul
+
+PAS = 0.001 # pas de temps du calcul
+# parse: -affectation
+DS1=[None]*5
+DS2=[None]*5
+DS3=[None]*5
+DS4=[None]*5
+CHS1=[None]*5
+CHS2=[None]*5
+MO=AFFE_MODELE( MAILLAGE=MA,
+ #test de validateur GEOM (typ=grma) avec grma derive de GEOM
+ AFFE=(_F(GROUP_MA = ('LI1'),
+ PHENOMENE = 'MECANIQUE',
+ MODELISATION = 'DIS_TR'),
+ ),
+ INFO=2,);
+
+for k in range(1,5):
+ DS1[k] = CREA_CHAMP( OPERATION='EXTR', TYPE_CHAM='NOEU_DEPL_R',
+ RESULTAT= MODESTA1, NUME_ORDRE=k, NOM_CHAM = 'DEPL');
+
+# parse: +affectation
+ff=23 # parametre bidon
+
+# parse: -all
+a=45
+#commment1
+##toto = FORMULE(REEL='(REEL:A) = A',
+## X=2
+## );
+# parse: +all
+b=45
+#commment2
+##toto = FORMULE(REEL='(REEL:A) = A',
+## X=2
+## );
+# parse: -comment
+c=45
+#commment3
+##toto = FORMULE(REEL='(REEL:A) = A',
+## X=2
+## );
+# parse: +comment
+d=45
+#commment5
+##toto = FORMULE(REEL='(REEL:A) = A',
+## X=2
+## );
+p=sin(ff)
+
+e=toto(a=1)
+e=toto(a=1,b=3)
+e=toto(1,b=3)
+e=toto(a,b=3)
+e=toto()
+sensible=[2.1E11, 0.3, 1.E-6, 1.E-6, ]
+
+n=len(sensible)
+# parse: -affectation
+
+PS=[None]*n
+
+for i in range(n):
+ PS[i]=DEFI_PARA_SENSI(VALE=sensible[i])
+# parse: +affectation
+
+TEST_RESU(RESU=(_F(RESULTAT = U3L,
+ INST = 1.0,
+ NOM_CHAM = 'DEPL',
+ GROUP_NO = 'PPA',
+ NOM_CMP = 'DX',
+ VALE = 2.86E-5,
+ PRECISION = 5.E-2,
+ REFERENCE = 'AUTRE_ASTER',
+ VERSION = '7.1.11',
+ ),
+ )
+ )#
+#
+FIN()
+#
+
+TEST_RESU(RESU=(_F(RESULTAT = U3L,
+ INST = 1.0,
+ NOM_CHAM = 'DEPL',
+ GROUP_NO = 'PPA',
+ NOM_CMP = 'DX',
+ VALE = 2.86E-5,
+ PRECISION = 5.E-2,
+ REFERENCE = 'AUTRE_ASTER',
+ VERSION = '7.1.11',
+ ),
+ )
+ ) #a
+
+titi = FORMULE(REEL='(REEL:A) = A',
+) # commentaire inline
+titi = FORMULE(REEL='(REEL:A) = A',
+ ) # commentaire inline
+
+def f(x):return x
+#comment
+def f(x):
+#comment
+ for i in range(10): s=0
+
+#com1
+#com2
+
+#com3
+a=1
+##commendcomm
+for k in range(1,10):
+
+ # Appel a GMSH pour le maillage
+
+ f=open("coque.geo","w")
+#comm
+ if a==1:
+
+ #comm
+
+ for i in x:
+#comm
+##commendcomm
+#comm
+##commendcomm
+#comm
+ if x==3:
+#comm
+ r=1
+ if w==4:
+#comm
+
+ if k:
+
+#comm
+ if g:
+
+#comm
+
+ if t:
+ a=5
+#comm
+if 1:
+ a=2
+ b=3
+ # commenta
+else:
+ # commen
+ # commen
+ a=3
+ # qqqqqqqqqqqqqqqq
+ c=5
+
+b=5
+
+if 1:
+ a=2
+ # commenta
+else:
+ a=3
+if 1:
+ if 2:
+ if 3:
+ a=1
+ elif 4:
+ b=1
+ else:
+ c=5
+ elif 3:
+ x=1
+ else:
+ y=4
+elif 4:
+ s=1
+else:
+ t=9
+#com1
+#com2
+
+#com3
+a=1
+##commendcomm
+for k in range(1,10):
+
+ # Appel a GMSH pour le maillage
+
+ f=open("coque.geo","w")
+#comm
+ if 1:
+ if 2:
+ if 3:
+ a=1
+ else:
+ a=6
+a=1
+##commendcomm
+for k in range(1,10):
+
+ # Appel a GMSH pour le maillage
+
+ f=open("coque.geo","w")
+#comm
+
+ if a==1:
+
+ #comm
+
+ for i in x:
+#comm
+##commendcomm
+#comm
+##commendcomm
+#comm
+ if x==3:
+#comm
+ r=1
+
+ if 1:
+ if 2:
+ if 3:
+ a=1
+ else:
+ a=6
+
+if 1:
+ if 2:
+ if 3:
+ r=1
+ # comm
+ else:
+ x=7
+ toto(a=1,
+b=3)
+SUP_=dict([(grand,0.) for grand in grand_obs])
+
+for k in range(1,ns+1):
+ x=toto(a=1,b=2)
+# comm
+ if 1:
+ #com
+
+ #com
+ x=1
+ #com
+
+ #com
+ ##com
+ elif 3:
+ ##com
+ x=1
+ else:
+ y=3
+
+def f():
+ return
+########################################################################
+
+########################################################################
+# macro commande de post-traitement (ex POST_GOUJ2E)
+# calcul des reactions cumulees suivant les filets
+
+def POST_GOUJ_ops(self,TABLE):
+ ier=0
+
+"""
+ if len(sys.argv)== 2:
+ progname, input = sys.argv
+ f=open(input)
+ t=f.read()
+ f.close()
+ else:
+ t=text
+ txt = PARSEUR_PYTHON(t).getTexte()
+ print (txt)
+ compile(txt,"<string>",'exec')
--- /dev/null
+# Copyright (C) 2007-2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+from __future__ import absolute_import
+
+
+import re
+from Extensions.i18n import tr
+
+#import traceback
+#traceback.print_stack()
+
+from Extensions import localisation
+from Noyau import N_CR
+
+
+def entryPoint():
+ """
+ Return a dictionary containing the description needed to load the plugin
+ """
+ return {
+ 'name' : 'xml',
+ 'factory' : XMLparser
+ }
+
+class XMLparser:
+ """
+ This converter works like Pythonparser, except that it is supposed to read XML
+ """
+
+ def __init__(self,cr=None):
+ print ('dans XML convert')
+ self.text=''
+ if cr : self.cr=cr
+ else: self.cr=N_CR.CR(debut='CR convertisseur format XML',
+ fin='fin CR format XML')
+
+ def readfile(self,filename):
+ self.filename=filename
+ try:
+ with open(filename) as fd :
+ self.text=fd.read()
+ except:
+ self.cr.exception(tr("Impossible d'ouvrir le fichier %s" ,str(filename)))
+ self.cr.fatal(tr("Impossible d'ouvrir le fichier %s" ,str(filename)))
+ return
+
+
+
+ def convert(self, outformat, appliEficas=None):
+ # ici on ne fait rien
+ # on le fera a la creation du JDC
+ try:
+ return self.text
+ except EficasException:
+ # Erreur lors de la conversion
+ l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],
+ sys.exc_info()[2])
+ self.cr.exception(tr("Impossible de convertir le fichier XML\n %s", ''.join(l)))
+ return ""
--- /dev/null
+# Copyright (C) 2007-2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+from __future__ import absolute_import
+
+
+from Extensions.i18n import tr
+from Extensions import localisation
+
+
+from .convert_python import Pythonparser
+from Noyau import N_CR
+
+try:
+ basestring
+except NameError:
+ basestring = str
+
+
+
+def entryPoint():
+ """
+ Return a dictionary containing the description needed to load the plugin
+ """
+ return {
+ 'name' : 'dico',
+ 'factory' : Dicoparser
+ }
+
+class Dicoparser(Pythonparser):
+ """
+ This converter initializes model variable from a python dictionnary
+ """
+
+ def __init__(self,cr=None):
+ # Si l'objet compte-rendu n'est pas fourni, on utilise le
+ # compte-rendu standard
+ self.text=''
+ self.textePy=''
+ if cr :
+ self.cr=cr
+ else:
+ self.cr=N_CR.CR(debut='CR convertisseur format dico',
+ fin='fin CR format dico')
+
+ def readfile(self,filename):
+ self.filename=filename
+ try:
+ with open(filename) as fd :
+ self.text=fd.read()
+ except:
+ self.cr.exception(tr("Impossible d'ouvrir le fichier %s" ,str(filename)))
+ self.cr.fatal(tr("Impossible d'ouvrir le fichier %s" ,str(filename)))
+ return
+
+ def convert(self,outformat,appli=None):
+ monTexteDico={}
+ exec (self.text,globals(),monTexteDico)
+ if len(monTexteDico.keys()) != 1 :
+ self.cr.exception(tr("Impossible de traiter le fichier %s" ,str(filename)))
+ self.cr.fatal(tr("Impossible de traiter le fichier %s" ,str(filename)))
+ return
+ self.textePy=""
+ monDico=monTexteDico[monTexteDico.keys()[0]]
+ for commande in monDico :
+ valeurs=monDico[commande]
+ if valeurs.has_key('NomDeLaSdCommande') :
+ # cas d un oper
+ self.textePy+=valeurs['NomDeLaSdCommande']+' = '+commande+'('
+ del valeurs['NomDeLaSdCommande']
+ else :
+ self.textePy+=commande+'('
+ for mot in valeurs :
+ if isinstance(valeurs[mot],dict) : self.traiteMCFact(mot,valeurs[mot])
+ else : self.textePy += mot+' = ' +str(valeurs[mot])+','
+ self.textePy+=');\n' # fin de la commande
+ #print (self.textePy)
+ return self.textePy
+
+ def traiteMCFact(self,mot,valeurs):
+ self.textePy += mot + '=_F('
+ for mot in valeurs :
+ if isinstance(valeurs[mot],dict) : self.traiteMCFact(mot,valeurs[mot])
+ else : self.textePy +=mot+' = ' +str(valeurs[mot])+','
+ self.textePy +='),'
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+"""
+"""
+
+from __future__ import absolute_import
+from .convert_python import Pythonparser
+
+def entryPoint():
+ """
+ Retourne les informations necessaires pour le chargeur de plugins
+ Ces informations sont retournees dans un dictionnaire
+ """
+ return {
+ # Le nom du plugin
+ 'name' : 'MAP',
+ # La factory pour creer une instance du plugin
+ 'factory' : Pythonparser,
+ }
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+"""
+ Ce module contient le plugin convertisseur de fichier
+ au format python pour EFICAS.
+
+ Un plugin convertisseur doit fournir deux attributs de classe :
+ extensions et formats et deux methodes : readfile,convert.
+
+ L'attribut de classe extensions est une liste d'extensions
+ de fichiers preconisees pour ce type de format. Cette information
+ est seulement indicative.
+
+ L'attribut de classe formats est une liste de formats de sortie
+ supportes par le convertisseur. Les formats possibles sont :
+ eval, dict ou exec.
+ Le format eval est un texte source Python qui peut etre evalue. Le
+ resultat de l'evaluation est un objet Python quelconque.
+ Le format dict est un dictionnaire Python.
+ Le format exec est un texte source Python qui peut etre execute.
+
+ La methode readfile a pour fonction de lire un fichier dont le
+ nom est passe en argument de la fonction.
+ - convertisseur.readfile(nom_fichier)
+
+ La methode convert a pour fonction de convertir le fichier
+ prealablement lu dans un objet du format passe en argument.
+ - objet=convertisseur.convert(outformat)
+
+ Ce convertisseur supporte le format de sortie exec
+
+"""
+from __future__ import absolute_import
+try :
+ from builtins import str
+ from builtins import object
+except :
+ pass
+import sys,traceback
+
+from .parseur_python import PARSEUR_PYTHON
+from Noyau import N_CR
+from Extensions.i18n import tr
+from Extensions.eficas_exception import EficasException
+
+def entryPoint():
+ """
+ Retourne les informations necessaires pour le chargeur de plugins
+ Ces informations sont retournees dans un dictionnaire
+ """
+ return {
+ # Le nom du plugin
+ 'name' : 'python',
+ # La factory pour creer une instance du plugin
+ 'factory' : Pythonparser,
+ }
+
+
+class Pythonparser(object):
+ """
+ Ce convertisseur lit un fichier au format python avec la
+ methode readfile : convertisseur.readfile(nom_fichier)
+ et retourne le texte au format outformat avec la
+ methode convertisseur.convert(outformat)
+
+ Ses caracteristiques principales sont exposees dans 2 attributs
+ de classe :
+ - extensions : qui donne une liste d'extensions de fichier preconisees
+ - formats : qui donne une liste de formats de sortie supportes
+ """
+ # Les extensions de fichier preconisees
+ extensions=('.py',)
+ # Les formats de sortie supportes (eval dict ou exec)
+ # Le format exec est du python executable (commande exec) converti avec PARSEUR_PYTHON
+ # Le format execnoparseur est du python executable (commande exec) non converti
+ formats=('exec','execnoparseur')
+
+ def __init__(self,cr=None):
+ # Si l'objet compte-rendu n'est pas fourni, on utilise le
+ # compte-rendu standard
+ self.text=''
+ if cr :
+ self.cr=cr
+ else:
+ self.cr=N_CR.CR(debut='CR convertisseur format python',
+ fin='fin CR format python')
+
+ def readfile(self,filename):
+ self.filename=filename
+ try:
+ with open(filename) as fd :
+ self.text=fd.read()
+ except:
+ self.cr.exception(tr("Impossible d'ouvrir le fichier %s" ,str(filename)))
+ self.cr.fatal(tr("Impossible d'ouvrir le fichier %s" ,str(filename)))
+ return
+
+ def convert(self,outformat,appliEficas=None):
+ if outformat == 'exec':
+ try:
+ #import cProfile, pstats, StringIO
+ #pr = cProfile.Profile()
+ #pr.enable()
+ l= PARSEUR_PYTHON(self.text).getTexte(appliEficas)
+
+ #pr.disable()
+ #s = StringIO.StringIO()
+ #sortby = 'cumulative'
+ #ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
+ #ps.print_stats()
+ #print (s.getValue())
+
+ return l
+ except EficasException:
+ # Erreur lors de la conversion
+ l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],
+ sys.exc_info()[2])
+ self.cr.exception(tr("Impossible de convertir le fichier Python qui doit contenir des erreurs.\n\
+ On retourne le fichier non converti. Prevenir la maintenance.\n\n %s", ''.join(l)))
+ # On retourne neanmoins le source initial non converti (au cas ou)
+ return self.text
+ elif outformat == 'execnoparseur':
+ return self.text
+ else:
+ raise EficasException(tr("Format de sortie : %s, non supporte", outformat))
+ return None
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2021 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
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# 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 object
+except :
+ pass
+import sys,string,re
+import traceback
+from Extensions.i18n import tr
+
+escapedQuotesRE = re.compile(r"(\\\\|\\\"|\\\')")
+stringsAndCommentsRE = \
+ re.compile(u"(\"\"\".*?\"\"\"|'''.*?'''|\"[^\"]*\"|\'[^\']*\'|#.*?\n)", re.DOTALL)
+#stringsAndCommentsRE = \
+# re.compile(u"(\"\"\".*\"\"\"|'''.*'''|\"[^\"]*\"|\'[^\']*\'|#.*\n)", re.DOTALL)
+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))
+#elif sys.platform[0:3]=="win" :
+# allcharsExceptNewlineTranstable = dict((ord(char), u'*') for char in allcharsExceptNewline)#
+#else :
+# allcharsExceptNewlineTranstable = string.maketrans(allcharsExceptNewline, '*'*len(allcharsExceptNewline))
+
+def maskStringsAndComments(src):
+ """Masque tous les caracteres de src contenus dans des commentaires ou des strings multilignes (triples
+ quotes et guillemets.
+ Le masquage est realise en remplacant les caracteres par des *
+ Attention : cette fonction doit etre utilisee sur un texte complet et pas ligne par ligne
+ """
+# remplace les \\, les \" les \' par **
+# 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
+# on prend 1 sur 2 en raison du split qui donne python, commentaire, python, commentaire...
+
+ src = escapedQuotesRE.sub("**", src)
+ allstrings = stringsAndCommentsRE.split(src)
+
+ # 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)+ \
+ allstrings[i][-3:]
+ else:
+ allstrings[i] = allstrings[i][0]+ \
+ allstrings[i][1:-1].translate(allcharsExceptNewlineTranstable)+ \
+ allstrings[i][-1]
+
+ return "".join(allstrings)
+
+implicitContinuationChars = (('(', ')'), ('[', ']'), ('{', '}'))
+linecontinueRE = re.compile(r"\\\s*(#.*)?$")
+emptyHangingBraces = [0,0,0,0,0]
+
+class parserException(Exception): pass
+class FatalError(Exception): pass
+
+#commentaire double precede d'un nombre quelconque de blancs (pas multiligne)
+pattern_2comments = re.compile(r"^\s*##.*")
+pattern_finComments = re.compile("^\s*##Fin Commentaire")
+#commentaire standard precede d'un nombre quelconque de blancs (pas multiligne)
+pattern_comment = re.compile(r"^\s*#.*")
+#fin de ligne ; suivi d'un nombre quelconque de blancs (pas multiligne)
+pattern_fin = re.compile(r"; *$")
+#pattern pour supprimer les blancs, tabulations et fins de ligne
+pattern_blancs = re.compile(r"[ \t\r\f\v]")
+#pattern_blancs = re.compile(r"[\s\n]")
+number_kw_pattern=re.compile(r"""
+(
+ #groupe nombre decimal
+ (?:
+ #signe : on ignore le signe +
+ [-]?
+ #groupe (avec ?: n'apparait pas en tant que groupe dans le resultat)
+ (?:
+ #mantisse forme entiere.fractionnaire
+ \d+(?:\.\d*)?
+ |
+ #ou forme .fractionnaire
+ \.\d+
+ )
+ (?:[eE][+-]?\d+)?
+ )
+ |
+ #argument keyword
+ [a-zA-Z_]\w*=
+)
+""",re.VERBOSE|re.MULTILINE)
+
+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 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)'''
+ >>> construitGenea(s,['a','x'])
+ {0.000213: '21.3e-5'}
+ """
+ d={}
+ mot=""
+ #on masque les strings et commentaires pour ne pas identifier de faux reels
+ for m in number_kw_pattern.findall(maskStringsAndComments(texte)):
+ if m[-1] == '=':
+ #argument keyword
+ mot=m[:-1]
+ else:
+ if mot not in listeMc:continue
+ #valeur
+ key=eval(m)
+ if str(key) != m: d[key]=m
+ return d
+
+
+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 setText(self,texte):
+ self.texte = texte
+
+ def appendText(self,texte):
+ """
+ Ajoute texte a self.texte en mettant un retour chariot a la fin de texte
+ """
+ texte = texte+'\n'
+ self.texte = self.texte +texte
+
+ def __str__(self):
+ return self.texte
+
+class COMMENTAIRE(ENTITE_JDC):
+
+ def __str__(self):
+ """
+ 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 appendText(self,texte):
+ """
+ Ajoute texte a self.texte en enlevant le # initial
+ """
+ texte = texte+'\n'
+ if texte[0] == '#':
+ self.texte = self.texte+texte[1:]
+ else:
+ # le diese n'est pas sur le premier caractere
+ amont,aval = texte.split('#',1) # on decoupe suivant la premiere occurrence de #
+ self.texte = self.texte +amont + aval
+
+class COMMANDE(ENTITE_JDC):
+
+ def __str__(self):
+ """
+ Retourne self.texte
+ """
+ return self.texte+'\n'
+
+ def getNbPar(self):
+ """
+ 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 = self.texte.split('\n')
+ nb = 0
+ for ligne in l_lignes:
+ 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 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 = 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 comprehensible par ACCAS
+ et exploitable par EFICAS
+ """
+ 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 appendText(self,texte):
+ """
+ Ajoute texte a self.texte en enlevant les doubles commentaires
+ """
+ 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 commentarisee comprehensible par ACCAS
+ et exploitable par EFICAS
+ """
+ return "COMMANDE_COMM(texte="+repr(self.texte)+")\n"
+ #return "COMMANDE_COMM(texte='''"+self.texte+"''')\n"
+
+class AFFECTATION_EVAL(ENTITE_JDC):
+
+ def appendText(self,texte):
+ """
+ Ajoute texte a self.texte en enlevant tout retour chariot
+ """
+ if texte[-1] == '\n' : texte = texte[1:-1]
+ self.texte = self.texte+texte
+
+ def __str__(self):
+ """
+ Retourne une expression du parametre EVAL comprehensible par ACCAS
+ et exploitable par EFICAS
+ """
+ nom,valeur = self.texte.split('=',1)
+ nom = nom.strip()
+ if valeur[-1] == '\n': valeur = valeur[:-1]
+ valeur = valeur.strip()
+ return nom+' = PARAMETRE_EVAL(nom=\''+nom+'\',valeur=\''+valeur+'\')\n\n'
+
+class PARSEUR_PYTHON(object):
+ """
+ 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-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*')
+
+ def __init__(self,texte):
+ self.texte = texte
+ self.l_objets=None
+ self.appliEficas=None
+
+ def isAffectation(self,texte):
+ """
+ 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 procedure ...
+ return 0
+ amont,aval = texte.split('=',1)
+ aval = aval.strip()
+
+
+ if self.pattern_commande.match(aval):
+ return 0
+ else:
+ 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 isEval(self,texte):
+ """
+ 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 procedure ...
+ return 0
+ 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 isCommande(self,texte):
+ """
+ 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 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 = texte.split('=',1)
+ aval = aval.strip()
+ if self.pattern_commande.match(aval):
+ return 1
+ else:
+ return 0
+
+ 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 "commentarisees").
+ """
+ l_lignes = self.texte.split('\n')
+ commentaire_courant = None
+ commande_courante = None
+ affectation_courante = None
+ commande_commentarisee_courante = None
+ self.l_objets = []
+
+ #initialisation du nombre de parentheses non fermees et de commentaires non termines
+ #Attention a reinitialiser en fin de ligne logique
+ #Une ligne logique peut s'etendre sur plusieurs lignes physiques avec des caracteres de continuation
+ #explicites ou implicites
+ hangingBraces = list(emptyHangingBraces)
+ hangingComments = 0
+
+ #Masquage des commentaires et strings multilignes
+ srcMasked=maskStringsAndComments('\n'.join(l_lignes))
+ masked_lines=srcMasked.split('\n')
+ lineno=0
+
+ for ligne in l_lignes :
+ line=masked_lines[lineno]
+ lineno=lineno+1
+ #print ("ligne:",line)
+ # mise a jour du nombre total de parentheses ouvertes (non fermees)
+ # et du nombre de commentaires non termines
+ for i in range(len(implicitContinuationChars)):
+ contchar = implicitContinuationChars[i]
+ numHanging = hangingBraces[i]
+ hangingBraces[i] = numHanging+line.count(contchar[0]) - line.count(contchar[1])
+
+ hangingComments ^= line.count('"""') % 2
+ hangingComments ^= line.count(u"'''") % 2
+ #print (hangingComments,hangingBraces)
+ if hangingBraces[0] < 0 or hangingBraces[1] < 0 or hangingBraces[2] < 0:
+ raise parserException()
+
+ if ligne.strip() == '':
+ # il s'agit d'un saut de ligne
+ # --> on l'ignore
+ continue
+
+ if pattern_2comments.match(ligne):
+ #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 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.appendText(ligne)
+ elif commande_commentarisee_courante :
+ # commande_commentarisee en cours : on ajoute la ligne
+ 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 commentarisee : on cree un objet commande_commentarisee_courante
+ commande_commentarisee_courante = COMMANDE_COMMENTARISEE(self)
+ commande_commentarisee_courante.appendText(ligne)
+
+ #on passe a la ligne suivante
+ continue
+
+ if pattern_comment.match(ligne):
+ #commentaire ordinaire avec seulement des blancs devant
+ if commande_commentarisee_courante :
+ # commande_commentarisee en cours : on la clot
+ commande_commentarisee_courante = None
+
+ if commande_courante :
+ # 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.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.appendText(ligne)
+ else :
+ # il s'agit d'un nouveau commentaire entre deux commandes
+ # --> on le cree et il devient le commentaire courant
+ commentaire_courant = COMMENTAIRE(self)
+ commentaire_courant.appendText(ligne)
+
+ #on passe a la ligne suivante
+ continue
+
+ # la ligne contient des donnees autre qu'un eventuel commentaire
+ if commentaire_courant :
+ # on clot un eventuel commentaire courant
+ commentaire_courant = None
+
+ if 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.appendText(ligne)
+ if not linecontinueRE.search(line) \
+ and (hangingBraces == emptyHangingBraces) \
+ and not hangingComments:
+ #la commande est terminee
+ self.analyseReel(commande_courante.texte)
+ commande_courante = None
+
+ #on passe a la ligne suivante
+ continue
+
+ if affectation_courante != None :
+ #poursuite d'une affectation
+ affectation_courante.appendText(ligne)
+ if not linecontinueRE.search(line) \
+ and (hangingBraces == emptyHangingBraces) \
+ and not hangingComments:
+ #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.isEval(ligne):
+ # --> affectation de type EVAL
+ if affectation_courante : affectation_courante = None
+ affectation = AFFECTATION_EVAL(self)
+ affectation.appendText(ligne)
+ #on passe a la ligne suivante
+ continue
+
+ 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).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 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.appendText(text)
+ if not linecontinueRE.search(line) \
+ and (hangingBraces == emptyHangingBraces) \
+ and not hangingComments:
+ #L'affectation est terminee
+ affectation_courante=None
+ #on passe a la ligne suivante
+ continue
+
+ if self.isCommande(ligne):
+ # --> nouvelle commande
+ affectation_courante = None
+ commande_courante = COMMANDE(self)
+ 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.analyseReel(commande_courante.texte)
+ commande_courante = None
+ #on passe a la ligne suivante
+ continue
+
+
+ def enleve (self,texte) :
+ """Supprime de texte tous les caracteres blancs, fins de ligne, tabulations
+ Le nouveau texte est retourne
+ """
+ i=0
+ chaine=""
+ while (i<len(texte)):
+ if (texte[i] == " " or texte[i] == "\n" or texte[i] == "\t") :
+ i=i+1
+ else :
+ chaine=chaine+texte[i]
+ i=i+1
+ return chaine
+
+ def construitGenea(self,texte):
+ indiceC=0
+ mot=""
+ dict_reel_concept={}
+
+ # traitement pour chaque caractere
+ while (indiceC < len(texte)):
+ c=texte[indiceC]
+ if ( c == "," or c == "(u" or c == ")"):
+ mot=""
+ elif ( c== "="):
+ #on doit trouver derriere soit une valeur soit une parenthese
+ valeur=""
+ nouvelindice=indiceC+1
+ if texte[nouvelindice] != "(u":
+ #pas de parenthese ouvrante derriere un signe =, on a une valeur.
+ while ( texte[nouvelindice] != "," and texte[nouvelindice] != ")"):
+ valeur=valeur+texte[nouvelindice]
+ nouvelindice=nouvelindice+1
+ if nouvelindice == len(texte) :
+ nouvelindice=nouvelindice -1
+ break
+ if mot in self.appliEficas.liste_simp_reel:
+ if valeur[0] != "'":
+ try :
+ clef=eval(valeur)
+ if str(clef) != str(valeur) :
+ dict_reel_concept[clef]=valeur
+ except :
+ pass
+ mot=""
+ indiceC=nouvelindice
+ else:
+ #parenthese ouvrante derriere un signe =, on a un tuple de valeur ou de mots cles facteurs.
+ # s agit -il d un tuple
+ if texte[nouvelindice+1] != "(u":
+ #le suivant n'est pas une parenthese ouvrante : on a un tuple de valeurs ou un mot cle facteur
+ tuple=False
+ #on avance jusqu'a la fin du tuple de valeurs ou jusqu'a la fin du premier mot cle simple
+ #contenu dans le mot cle facteur
+ while ( texte[nouvelindice] != "="):
+ if texte[nouvelindice] == ")" :
+ tuple=True
+ break
+ else :
+ nouvelindice=nouvelindice+1
+ if nouvelindice == len(texte) :
+ nouvelindice=nouvelindice -1
+ break
+ if tuple :
+ #cas du tuple de valeurs
+ valeur=texte[indiceC+1:nouvelindice+1]
+ indiceC=nouvelindice+1
+ if mot in self.appliEficas.liste_simp_reel:
+ valeur=valeur[1:-1]
+ for val in valeur.split(',') :
+ # Attention la derniere valeur est""
+ try :
+ if val[0] != "'":
+ clef=eval(val)
+ if str(clef) != str(val) :
+ dict_reel_concept[clef]=val
+ except :
+ pass
+ mot=""
+ # ou de ( imbriquees
+ else :
+ #cas du mocle facteur simple ou
+ mot=""
+ else :
+ mot=mot+texte[indiceC]
+ indiceC=indiceC+1
+ # traitement du dernier inutile
+ # c est un ;
+ return dict_reel_concept
+
+ def analyseReel(self,commande) :
+ nomConcept=None
+ # On verifie qu on a bien un OPER
+ # et pas une MACRO
+ if commande.find(u"=") > commande.find(u"(u") :
+ return
+ if commande.find(u"=") > 0:
+ #epure1=self.enleve(commande)
+ epure1=pattern_blancs.sub(u"",commande)
+ nomConcept,corps=epure1.split(u"=",1)
+ epure2=corps.replace(u"_F(u","(u")
+ #nomConcept=epure1.split(u"=")[0]
+ #index=epure1.find(u"=")
+ #epure2=epure1[index+1:len(epure1)].replace(u"_F(u","(u")
+ #dict_reel_concept=self.construitGenea(epure2)
+ if self.appliEficas:
+ dict_reel_concept=construitGenea(epure2,self.appliEficas.liste_simp_reel)
+ else:
+ dict_reel_concept={}
+ if nomConcept == "sansnom" :
+ nomConcept = ""
+ if nomConcept !=None :
+ if len(dict_reel_concept) != 0:
+ self.appliEficas.dict_reels[nomConcept]=dict_reel_concept
+
+ def getTexte(self,appliEficas=None):
+ """
+ Retourne le texte issu de l'analyse
+ """
+ self.appliEficas=appliEficas
+ try:
+ #if 1:
+ if not self.l_objets : self.analyse()
+ txt=''
+ for obj in self.l_objets:
+ txt = txt+str(obj)
+ #else :
+ except parserException:
+ #Impossible de convertir le texte, on le retourne tel que
+ txt=self.texte
+ return txt
+
+def test():
+ #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'
+ with open(fichier) as fd:
+ texte = fd.read()
+ class appliEficas(object):
+ dict_reels={}
+ liste_simp_reel=["VALE","VALE_C","GROUP_MA","RAYON"]
+ a=appliEficas()
+
+ compile(txt, '<string>', 'exec')
+ print((a.dict_reels))