Hors-sujet
Analyseur lexical sur PYTHON
Salut !
Je voulais programmer un analyseur lexical sur python qui permet de découper un texte selon les variables, nombres, signes mathématiques etc... qu’il contient. Cela en utilisant seulement le module "re" et toutes les autres fonctions de base de python (sans le module ’sys’). J’ai réussi à faire un programme qui stocke les informations sur les positions des variables, des nombres etc... mais mon programme est plutôt lourd et surtout il renvoi les variables, nombres et autres dans des listes à la place d’avoir ce que je voudrais, c’est à dire un texte où les variables, nombres etc... sont espacés et dans le bon ordre.
Pour rendre cela plus clair :
Ce que je veux :
’AA45AA’ ---> ’ AA 45 AA ’
Ce que j’ai :
’AA45AA’ ---> ’ indV : [2,’AA’,6,’AA] ; indN : [4,’45’]
Voici mon code :
from math import *
import re
class AnLex :
VAR=’[a-zA-Z]+’
NR=’[0-9]+[.] ?[0-9]*’
SOUS=’[-]’
ADD=’[+]’
MULT=’[*]’
DIV=’[/]’
PARG=’[(]’
PARD=’[)]’
def __init__(self,txt) :
VAR=’[a-zA-Z]+’
NR=’[0-9]+[.] ?[0-9]*’
SOUS=’[-]’
ADD=’[+]’
MULT=’[*]’
DIV=’[/]’
PARG=’[(]’
PARD=’[)]’
self.txt=txt
self.VAR=re.findall(VAR,txt)
self.NR=re.findall(NR,txt)
self.SOUS=re.findall(SOUS,txt)
self.ADD=re.findall(ADD,txt)
self.MULT=re.findall(MULT,txt)
self.DIV=re.findall(DIV,txt)
self.PARG=re.findall(PARG,txt)
self.PARD=re.findall(PARD,txt)
def search(self) :
’’’mettre au point un système qui renvoie les string découper en fonction du type de charactère dans une liste’’’
indV=[]
indN=[]
indS=[]
indA=[]
indM=[]
indD=[]
indPG=[]
indPD=[]
def Vp(B) :
nonlocal indV
V=re.search(AnLex.VAR,B)
V=V.span()
Y=B[slice(V[0],V[1])]
text=B[V[1] :]
indV=indV + [indV[-2]+V[1]] + [Y]
if re.search(AnLex.VAR,text) !=None :
Vp(text)
#une liste qui stocke les positions des vars
def V(self) :
nonlocal indV
V=re.search(AnLex.VAR,self.txt) #début de V :renvoie les premières VAR dans txt
V=V.span()
Y=self.txt[slice(V[0],V[1])]
text =self.txt[V[1] :] #fin de V, la première suite de variable a été trouvée et est maintenant supprimmée de txt (j’ai peut être pas besoin de remove V[0] de txt et à la place exécuter cette action dans le cas seul où une Var a déjà été trouvée dans txt)
indV=indV + [V[1]] + [Y]
if re.search(AnLex.VAR,text) !=None :
Vp(text) #une liste qui stocke les positions des vars
print(’indV :’,indV)
def Np(B) :
nonlocal indN
N=re.search(AnLex.NR,B)
N=N.span()
Y=B[slice(N[0],N[1])]
text=B[N[1] :]
indN=indN + [indN[-2]+N[1]] + [Y]
if re.search(AnLex.NR,text) !=None :
Np(text)
#une liste qui stocke les positions des vars
def N(self) :
’’’renvoie les premiers nombres dans txt’’’
nonlocal indN
N=re.search(AnLex.NR,self.txt)
N=N.span()
Y=self.txt[slice(N[0],N[1])]
text = self.txt[N[1] :]
indN=indN + [N[1]] + [Y]
if re.search(AnLex.NR,text) !=None :
Np(text)
print(’indN :’,indN)
def Sp(B) :
nonlocal indS
S=re.search(AnLex.SOUS,B)
S=S.span()
Y=B[slice(S[0],S[1])]
text=B[S[1] :]
indS=indS + [indS[-2]+S[1]] + [Y]
if re.search(AnLex.SOUS,text) !=None :
Sp(text)
#une liste qui stocke les positions des vars
def S(self) :
nonlocal indS
B=self.txt
S=re.search(AnLex.SOUS,self.txt)
S=S.span()
Y=self.txt[slice(S[0],S[1])]
text=B[S[1] :]
indS=indS+[S[1]]+[Y]
if re.search(AnLex.SOUS,text) !=None :
Sp(text)
print(’indS :’,indS)
def Ap(B) :
nonlocal indA
A=re.search(AnLex.ADD,B)
A=A.span()
Y=B[slice(A[0],A[1])]
text=B[A[1] :]
indA=indA + [indA[-2]+A[1]] + [Y]
if re.search(AnLex.ADD,text) !=None :
Ap(text)
#une liste qui stocke les positions des vars
def A(self) :
nonlocal indA
B=self.txt
A=re.search(AnLex.ADD,self.txt)
A=A.span()
Y=self.txt[slice(A[0],A[1])]
text=B[A[1] :]
indA=indA+[A[1]]+[Y]
if re.search(AnLex.ADD,text) !=None :
Ap(text)
print(’indA :’,indA)
def Mp(B) :
nonlocal indM
M=re.search(AnLex.MULT,B)
M=M.span()
Y=B[slice(M[0],M[1])]
text=B[M[1] :]
indM=indM + [indM[-2]+M[1]] + [Y]
if re.search(AnLex.MULT,text) !=None :
Mp(text)
#une liste qui stocke les positions des vars
def M(self) :
nonlocal indM
B=self.txt
M=re.search(AnLex.MULT,self.txt)
M=M.span()
Y=self.txt[slice(M[0],M[1])]
text=B[M[1] :]
indM=indM+[M[1]]+[Y]
if re.search(AnLex.MULT,text) !=None :
Mp(text)
print(’indM :’,indM)
def Dp(B) :
nonlocal indD
D=re.search(AnLex.DIV,B)
D=D.span()
Y=B[slice(D[0],D[1])]
text=B[D[1] :]
indD=indD + [indD[-2]+D[1]] + [Y]
if re.search(AnLex.DIV,text) !=None :
Dp(text)
#une liste qui stocke les positions des vars
def D(self) :
nonlocal indD
B=self.txt
D=re.search(AnLex.DIV,self.txt)
D=D.span()
Y=self.txt[slice(D[0],D[1])]
text=B[D[1] :]
indD=indD+[D[1]]+[Y]
if re.search(AnLex.DIV,text) !=None :
Dp(text)
print(’indD :’,indD)
def PGp(B) :
nonlocal indPG
PG=re.search(AnLex.PARG,B)
PG=PG.span()
Y=B[slice(PG[0],PG[1])]
text=B[PG[1] :]
indPG=indPG + [indPG[-2]+PG[1]] + [Y]
if re.search(AnLex.PARG,text) !=None :
PGp(text)
#une liste qui stocke les positions des vars
def PG(self) :
nonlocal indPG
B=self.txt
PG=re.search(AnLex.PARG,self.txt)
PG=PG.span()
Y=self.txt[slice(PG[0],PG[1])]
text=B[PG[1] :]
indPG=indPG+[PG[1]]+[Y]
if re.search(AnLex.PARG,text) !=None :
PGp(text)
print(’indPG :’,indPG)
def PDp(B) :
nonlocal indPD
PD=re.search(AnLex.PARD,B)
PD=PD.span()
Y=B[slice(PD[0],PD[1])]
text=B[PD[1] :]
indPD=indPD + [indPD[-2]+PD[1]] + [Y]
if re.search(AnLex.PARD,text) !=None :
PDp(text)
#une liste qui stocke les positions des vars
def PD(self) :
nonlocal indPD
B=self.txt
PD=re.search(AnLex.PARD,self.txt)
PD=PD.span()
Y=self.txt[slice(PD[0],PD[1])]
text=B[PD[1] :]
indPD=indPD+[PD[1]]+[Y]
if re.search(AnLex.PARD,text) !=None :
PDp(text)
print(’indPD :’,indPD)
if re.search(AnLex.VAR,self.txt) !=None:V(self)
if re.search(AnLex.NR,self.txt) !=None:N(self)
if re.search(AnLex.SOUS,self.txt) !=None:S(self)
if re.search(AnLex.ADD,self.txt) !=None:A(self)
if re.search(AnLex.MULT,self.txt) !=None:M(self)
if re.search(AnLex.DIV,self.txt) !=None:D(self)
if re.search(AnLex.PARG,self.txt) !=None:PG(self)
if re.search(AnLex.PARD,self.txt) !=None:PD(self)
Analyseur lexical sur PYTHON
Bonjour Po,
Tout d’abord je pense que la meilleur façon de faire ce que tu souhaite est d’utiliser une lib type pybison qui à mon humble avis seras la manière la plus propre et la plus rapide en temps d’exécution.
Si tu veux vraiment le faire "à la main" l’astuce et de :
– Te faire un tableau d’élément à matcher [(’VAR’,’[a-zA-Z] ’),...]
– Te faire une fonction qui te retourne la classe et le plus grand élément matchant une des classe que tu à définit dans le tableau précédent
Par exemple pour ta chaine AA45AA qui te retourne (2,’VAR’,’AA’)
Dans ta fonction principale tu fais donc
i = 0
max_match(mon_str[i :],tab_match) #ne pas oublier le :
tu stock le resultat dans un tableau
ici tu ajoute 2 à i
et tu continue
max_match(mon_str[i :],tab_match) ...
le but etant à la fin que tu obtiennes [(2,’VAR’,’AA’),(2,’NR’,45),(2,’VAR’,’AA’)
Tu peux t’inspirer de ce tuto, https://replit.com/talk/learn/Make-a-Full-Lexer-in-Python/111397 mais attention contrairement à toi il est moins générique.
Bon courage.