Hors-sujet

jeudi 15 décembre 2022, 18:38  #1
Analyseur lexical sur PYTHON
PO_po
  • 3 posts

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)

mardi 3 janvier 2023, 12:46  #2
Analyseur lexical sur PYTHON
KoronaK
  • 1 posts

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.