Browse Source

ahhhhhhhhhhhhhhhhhhhhhhh

master
alexandre.aboulin 2 years ago
parent
commit
684e22cec7
  1. 52
      expression.py
  2. 45
      infixe.py
  3. 114
      lib/File.py
  4. 91
      lib/Pile.py
  5. 111
      lib/listeChaine.py
  6. 4
      main.py
  7. 79
      reader.py

52
expression.py

@ -1 +1,51 @@
from lexer import Token
import re
class Token:
NUMBER = 0
OPERATOR = 1
PARENTHESE = 2
FUNCTION = 3
@staticmethod
def isNumber(n):
return re.match(r'\d+', str(n)) is not None
@staticmethod
def getPrecedence(tok):
if tok == "(" or tok == "":
return 4
elif tok == "*" or tok == "/":
return 3
elif tok == "+" or tok == "-":
return 2
def __init__(self, type, val):
self.type = type
self.val = val
class Expression:
def __init__(self, val=None, gauche=None, droite=None):
if Token.isNumber(val) and (gauche != None or droite != None):
raise AttributeError("gauche et droite ne peuvent pas exister si val est un nombre")
self.val = val
self.gauche = gauche
self.droite = droite
def evalue(self):
if self.val == "+":
return self.gauche.evalue() + self.droite.evalue()
elif self.val == "-":
return self.gauche.evalue() - self.droite.evalue()
elif self.val == "*":
return self.gauche.evalue() * self.droite.evalue()
elif self.val == "/":
return self.gauche.evalue() / self.droite.evalue()
else:
return float(self.val)
def __str__(self):
if Token.isNumber(self.val):
return str(self.val)
return "(" + str(self.gauche.__str__()) + str(self.val) + str(self.droite.__str__()) + ")"

45
infixe.py

@ -29,7 +29,7 @@ class Token:
PARENTHESE_OUVERTE = "("
PARENTHESE_FERME = ")"
NUMBER = re.compile(r'\d+')
NUMBER = re.compile(r'(?:\d+)?.\d+')
@staticmethod
def isNumber(n):
@ -59,7 +59,6 @@ def arbre(tokens): #-> Expression
waiting_before_exp = None
waiting_for_after_exp = None
##Brackets loop
i = 0
while i < len(tokens):
if tokens[i] == "(":
@ -83,7 +82,7 @@ def arbre(tokens): #-> Expression
else:
waiting_before_exp = exp
elif tokens[i] == "*":
elif tokens[i] == "*" or tokens[i] == "+":
exp = Expression("*")
if Token.isNumber(tokens[i-1]):
exp.gauche = tokens[i-1]
@ -102,49 +101,13 @@ def arbre(tokens): #-> Expression
exp.gauche = waiting_before_exp
waiting_for_after_exp = exp
else:
raise Exception()
elif tokens[i] == "+":
exp = Expression("+")
if Token.isNumber(tokens[i-1]):
exp.gauche = tokens[i-1]
if Token.isNumber(tokens[i+1]):
exp.droite = tokens[i+1]
if Token.isNumber(tokens[i-1]) and Token.isNumber(tokens[i+1]):
return exp
if tokens[i-1] == ")":
exp.gauche = waiting_before_exp
waiting_before_exp = None
elif tokens[i+1] == "(":
waiting_for_after_exp = exp
print(exp)
elif tokens[i-1] == " ":
exp.gauche = waiting_before_exp
waiting_for_after_exp = exp
else:
raise Exception()
raise Exception()
i += 1
##Multiplication loop
#i = 0
#while i != len(tokens):
# if tokens[i] == "*":
# print("at")
# return Expression("*", tokens[i-1], tokens[i+1])
# i += 1
##Addition loop
#i = 0
#while i != len(tokens):
# if tokens[i] == "+":
# return Expression("+", tokens[i-1], tokens[i+1])
# i += 1
return waiting_for_after_exp
if __name__ == "__main__":
print(arbre(tokenize("(2*8)*4+(7*4)*7")))
print(arbre(tokenize("(2*8)+(4+7)")))

114
lib/File.py

