Files
calc_engine/tokenizer.py
T

75 lines
2.5 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 SyntaxError("Invalid grammar, to many periods in number. Found at position " + str (i) + ".")
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 == token.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