Browse Source

fonctions

master
Kalyax 2 years ago
parent
commit
6381b32ea9
  1. 113
      infixe.py
  2. 11
      main.py
  3. 67
      misc/expression.py
  4. 39
      misc/parser.py
  5. 27
      misc/tokenizer.py

113
infixe.py

@ -1,113 +0,0 @@
import re
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 == Token.OPERAND_ADDITION:
return self.gauche.evalue() + self.droite.evalue()
elif self.val == Token.OPERAND_MULTIPLICATION:
return self.gauche.evalue() * self.droite.evalue()
else:
return int(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__()) + ")"
class Token:
ADDITION = "+"
MULTIPLICATION = "*"
PARENTHESE_OUVERTE = "("
PARENTHESE_FERME = ")"
NUMBER = re.compile(r'(?:\d+)?.\d+')
@staticmethod
def isNumber(n):
return Token.NUMBER.match(str(n)) is not None
def tokenize(text):
buffer = ""
tokens = []
for char in text:
if Token.isNumber(char):
buffer += char
continue
elif char == " ":
continue
if buffer != "":
tokens.append(buffer)
buffer = ""
tokens.append(char)
if buffer != "":
tokens.append(buffer)
return tokens
def arbre(tokens): #-> Expression
print(tokens)
current = None
waiting_before_exp = None
waiting_for_after_exp = None
i = 0
while i < len(tokens):
if tokens[i] == "(":
j = i + 1
innerBrackets = 1
innerTokens = []
while tokens[j] != ")" and innerBrackets != 0:
if tokens[j] == "(":
innerBrackets += 1
elif tokens[j] == ")":
innerBrackets -= 1
innerTokens.append(tokens[j])
j += 1
exp = arbre(innerTokens)
tokens = tokens[:i] + [" "] + tokens[j+1:]
#i -= j+1
if waiting_for_after_exp != None:
waiting_for_after_exp.droite = exp
waiting_before_exp = waiting_for_after_exp
waiting_for_after_exp = None
else:
waiting_before_exp = exp
elif tokens[i] == "*" or 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()
i += 1
return waiting_for_after_exp
if __name__ == "__main__":
print(arbre(tokenize("(2*8)+(4+7)")))

11
main.py

@ -1,4 +1,9 @@
from reader import * from misc.parser import *
from misc.tokenizer import *
cal = str(input("Entrez votre calcul en NPI : ")) while True:
print(npi2tree(shutting_yard(tokenize(cal))).evalue()) calcul = str(input("Entrez votre calcul en NPI : "))
tokens = tokenize(calcul)
npi = shutting_yard(tokens)
expression = npi2tree(npi)
print(expression.evalue())

67
expression.py → misc/expression.py

@ -1,28 +1,5 @@
import re import re
from math import cos, sin, exp, sqrt
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: class Expression:
@ -42,6 +19,17 @@ class Expression:
return self.gauche.evalue() * self.droite.evalue() return self.gauche.evalue() * self.droite.evalue()
elif self.val == "/": elif self.val == "/":
return self.gauche.evalue() / self.droite.evalue() return self.gauche.evalue() / self.droite.evalue()
elif self.val == "^":
return self.gauche.evalue() ** self.droite.evalue()
elif self.val == "cos":
return cos(self.gauche.evalue())
elif self.val == "sin":
return sin(self.gauche.evalue())
elif self.val == "exp":
return exp(self.gauche.evalue())
elif self.val == "sqrt":
return sqrt(self.gauche.evalue())
else: else:
return float(self.val) return float(self.val)
@ -49,3 +37,34 @@ class Expression:
if Token.isNumber(self.val): if Token.isNumber(self.val):
return str(self.val) return str(self.val)
return "(" + str(self.gauche.__str__()) + str(self.val) + str(self.droite.__str__()) + ")" return "(" + str(self.gauche.__str__()) + str(self.val) + str(self.droite.__str__()) + ")"
class Token:
NUMBER = 0
OPERATOR = 1
PARENTHESE = 2
FUNCTION = 3
@staticmethod
def isChar(n):
return re.match(r'[a-z]', str(n)) is not None
@staticmethod
def isNumber(n):
return re.match(r'\d+', str(n)) is not None
@staticmethod
def getPrecedence(tok):
if tok == "(" or 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
def __str__(self):
return self.val

39
reader.py → misc/parser.py

@ -1,29 +1,7 @@
from expression import Token, Expression from misc.expression import Token, Expression
from lib.Pile import Pile_chaine as Pile from lib.Pile import Pile_chaine as Pile
from lib.File import File_chaine as File from lib.File import File_chaine as File
def tokenize(text: str) -> list:
buffer = ""
tokens = []
for char in text:
#NUMBER
if Token.isNumber(char) or char == ".":
buffer += char
else:
#PUSH
if buffer != "":
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))
return tokens
def shutting_yard(tokens: list) -> File: def shutting_yard(tokens: list) -> File:
output = File() output = File()
opertator = Pile() opertator = Pile()
@ -53,19 +31,18 @@ def shutting_yard(tokens: list) -> File:
return output return output
def npi2tree(tokens: File) -> Expression: def npi2tree(tokens: File) -> Expression:
pile = Pile() pile = Pile()
while not tokens.est_vide(): while not tokens.est_vide():
token = tokens.defiler() token = tokens.defiler()
if token.val in ["+", "-", "*", "/"]: if token.type == Token.OPERATOR:
exp = Expression(token.val, pile.depiler(), pile.depiler()) a, b = pile.depiler(), pile.depiler()
t = ((a, b) if token.val != "^" else (b, a))
exp = Expression(token.val, *t)
pile.empiler(exp)
elif token.type == Token.FUNCTION:
exp = Expression(token.val, pile.depiler(), None)
pile.empiler(exp) pile.empiler(exp)
else: else:
pile.empiler(Expression(token.val)) pile.empiler(Expression(token.val))
return pile.depiler() return pile.depiler()
if __name__ == "__main__":
a = npi2tree(shutting_yard(tokenize("2+44*(4+21)"))).evalue()
print(a)
#print(npi2tree(tokenize("6 4 3 + *")))

27
misc/tokenizer.py

@ -0,0 +1,27 @@
from misc.expression import Token
def tokenize(text: str) -> list:
buffer_num = ""
buffer_func = ""
tokens = []
for char in text:
if Token.isChar(char):
buffer_func += char
elif Token.isNumber(char) or char == ".":
buffer_num += char
else:
if buffer_num != "":
tokens.append(Token(Token.NUMBER, buffer_num))
buffer_num = ""
if buffer_func != "":
tokens.append(Token(Token.FUNCTION, buffer_func))
buffer_func = ""
if char == "(" or char == ")":
tokens.append(Token(Token.PARENTHESE, char))
elif char != " ":
tokens.append(Token(Token.OPERATOR, char))
if buffer_num != "":
tokens.append(Token(Token.NUMBER, buffer_num))
if buffer_func != "":
tokens.append(Token(Token.FUNCTION, buffer_func))
return tokens
Loading…
Cancel
Save