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", "opp"] operateurs = ["+", "-", "*", "/", "^"] 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("tour de boucle n°",index_token, "\npile_op \t",pile_op, "\nsortie \t", sortie) #nombre if estUnNombre(token): if sortie != []: if pile_op.est_vide(): #mul. implicite sortie.append(token) sortie.append("*") else: if last_token == pile_op.sommet(): #opération binaire normale ou fonction (avec avant elle ultimement une opération binaire) sortie.append(token) if 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) #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(): #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(): #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()