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.
82 lines
2.6 KiB
82 lines
2.6 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"]
|
|
operateurs = ["+", "-", "*", "/", "^"]
|
|
priorite = {"opp":1,
|
|
"^":1,
|
|
"*":2,
|
|
"/":2,
|
|
"+":3,
|
|
"-":3
|
|
}
|
|
associativite = {"opp": "droit",
|
|
"^":"droit",
|
|
"*":"gauche",
|
|
"/":"gauche",
|
|
"+":"gauche",
|
|
"-":"gauche"
|
|
}
|
|
last_token = None
|
|
for token in liste_en_infixe:
|
|
#nombre
|
|
if estUnNombre(token):
|
|
sortie.append(token)
|
|
#fonction
|
|
elif token in fonctions:
|
|
pile_op.empiler(token)
|
|
#operateur
|
|
elif token in operateurs:
|
|
if token == "-" and not (estUnNombre(last_token) or last_token == ")"):
|
|
# "-" est l'opposé, "_" pour prefixe & postfixe
|
|
pile_op.empiler("opp")
|
|
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 == ",":
|
|
while pile_op.sommet() != "(":
|
|
sortie.append(pile_op.depiler())
|
|
# "("
|
|
elif token == "(":
|
|
pile_op.empiler(token)
|
|
# ")"
|
|
elif token == ")":
|
|
try:
|
|
while pile_op.sommet() != "(":
|
|
if not pile_op.est_vide():
|
|
sortie.append(pile_op.depiler())
|
|
else:
|
|
raise SyntaxError
|
|
except IndexError:
|
|
raise SyntaxError
|
|
if pile_op.sommet() == "(":
|
|
pile_op.depiler()
|
|
if not pile_op.est_vide():
|
|
if pile_op.sommet() in fonctions:
|
|
sortie.append(pile_op.depiler())
|
|
|
|
last_token = token
|
|
|
|
while not pile_op.est_vide():
|
|
if pile_op.sommet() != "(":
|
|
sortie.append(pile_op.depiler())
|
|
else:
|
|
raise SyntaxError
|
|
|
|
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()
|