@ -0,0 +1,114 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class File_lst:
"""Implémentation d'une file par une liste."""
def __init__(self):
"""Crée une file vide."""
self.__file = []
def est_vide(self):
"""Indique si la file est vide."""
return self.__file == []
def enfiler(self, valeur):
"""Enfile l'élément valeur."""
self.__file.append(valeur)
def defiler(self):
"""Défile la tête de la file et la renvoie."""
return self.__file.pop(0)
def taille(self):
"""Renvoie la taille de la file."""
return len(self.__file)
def tete(self):
"""Renvoie la tête de la file (sans la défiler)."""
return self.__file[0]
def __str__(self):
s = "tete->"
for val in self.__file:
s += str(val) + "->"
return s + "queue"
class Maillon:
"""Un maillon d'une liste doublement chaînée."""
def __init__(self, precedent, valeur, suivant):
self.valeur = valeur
self.precedent = precedent
self.suivant = suivant
def __str__(self):
return str(self.valeur)
class File_chaine:
"""Implémentation d'une file par une liste doublement chaînée."""
def __init__(self):
"""Crée une file vide."""
self.__debut = self.__fin = None
self.__taille = 0
def est_vide(self):
"""Indique si la file est vide."""
return self.__taille == 0
def enfiler(self, valeur):
"""Enfile l'élément valeur."""
maillon = Maillon(self.__fin, valeur, None)
if self.est_vide():
self.__debut = self.__fin = maillon
else:
self.__fin.suivant = maillon
self.__fin = maillon
self.__taille += 1
def defiler(self):
"""Défile la tête de la file et la renvoie."""
if self.est_vide():
raise IndexError("Impossible de défiler une file vide.")
valeur = self.__debut.valeur
self.__taille -= 1
if self.est_vide():
self.__debut = self.__fin = None
else:
self.__debut = self.__debut.suivant
self.__debut.precedent = None
return valeur
def taille(self):
"""Renvoie la taille de la file."""
return self.__taille
def tete(self):
"""Renvoie la tête de la file (sans la défiler)."""
if self.est_vide():
raise IndexError("Une file vide n'a pas de tête.")
return self.__debut.valeur
def __str__(self):
s = "tete->"
maillon = self.__debut
while maillon is not None:
s += str(maillon) + "->"
maillon = maillon.suivant
return s + "queue"
if __name__ == "__main__":
f = File_lst()
print(f.est_vide())
f.enfiler('A')
f.enfiler('B')
f.enfiler('C')
print(f.est_vide())
print(f.tete())
print(f)
print(f.taille())
print(f.defiler())
print(f.defiler())
print(f.defiler())
print(f.est_vide())

91
lib/Pile.py

@ -0,0 +1,91 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from lib.listeChaine import ListeChaine
class Pile_lst:
"""Implémentation d'une pile par une liste."""
def __init__(self):
"""Crée une pile vide."""
self.__pile = []
def est_vide(self):
"""Indique si la pile est vide."""
return self.__pile == []
def empiler(self, valeur):
"""Empile la valeur."""
self.__pile.append(valeur)
def depiler(self):
"""Dépile le sommet de la pile et le renvoie."""
return self.__pile.pop()
def taille(self):
"""Renvoie la taille de la pile."""
return len(self.__pile)
def sommet(self):
"""Renvoie le sommet de la pile (sans le dépiler)."""
return self.__pile[-1]
def __str__(self):
s = "|"
for val in self.__pile:
s = str(val) + "->" + s
return s
class Pile_chaine:
"""Implémentation d'une pile par une liste chaînée."""
def __init__(self):
"""Crée une pile vide."""
self.__pile = ListeChaine()
self.__taille = 0
def est_vide(self):
"""Indique si la pile est vide."""
return self.__taille == 0
def empiler(self, valeur):
"""Empile la valeur."""
self.__pile.ajoute(valeur)
self.__taille += 1
def depiler(self):
"""Dépile le sommet de la pile et le renvoie."""
if self.est_vide():
raise IndexError("Impossible de dépiler une pile vide.")
valeur = self.__pile.tete()
self.__pile = self.__pile.queue()
self.__taille -= 1
return valeur
def taille(self):
"""Renvoie la taille de la pile."""
return self.__taille
def sommet(self):
"""Renvoie le sommet de la pile (sans le dépiler)."""
if self.est_vide():
raise IndexError("Une pile vide n'a pas de sommet.")
return self.__pile.tete()
def __str__(self):
return str(self.__pile) + "->|"
if __name__ == "__main__":
p = Pile_lst()
print(p.est_vide())
p.empiler('A')
p.empiler('B')
p.empiler('C')
print(p.est_vide())
print(p.sommet())
print(p)
print(p.taille())
print(p.depiler())
print(p.depiler())
print(p.depiler())
print(p.est_vide())

111
lib/listeChaine.py

