89 lines
3.0 KiB
Python
89 lines
3.0 KiB
Python
import token
|
|
|
|
def get_tokens_from_expression_string(expression_string):
|
|
"""
|
|
Takes user input of an actuarial formula and parses the formula to id its components.
|
|
:return: tokens (List of objects of CToken class).
|
|
"""
|
|
tokens = [] # List of objects of CToken class
|
|
tmp = ""
|
|
parsing_number = False
|
|
symbols_dic = {} # Dictionary to keep track of the no. of times each variable appears.
|
|
|
|
for i in range(0, len(expression_string)):
|
|
c = expression_string[i]
|
|
if c == '.' or c.isdigit():
|
|
if tmp.count('.') == 1:
|
|
raise ValueError("Invalid grammar, to many periods in number!")
|
|
if len(tokens) > 1:
|
|
lookBehind = tokens[-1]
|
|
if lookBehind.type == token.TokenType.exp_end:
|
|
tokens.append(token.CToken("^", token.TokenType.power))
|
|
if (i + 1) == len(expression_string):
|
|
tokens.append(token.CToken(tmp + c, token.TokenType.constant))
|
|
parsing_number = True
|
|
tmp = tmp + c
|
|
continue
|
|
elif c == '(':
|
|
if parsing_number:
|
|
tokens.append(token.CToken(tmp, token.TokenType.constant))
|
|
tokens.append(token.CToken("*", token.TokenType.multiply))
|
|
tokens.append(token.CToken("(", token.TokenType.exp_start))
|
|
parsing_number = False
|
|
tmp = ""
|
|
continue
|
|
elif c == ')':
|
|
if parsing_number:
|
|
tokens.append(token.CToken(tmp, token.TokenType.constant))
|
|
tokens.append(token.CToken(")", token.TokenType.exp_end))
|
|
parsing_number = False
|
|
tmp = ""
|
|
continue
|
|
elif token.TokenType.get_operator(c) != token.TokenType.unknown:
|
|
if parsing_number:
|
|
tokens.append(token.CToken(tmp, token.TokenType.constant))
|
|
tokens.append(token.CToken(c, token.TokenType.get_operator(c)))
|
|
parsing_number = False
|
|
tmp = ""
|
|
continue
|
|
elif c != ' ':
|
|
if len(tokens) > 1:
|
|
lookBehind = tokens[-1]
|
|
if lookBehind.type == TokenType.exp_end:
|
|
tokens.append(token.CToken("^", token.TokenType.power))
|
|
if (i + 1) < len(expression_string):
|
|
lookAHead = expression_string[i + 1]
|
|
if lookAHead == '(':
|
|
tokens.append(token.CToken(c, token.TokenType.variable))
|
|
tokens.append(token.CToken("*", token.TokenType.multiply))
|
|
tmp = ""
|
|
parsing_number = False
|
|
continue
|
|
if parsing_number:
|
|
tokens.append(token.CToken(tmp, token.TokenType.constant))
|
|
tokens.append(token.CToken("*", token.TokenType.multiply))
|
|
if c in symbols_dic.keys():
|
|
symbols_dic[c] += 1
|
|
else:
|
|
symbols_dic[c] = 1
|
|
tokens.append(token.CToken(c + str(symbols_dic[c]), token.TokenType.variable))
|
|
parsing_number = False
|
|
tmp = ""
|
|
|
|
return tokens
|
|
|
|
def operate(n1, n2, tokenType):
|
|
if tokenType == token.TokenType.add:
|
|
print("Adding %d and %d to get %d." %(n1, n2, n1 + n2))
|
|
elif tokenType == token.TokenType.subtract:
|
|
print("Subtracting %d and %d to get %d." %(n1, n2, n1 - n2))
|
|
elif tokenType == token.TokenType.multiply:
|
|
print("Multiplying %d and %d to get %d" %(n1, n2, n1 * n2))
|
|
elif tokenType == token.TokenType.divide:
|
|
print("Dividing %d and %d to get %d" %(n1, n2, n1 / n2))
|
|
elif tokenType == token.TokenType.power:
|
|
print("Raising %d to the power of %d to get %d" %(n1, n2, n1**n2))
|
|
else:
|
|
raise ValueError("Invalid operator value.")
|
|
|