--- /dev/null
+import log
+
+from load import getJDC
+from mocles import parseKeywords
+import removemocle
+import renamemocle
+
+atraiter=("DEBUT","LIRE_MAILLAGE","AFFE_MODELE","DEFI_GROUP",
+ "AFFE_MATERIAU","DEFI_MATERIAU","STAT_NONLINE",
+ )
+
+filename="toto.comm"
+jdc=getJDC(filename,atraiter)
+root=jdc.root
+
+#Parse les mocles des commandes
+parseKeywords(root)
+
+removemocle.removemocleinfact(jdc,"AFFE_MATERIAU","AFFE","TOUT")
+removemocle.removemocle(jdc,"STAT_NONLINE","SOLVEUR")
+renamemocle.renamemocleinfact(jdc,"AFFE_MODELE","AFFE","PHENOMENE","TOTO")
+renamemocle.renamemocleinfact(jdc,"AFFE_MODELE","AFFE","MODELISATION","TITI")
+renamemocle.renamemocleinfact(jdc,"DEFI_GROUP","CREA_GROUP_NO","GROUP_MA","TUTU")
+removemocle.removemocle(jdc,"LIRE_MAILLAGE","INFO")
+removemocle.removemocle(jdc,"LIRE_MAILLAGE","UNITE")
+renamemocle.renamemocle(jdc,"DEFI_MATERIAU","ELAS","ELASTIC")
+renamemocle.renamemocle(jdc,"AFFE_MATERIAU","MAILLAGE","MAILL")
+removemocle.removemocleinfact(jdc,"STAT_NONLINE","SOLV","METHOD")
+removemocle.removemocle(jdc,"STAT_NONLINE","AFFE")
+
+
+f=open("tutu.comm",'w')
+f.write(jdc.getSource())
+f.close()
--- /dev/null
+# -*- coding: utf-8 -*-
+
+import os
+import parseur
+from mocles import parseKeywords
+
+atraiter=("DEBUT","LIRE_MAILLAGE","AFFE_MODELE","DEFI_GROUP",
+ "AFFE_MATERIAU","DEFI_MATERIAU",
+ )
+
+JDCdict={}
+
+class JDC:
+ """Cet objet conserve toutes les informations relatives à un fichier de commandes .comm"""
+ def __init__(self,filename,src,atraiter):
+ self.filename = os.path.abspath(filename)
+ self.atraiter=atraiter
+ self.init(src,atraiter)
+
+ def init(self,src,atraiter):
+ self.root=parseur.parser(src,atraiter)
+ self.lines=src.splitlines(1)
+
+ def parseKeywords(self):
+ parseKeywords(self.root)
+
+ def reset(self,src):
+ self.init(src,self.atraiter)
+ self.parseKeywords()
+
+ def getSource(self):
+ return "".join(self.getLines())
+
+ def getLine(self,linenum):
+ return self.getLines()[linenum-1]
+
+ def getLines(self):
+ return self.lines
+
+def getJDC(filename,atraiter=atraiter):
+ jdc=JDCdict.get(filename)
+ if not jdc:
+ f=open(filename)
+ src=f.read()
+ f.close()
+ jdc=JDC(filename,src,atraiter)
+ JDCdict[filename]=jdc
+ return jdc
+
--- /dev/null
+import logging
+logger=logging.getLogger()
+hdlr=logging.FileHandler('convert.log','w')
+#formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
+formatter = logging.Formatter('%(levelname)s: %(message)s')
+hdlr.setFormatter(formatter)
+logger.addHandler(hdlr)
+logger.setLevel(logging.INFO)
--- /dev/null
+# -*- coding: utf-8 -*-
+
+import compiler
+import types
+from parseur import Keyword,FactNode,lastparen,lastparen2
+from visiteur import KeywordFinder,visitor
+from utils import indexToCoordinates
+
+debug=0
+
+def parseFact(match,c,kw):
+ submatch=match[2]
+ lastpar=match[0]+lastparen(c.src[match[0]:])
+ if type(submatch[0][0]) ==types.IntType:
+ #mot cle facteur isolé
+ no=FactNode()
+ kw.addChild(no)
+ for ii in range(len(submatch)-1):
+ e=submatch[ii]
+ x,y=indexToCoordinates(c.src,e[0])
+ lineno=y+c.lineno
+ colno=x
+ x,y=indexToCoordinates(c.src,submatch[ii+1][0])
+ endline=y+c.lineno
+ endcol=x
+ no.addChild(Keyword(e[1],lineno,colno,endline,endcol))
+ #last one
+ e=submatch[-1]
+ x,y=indexToCoordinates(c.src,e[0])
+ lineno=y+c.lineno
+ colno=x
+ x,y=indexToCoordinates(c.src,lastpar-1)
+ endline=y+c.lineno
+ endcol=x
+ no.addChild(Keyword(e[1],lineno,colno,endline,endcol))
+ else:
+ #mot cle facteur multiple
+ ii=0
+ for l in submatch:
+ lastpar=l[0][0]+lastparen2(c.src[l[0][0]:])
+ ii=ii+1
+ no=FactNode()
+ kw.addChild(no)
+ for j in range(len(l)-1):
+ e=l[j]
+ x,y=indexToCoordinates(c.src,e[0])
+ lineno=y+c.lineno
+ colno=x
+ x,y=indexToCoordinates(c.src,l[j+1][0])
+ endline=y+c.lineno
+ endcol=x
+ no.addChild(Keyword(e[1],lineno,colno,endline,endcol))
+ #last one
+ e=l[-1]
+ x,y=indexToCoordinates(c.src,e[0])
+ lineno=y+c.lineno
+ colno=x
+ x,y=indexToCoordinates(c.src,lastpar-1)
+ endline=y+c.lineno
+ endcol=x
+ no.addChild(Keyword(e[1],lineno,colno,endline,endcol))
+
+
+def parseKeywords(root):
+ """A partir d'un arbre contenant des commandes, ajoute les noeuds fils correspondant aux mocles
+ de la commande
+ """
+ matchFinder=KeywordFinder()
+
+ for c in root.childNodes:
+ ast=compiler.parse(c.src)
+ #print ast
+ matchFinder.reset(c.src)
+ visitor.walk(ast, matchFinder)
+ #print matchFinder.matches
+ if len(matchFinder.matches) > 1:
+ #plusieurs mocles trouvés : un mocle commence au début du keyword (matchFinder.matches[i][0])
+ # et finit juste avant le keyword suivant (matchFinder.matches[i+1][0]])
+ for i in range(len(matchFinder.matches)-1):
+ if debug:print "texte:",c.src[matchFinder.matches[i][0]:matchFinder.matches[i+1][0]]
+ x,y=indexToCoordinates(c.src,matchFinder.matches[i][0])
+ lineno=y+c.lineno
+ colno=x
+ x,y=indexToCoordinates(c.src,matchFinder.matches[i+1][0])
+ endline=y+c.lineno
+ endcol=x
+ if debug:print matchFinder.matches[i][0],matchFinder.matches[i][1],lineno,colno,endline,endcol
+ kw=Keyword(matchFinder.matches[i][1],lineno,colno,endline,endcol)
+ c.addChild(kw)
+ submatch= matchFinder.matches[i][2]
+ if submatch:
+ parseFact(matchFinder.matches[i],c,kw)
+ #dernier mocle : il commence au debut du dernier keyword (matchFinder.matches[i+1][0]) et
+ #finit avant la parenthese fermante de la commande (c.lastparen)
+ if debug:print "texte:",c.src[matchFinder.matches[i+1][0]:c.lastparen]
+ x,y=indexToCoordinates(c.src,matchFinder.matches[i+1][0])
+ lineno=y+c.lineno
+ colno=x
+ x,y=indexToCoordinates(c.src,c.lastparen)
+ endline=y+c.lineno
+ endcol=x
+ if debug:print matchFinder.matches[i+1][0],matchFinder.matches[i+1][1],lineno,colno,endline,endcol
+ kw=Keyword(matchFinder.matches[i+1][1],lineno,colno,endline,endcol)
+ c.addChild(kw)
+ submatch= matchFinder.matches[i+1][2]
+ if submatch:
+ parseFact(matchFinder.matches[i+1],c,kw)
+
+ elif len(matchFinder.matches) == 1:
+ #un seul mocle trouve : il commence au début du keyword (matchFinder.matches[0][0]) et
+ #finit juste avant la parenthese fermante de la commande (c.lastparen)
+ if debug:print "texte:",c.src[matchFinder.matches[0][0]:c.lastparen]
+ x,y=indexToCoordinates(c.src,matchFinder.matches[0][0])
+ lineno=y+c.lineno
+ colno=x
+ x,y=indexToCoordinates(c.src,c.lastparen)
+ endline=y+c.lineno
+ endcol=x
+ if debug:print matchFinder.matches[0][0],matchFinder.matches[0][1],lineno,colno,endline,endcol
+ kw=Keyword(matchFinder.matches[0][1],lineno,colno,endline,endcol)
+ c.addChild(kw)
+ submatch= matchFinder.matches[0][2]
+ if submatch:
+ parseFact(matchFinder.matches[0],c,kw)
+ else:
+ pass
+
--- /dev/null
+# -*- coding: utf-8 -*-
+import re,string
+import compiler
+
+debug=0
+
+escapedQuotesRE = re.compile(r"(\\\\|\\\"|\\\')")
+stringsAndCommentsRE = \
+ re.compile("(\"\"\".*?\"\"\"|'''.*?'''|\"[^\"]*\"|\'[^\']*\'|#.*?\n)", re.DOTALL)
+allchars = string.maketrans("", "")
+allcharsExceptNewline = allchars[: allchars.index('\n')]+allchars[allchars.index('\n')+1:]
+allcharsExceptNewlineTranstable = string.maketrans(allcharsExceptNewline, '*'*len(allcharsExceptNewline))
+
+def maskStringsAndComments(src):
+ """Remplace tous les caracteres dans commentaires et strings par des * """
+ src = escapedQuotesRE.sub("**", src)
+ allstrings = stringsAndCommentsRE.split(src)
+ # every odd element is a string or comment
+ for i in xrange(1, len(allstrings), 2):
+ if allstrings[i].startswith("'''")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)
+
+#un nombre queconque de blancs,un nom,des blancs
+pattern_oper = re.compile(r"^\s*(.*?=\s*)?([a-zA-Z_]\w*)(\s*)(\()(.*)",re.DOTALL)
+pattern_proc = re.compile(r"^\s*([a-zA-Z_]\w*)(\s*)(\()(.*)",re.DOTALL)
+
+implicitContinuationChars = (('(', ')'), ('[', ']'), ('{', '}'))
+linecontinueRE = re.compile(r"\\\s*(#.*)?$")
+emptyHangingBraces = [0,0,0,0,0]
+
+class UnbalancedBracesException: pass
+
+class Node:
+ def __init__(self):
+ self.childNodes=[]
+
+ def addChild(self,node):
+ self.childNodes.append(node)
+
+class FactNode(Node):pass
+class JDCNode(Node):
+ def __init__(self,src):
+ Node.__init__(self)
+ self.src=src
+
+class Command(Node):
+ def __init__(self,name,lineno,colno,firstparen):
+ Node.__init__(self)
+ self.name=name
+ self.lineno=lineno
+ self.colno=colno
+ self.firstparen=firstparen
+
+class Keyword(Node):
+ def __init__(self,name,lineno,colno,endline,endcol):
+ Node.__init__(self)
+ self.name=name
+ self.lineno=lineno
+ self.colno=colno
+ self.endline=endline
+ self.endcol=endcol
+
+def printNode(node):
+ if hasattr(node,'name'):
+ print node.name
+ else:
+ print "pas de nom pour:",node
+ for c in node.childNodes:
+ printNode(c)
+
+def parser(src,atraiter):
+ """Parse le texte src et retourne un arbre syntaxique (root).
+
+ Cet arbre syntaxique a comme noeuds (childNodes) les commandes à traiter (liste atraiter)
+ """
+ lines=src.splitlines(1)
+ maskedSrc=maskStringsAndComments(src)
+ #print maskedSrc
+ maskedLines=maskedSrc.splitlines(1)
+
+ root=JDCNode(src)
+
+ # (a) dans un premier temps on extrait les commandes et on les insère dans un arbre (root)
+ # les noeuds fils sont stockés dans root.childNodes (liste)
+ lineno=0
+ for line in maskedLines:
+ lineno=lineno+1
+ if debug:print "line",lineno,":",line
+ m=pattern_proc.match(line)
+ if m and (m.group(1) in atraiter):
+ if debug:print m.start(3),m.end(3),m.start(4)
+ root.addChild(Command(m.group(1),lineno,m.start(1),m.end(3)))
+ else:
+ m=pattern_oper.match(line)
+ if m and (m.group(2) in atraiter):
+ root.addChild(Command(m.group(2),lineno,m.start(2),m.end(4)))
+
+ #(b) dans un deuxième temps , on récupère le texte complet de la commande jusqu'à la
+ # dernière parenthèse fermante
+
+ #iterateur sur les lignes physiques masquées
+ iterlines=iter(maskedLines)
+
+ linenum=0
+ for c in root.childNodes:
+ lineno=c.lineno
+ colno=c.colno # début de la commande
+ while linenum < lineno:
+ line=iterlines.next()
+ linenum=linenum+1
+ if linenum != lineno:
+ if debug:print "line %s:"%linenum, line
+ tmp = []
+ hangingBraces = list(emptyHangingBraces)
+ hangingComments = 0
+ while 1:
+ # update hanging braces
+ 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("'''") % 2
+
+ if hangingBraces[0] < 0 or hangingBraces[1] < 0 or hangingBraces[2] < 0:
+ raise UnbalancedBracesException()
+
+ if linecontinueRE.search(line):
+ tmp.append(lines[linenum-1])
+ elif hangingBraces != emptyHangingBraces:
+ tmp.append(lines[linenum-1])
+ elif hangingComments:
+ tmp.append(lines[linenum-1])
+ else:
+ tmp.append(lines[linenum-1])
+ src="".join(tmp)
+ c.src=src
+ c.endline=linenum
+ decal=len(line)-line.rindex(')')
+ c.lastparen=len(src)-decal
+ if debug:print "logical line %s %s:" % (c.lineno,c.endline),src
+ break
+ line=iterlines.next()
+ linenum=linenum+1
+
+ return root
+
+
+def lastparen(src):
+ """Retourne la position de la derniere parenthese fermante dans src a partir du debut de la string
+
+ La string doit contenir la premiere parenthese ouvrante
+ """
+ src=maskStringsAndComments(src)
+ level=0
+ i,n=0,len(src)
+ while i < n:
+ ch=src[i]
+ i=i+1
+ if ch in ('(','['):
+ level=level+1
+ if ch in (')',']'):
+ if level == 0:
+ raise UnbalancedBracesException()
+ level=level-1
+ if level == 0:
+ #derniere parenthese fermante
+ return i
+
+def lastparen2(src):
+ """Retourne la position de la derniere parenthese fermante dans src a partir du debut de la string
+
+ La string ne contient pas la premiere parenthese ouvrante
+ """
+ src=maskStringsAndComments(src)
+ level=1
+ i,n=0,len(src)
+ while i < n:
+ ch=src[i]
+ i=i+1
+ if ch in ('(','['):
+ level=level+1
+ if ch in (')',']'):
+ if level == 0:
+ raise UnbalancedBracesException()
+ level=level-1
+ if level == 0:
+ #derniere parenthese fermante
+ return i
--- /dev/null
+# -*- coding: utf-8 -*-
+import logging
+from parseur import FactNode
+
+debug=1
+#on n'a qu'un mocle par commande. On peut donc supprimer le mocle sans trop de précautions (a part iterer a l'envers sur les commandes)
+#avant de supprimer un autre mocle, on remet à jour l'arbre syntaxique (lineno,colno,etc.)
+def removemocle(jdc,command,mocle):
+ #on itere sur les commandes a l'envers pour ne pas polluer les numeros de ligne avec les modifications
+ commands= jdc.root.childNodes[:]
+ commands.reverse()
+ for c in commands:
+ if c.name != command:continue
+ for mc in c.childNodes:
+ if mc.name != mocle:continue
+ removemc(jdc,c,mc)
+
+ jdc.reset(jdc.getSource())
+
+def removemc(jdc,c,mc):
+ if debug:print "Suppression de:",c.name,mc.name,mc.lineno,mc.colno,mc.endline,mc.endcol
+ logging.info("Suppression de: %s, %s, %s, %s, %d, %d",c.name,mc.name,mc.lineno,mc.colno,mc.endline,mc.endcol)
+ if mc.endline > mc.lineno:
+ if debug:print "mocle sur plusieurs lignes--%s--" % jdc.getLines()[mc.lineno-1][mc.colno:]
+ jdc.getLines()[mc.lineno-1]=jdc.getLines()[mc.lineno-1][:mc.colno]
+ jdc.getLines()[mc.endline-1]=jdc.getLines()[mc.endline-1][mc.endcol:]
+ #attention : supprimer les lignes à la fin
+ jdc.getLines()[mc.lineno:mc.endline-1]=[]
+ else:
+ if debug:print "mocle sur une ligne--%s--" % jdc.getLines()[mc.lineno-1][mc.colno:mc.endcol]
+ s=jdc.getLines()[mc.lineno-1]
+ jdc.getLines()[mc.lineno-1]=s[:mc.colno]+s[mc.endcol:]
+
+def removemocleinfact(jdc,command,fact,mocle):
+ #on itere sur les commandes a l'envers pour ne pas polluer les numeros de ligne avec les modifications
+ commands= jdc.root.childNodes[:]
+ commands.reverse()
+ for c in commands:
+ if c.name != command:continue
+ for mc in c.childNodes:
+ if mc.name != fact:continue
+ l=mc.childNodes[:]
+ l.reverse()
+ for ll in l:
+ for n in ll.childNodes:
+ if n.name != mocle:continue
+ removemc(jdc,c,n)
+
+ jdc.reset(jdc.getSource())
--- /dev/null
+# -*- coding: utf-8 -*-
+import logging
+from parseur import FactNode
+debug=0
+#on n'a qu'un mocle par commande.
+#en fin de traitement, on remet à jour l'arbre syntaxique (lineno,colno,etc.)
+def renamemocle(jdc,command,mocle,new_name):
+ for c in jdc.root.childNodes:
+ if c.name != command:continue
+ for mc in c.childNodes:
+ if mc.name != mocle:continue
+ if debug:print "Renommage de:",c.name,mc.name,mc.lineno,mc.colno
+ logging.info("Renommage de: %s, %s, %s, %s en %s",c.name,mc.name,mc.lineno,mc.colno,new_name)
+ s=jdc.getLines()[mc.lineno-1]
+ jdc.getLines()[mc.lineno-1]=s[:mc.colno]+new_name+s[mc.colno+len(mocle):]
+
+ jdc.reset(jdc.getSource())
+
+def renamemocleinfact(jdc,command,fact,mocle,new_name):
+ for c in jdc.root.childNodes:
+ if c.name != command:continue
+ for mc in c.childNodes:
+ if mc.name != fact:continue
+ l=mc.childNodes[:]
+ #on itere a l'envers
+ l.reverse()
+ for ll in l:
+ for n in ll.childNodes:
+ if n.name != mocle:continue
+ s=jdc.getLines()[n.lineno-1]
+ jdc.getLines()[n.lineno-1]=s[:n.colno]+new_name+s[n.colno+len(mocle):]
+
+ jdc.reset(jdc.getSource())
+
--- /dev/null
+DEBUT()
+
+MAIL=LIRE_MAILLAGE( )
+
+#
+# DEFINITION DES GROUPES DE NOEUDS
+MAIL=DEFI_GROUP( reuse=MAIL, MAILLAGE=MAIL,CREA_GROUP_NO=(
+ _F( GROUP_MA = 'ENCAST'),
+ _F( GROUP_MA = 'CONT_PR'),
+ _F( GROUP_MA = ( 'B', 'SECT_MED', )))
+ )
+
+MAIL=DEFI_GROUP( CREA_GROUP_NO=[
+ _F( GROUP_MA = 'ENCAST',INFO=2),
+ _F( GROUP_MA = 'CONT_PR'),
+ _F( GROUP_MA = ( 'B', 'SECT_MED', ))]
+ )
+#
+# DEFINITION DU MODELE
+MODELE=AFFE_MODELE( MAILLAGE=MAIL,
+ AFFE=_F( TOUT = 'OUI',
+ PHENOMENE = 'MECANIQUE',
+ MODELISATION = 'AXIS_FOURIER') )
+
+#
+# DEFINITION DU MATERIAU
+ACIER=DEFI_MATERIAU( ELAS= _F( E = 2.1E11, NU = 0.3,
+ ALPHA = 1.E-5, RHO = 7800.) #comment
+ #comment
+ )
+
+#
+# ATTRIBUTION DU MATERIAU
+CHMAT=AFFE_MATERIAU( MAILLAGE =MAIL,
+ AFFE=_F( TOUT = 'OUI',
+ MATER = ACIER) )
+CHMAT2=AFFE_MATERIAU( MAILLAGE =MAIL,
+ AFFE=(_F( TOUT = 'OUI', MATER = ACIER),
+ _F( TOUT = 'OUI', MATER = ACIER),
+ _F( TOUT = 'OUI', MATER = ACIER),
+ )
+ )
+STAT_NONLINE(SOLVEUR=_F(METHOD="FRONT",
+ PREC=1.E-3))
+STAT_NONLINE(SOLV=_F(METHOD="FRONT",
+ PREC=1.E-3),
+ AFFE=(_F( TOUT = 'OUI', MATER = ACIER),
+ _F( TOUT = 'OUI', MATER = ACIER),
+ _F( TOUT = 'OUI', MATER = ACIER),
+ )
+ )
+
+MA=LIRE_MAILLAGE(UNITE=20,INFO=2,TEXT="""aaaa(
+bbb""")
+"""
+MOO=AFFE_MODELE()
+"""
+MO=AFFE_MODELE(MAILLAGE=MA,
+ INFO=2,
+ )
+#LIRE_MAILLAGE()
+MA2=LIRE_MAILLAGE(UNITE=21)
+MA3 = LIRE_MAILLAGE ( #comment ( ]
+ UNITE=23,
+ )
+MA4 = LIRE_MAILLAGE ( #commentaire commande
+ UNITE
+ =
+ 24
+ ,INFO=2 #commentaire mocle INFO
+ ) #commentaire fin commande
+M5=LIRE_MAILLAGE ( #comment commande
+)
+a[2*(i+1)]=LIRE_MAILLAGE(UNITE=21)
--- /dev/null
+import re
+
+def indexToCoordinates(src, index):
+ """return le numero de la colonne (x) et le numero de la ligne (y) dans src"""
+ y = src[: index].count("\n")
+ startOfLineIdx = src.rfind("\n", 0, index)+1
+ x = index-startOfLineIdx
+ return x, y
+
+def linetodict(line):
+ """Transforme une ligne (string) en un dictionnaire de mots repérés par le numéro de la colonne"""
+
+ words = re.split("(\w+)", line)
+ h = {};i = 0
+ for word in words:
+ h[i] = word
+ i+=len(word)
+ return h
+
+def dicttoline(d):
+ """Transformation inverse: à partir d'un dictionnaire retourne une ligne"""
+ cols = d.keys()
+ cols.sort()
+ return "".join([d[colno]for colno in cols])
--- /dev/null
+import re
+from compiler import visitor
+
+class MatchFinder:
+ """Visiteur de base : gestion des matches """
+ def reset(self,line):
+ self.matches = []
+ self.words = re.split("(\w+)", line) # every other one is a non word
+ self.positions = []
+ i = 0
+ for word in self.words:
+ self.positions.append(i)
+ i+=len(word)
+ self.index = 0
+
+ def popWordsUpTo(self, word):
+ if word == "*":
+ return # won't be able to find this
+ posInWords = self.words.index(word)
+ idx = self.positions[posInWords]
+ self.words = self.words[posInWords+1:]
+ self.positions = self.positions[posInWords+1:]
+
+ def appendMatch(self,name):
+ idx = self.getNextIndexOfWord(name)
+ self.matches.append((idx, name))
+
+ def getNextIndexOfWord(self,name):
+ return self.positions[self.words.index(name)]
+
+
+class KeywordFinder(MatchFinder):
+ """Visiteur pour les keywords d'une commande """
+
+ def visitKeyword(self,node):
+ idx = self.getNextIndexOfWord(node.name)
+ #self.appendMatch(node.name)
+ self.popWordsUpTo(node.name)
+ prevmatches=self.matches
+ self.matches = []
+ for child in node.getChildNodes():
+ self.visit(child)
+ prevmatches.append((idx, node.name,self.matches))
+ self.matches=prevmatches
+
+ def visitTuple(self,node):
+ matchlist=[]
+ for child in node.getChildNodes():
+ self.matches = []
+ self.visit(child)
+ if self.matches:
+ #Pour eviter les tuples et listes ordinaires, on ne garde que les visites fructueuses
+ matchlist.append(self.matches)
+ self.matches=matchlist
+
+ visitList=visitTuple
+
+ def visitName(self,node):
+ self.popWordsUpTo(node.name)
+ def visitAssName(self,node):
+ self.popWordsUpTo(node.name)