@ -0,0 +1,111 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Sep 22 20:44:35 2020
@author: manu
"""
class Maillon:
"""Un maillon d'une liste chaînée."""
def __init__(self, valeur, suivant):
self.valeur = valeur
self.suivant = suivant
def __str__(self):
"""Renvoie une chane de caractères représentant le maillon."""
return str(self.valeur)
class ListeChaine:
"""Une liste chaînée."""
def __init__(self, tete=None):
"""Crée une liste vide, ou une liste dont la tete (un maillon)
est donnée."""
self.__tete = tete
def est_vide(self):
"""Indique si la liste est vide."""
return self.__tete is None
def tete(self):
"""Renvoie la valeur du premier élément de la liste."""
if self.est_vide():
raise IndexError("La liste vide n'a pas de tête")
return self.__tete.valeur
def queue(self):
"""Renvoie la queue de la liste."""
if self.est_vide():
raise IndexError("La liste vide n'a pas de queue")
return ListeChaine(self.__tete.suivant)
def ajoute(self, valeur):
"""ajoute `valeur` en tête de la liste."""
self.__tete = Maillon(valeur, self.__tete)
def __str__(self):
"""Renvoie une chaîne de caractères représentant la liste."""
maillon = self.__tete
s = ''
while maillon is not None:
s = s + str(maillon.valeur)
maillon = maillon.suivant
if maillon is not None:
s += '->'
return s
def __len__(self):
"""Renvoie la longueur de la liste."""
maillon = self.__tete
long = 0
while maillon is not None:
long = long + 1
maillon = maillon.suivant
return long
def __getitem__(self, n):
"""Renvoie l'élément d'indice n de la liste."""
maillon = self.__tete
i = 0
while i < n and maillon is not None:
i = i + 1
maillon = maillon.suivant
if maillon is None or n < 0:
raise IndexError("Indice non valide")
return maillon.valeur
def __add__(self, other):
"""Renvoie la liste correspondant à la concaténation des 2 listes."""
if self.est_vide():
return other
v = self.tete()
q = self.queue()
return ListeChaine(Maillon(v, (q + other).__tete))
def reverse(self):
"""Renvoie une liste correspondant à la liste renversée."""
res = ListeChaine()
maillon = self.__tete
while maillon is not None:
res.ajoute(maillon.valeur)
maillon = maillon.suivant
return res
if __name__ == "__main__":
lst = ListeChaine()
print(lst.est_vide())
lst.ajoute(306)
lst.ajoute(42)
lst.ajoute(205)
print(lst)
print(lst.est_vide())
print(lst[0])
print(lst[1])
print(len(lst))
lst2 = ListeChaine()
lst2.ajoute(18)
lst2.ajoute(45)
print(lst + lst2)

4
main.py

@ -0,0 +1,4 @@
from reader import *
cal = input("Entrez votre calcul en NPI : ")
print(npi2tree(tokenize(cal)).evalue())

79
reader.py

@ -0,0 +1,79 @@
from expression import Token, Expression
from lib.Pile import Pile_chaine as Pile
from lib.File import File_chaine as File
def tokenize(text):
buffer = ""
tokens = []
for char in text:
#NUMBER
if Token.isNumber(char) or char == ".":
buffer += char
else:
#PUSH
if buffer != "":
print("a")
tokens.append(Token(Token.NUMBER, buffer))
buffer = ""
#SINGLE CHAR
if char != " ":
if char == "(" or char == ")":
tokens.append(Token(Token.PARENTHESE, char))
else:
tokens.append(Token(Token.OPERATOR, char))
if buffer != "":
tokens.append(Token(Token.NUMBER, buffer))
for token in tokens:
print(token.type, ":", token.val)
return tokens
def shutting_yard(tokens):
output = File()
opertator = Pile()
for token in tokens:
if token.type == Token.NUMBER:
output.enfiler(token)
elif token.type == Token.FUNCTION:
opertator.empiler(token)
elif token.type == Token.OPERATOR:
if not opertator.est_vide():
o2 = opertator.sommet()
a = o2 != "("
print(o2.val)
b = Token.getPrecedence(o2.val) > Token.getPrecedence(token.val)
c = Token.getPrecedence(token.val) == Token.getPrecedence(o2.val)
while a and (b or (c)): #and d))
output.enfiler(opertator.depiler())
opertator.empiler(token)
elif token.val == "(":
opertator.empiler(token)
elif token.val == ")":
while opertator.sommet() != "(":
assert not opertator.est_vide()
output.enfiler(opertator.depiler())
assert opertator.sommet() == "("
opertator.depiler()
if opertator.sommet().type == Token.FUNCTION:
output.enfiler(opertator.depiler())
while not opertator.est_vide():
assert opertator.sommet != "("
output.enfiler(opertator.depiler())
return output
def npi2tree(tokens):
pile = Pile()
for token in tokens:
if token in ["+", "-", "*", "/"]:
exp = Expression(token, pile.depiler(), pile.depiler())
pile.empiler(exp)
else:
pile.empiler(Expression(token))
return pile.depiler()
if __name__ == "__main__":
print(shutting_yard(tokenize("2+44(4+21)")))
#print(npi2tree(tokenize("6 4 3 + *")))
Loading…
Cancel
Save