You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
6.1 KiB
151 lines
6.1 KiB
from Pile import Pile_chaine as Pile
|
|
from math import *
|
|
|
|
def infixe2npi(liste_en_infixe):
|
|
"""conversion d'une liste en notation infixe à une liste en npi"""
|
|
|
|
pile_op = Pile()
|
|
sortie = []
|
|
|
|
fonctions = ["sin","cos","tan","sqrt"]
|
|
operateurs = ["+", "-", "*", "/", "^","opp"]
|
|
priorite = {"sin":1,
|
|
"opp":1,
|
|
"^":1,
|
|
"*":2,
|
|
"/":2,
|
|
"+":3,
|
|
"-":3
|
|
}
|
|
associativite = {"opp": "droit",
|
|
"^":"droit",
|
|
"*":"gauche",
|
|
"/":"gauche",
|
|
"+":"gauche",
|
|
"-":"gauche"
|
|
}
|
|
last_token = None
|
|
print(40*"=")
|
|
for index_token, token in enumerate(liste_en_infixe):
|
|
print(20*"-")
|
|
print("token", token)
|
|
#nombre
|
|
if estUnNombre(token):
|
|
if sortie != []:
|
|
if pile_op.est_vide():
|
|
#mul. implicite
|
|
sortie.append(token)
|
|
sortie.append("*")
|
|
print("c'est un nombre et il est dans le cas pile_op.est_vide()")
|
|
else:
|
|
print(last_token, pile_op.sommet())
|
|
if last_token == pile_op.sommet() or pile_op.sommet() == "opp":
|
|
#opération binaire normale ou fonction (avec avant elle ultimement une opération binaire)
|
|
sortie.append(token)
|
|
print("c'est un nombre et il est dans le cas last_token == pile_op.sommet()")
|
|
if last_token == sortie[-1]:
|
|
print("c'est un nombre et il est dans le cas last_token == sortie[-1]")
|
|
#on a affaire à une expression (chiffre (... 2), opération (... +), fonction (... fx)) qui est in fine un nombre
|
|
cleanFx(pile_op, sortie)
|
|
sortie.append(token)
|
|
sortie.append("*")
|
|
else:
|
|
sortie.append(token)
|
|
print("c'est un nombre et il est dans le cas sortie == []")
|
|
#fonction
|
|
elif token in fonctions:
|
|
if sortie != []:
|
|
if pile_op.est_vide():
|
|
#mul. implicite
|
|
pile_op.empiler("*")
|
|
pile_op.empiler(token)
|
|
else:
|
|
if last_token == pile_op.sommet() or pile_op.sommet() == "opp":
|
|
#composition de fonctions, ou fonction qui suit un opérateur
|
|
pile_op.empiler(token) #normal
|
|
if last_token == sortie[-1]:
|
|
#le dernier element est l'argument de la fonction (ou
|
|
#des fonctions, composées) sur la pile - s'il y a des fonctions
|
|
cleanFx(pile_op, sortie)
|
|
pile_op.empiler("*")
|
|
pile_op.empiler(token)
|
|
else:
|
|
pile_op.empiler(token)
|
|
|
|
#operateur
|
|
elif token in operateurs:
|
|
if not (estUnNombre(last_token) or last_token == ")"):
|
|
#opérations unaires
|
|
if token == "-" :
|
|
#opposé
|
|
pile_op.empiler("opp")
|
|
elif token == "+":
|
|
#identité
|
|
pass
|
|
else:
|
|
raise ValueError("Opérateur mal utilisé","n'a ici qu'un seul opérande, quand il devrait en avoir deux.",index_token)
|
|
else:
|
|
try:
|
|
while pile_op.sommet() != "(" and (priorite[pile_op.sommet()] < priorite[token] or (priorite[pile_op.sommet()] == priorite[token] and associativite[token] == "gauche")):
|
|
sortie.append(pile_op.depiler())
|
|
except IndexError:
|
|
pass
|
|
pile_op.empiler(token)
|
|
# "("
|
|
elif token == "(":
|
|
if sortie != []:
|
|
if pile_op.est_vide():
|
|
#mul. implicite
|
|
pile_op.empiler("*")
|
|
pile_op.empiler(token)
|
|
else:
|
|
if last_token == pile_op.sommet() or pile_op.sommet() == "opp":
|
|
#parenthèse qui suit une fonction ou parenthèse normale
|
|
pile_op.empiler(token) #normal
|
|
if last_token == sortie[-1]:
|
|
#le dernier element est l'argument de la fonction (ou
|
|
#des fonctions, composées) sur la pile - s'il y a des fonctions
|
|
cleanFx(pile_op, sortie)
|
|
pile_op.empiler("*")
|
|
pile_op.empiler(token)
|
|
else:
|
|
pile_op.empiler(token)
|
|
# ")"
|
|
elif token == ")":
|
|
try:
|
|
while pile_op.sommet() != "(":
|
|
if pile_op.est_vide():
|
|
raise SyntaxError(("Mauvais () detail", index_token))
|
|
else:
|
|
sortie.append(pile_op.depiler())
|
|
except IndexError:
|
|
raise SyntaxError(("Mauvais parenthésage.", index_token))
|
|
if pile_op.sommet() == "(":
|
|
pile_op.depiler()
|
|
if not pile_op.est_vide():
|
|
if pile_op.sommet() in fonctions:
|
|
sortie.append(pile_op.depiler())
|
|
else:
|
|
raise ValueError("Fonction inconnue","n'est pas une fonction connue, ou il manque des espaces.", index_token)
|
|
last_token = token
|
|
|
|
while not pile_op.est_vide():
|
|
if pile_op.sommet() != "(":
|
|
sortie.append(pile_op.depiler())
|
|
else:
|
|
raise SyntaxError(("Mauvais parenthésage", 0))
|
|
print("infixe2npi : ",sortie)
|
|
return sortie
|
|
|
|
def cleanFx(pile, sortie):
|
|
#doc bof
|
|
"""sort toutes les fonctions et opérateurs de la pile"""
|
|
while not pile.est_vide():
|
|
sortie.append(pile.depiler())
|
|
return sortie
|
|
|
|
def estUnNombre(txt):
|
|
"""indique si la chaine de caractères txt est un nombre (entier (négatif) ou flottant)"""
|
|
if txt == None : return False
|
|
if txt[0] == "-" : txt = txt.replace('-','',1)
|
|
return txt.replace('.','',1).isdigit()
|