Compare commits

..

4 Commits

4 changed files with 49 additions and 13 deletions

View File

@@ -20,5 +20,5 @@ The reason I chose to do this, is that my parsing algorithm considers everything
- Simple error checking - Simple error checking
## To-do ## To-do
- Simple algebraic parsing (assign values to variables, etc.) - ~~Simple algebraic parsing (assign values to variables, etc.)~~
- More robust error-checking - More robust error-checking

View File

@@ -2,10 +2,12 @@ import re
from parse import * from parse import *
# List of valid operators # List of valid operators
opers = ['+', '-', '*', '/'] opers = ['+', '-', '*', '/', '=']
# Regular expression that checks for valid characters in an expression # Regular expression that checks for valid characters in an expression
valid_chars = '[ 0-9.\(\)+-\/*]' valid_chars = '[ 0-9a-z.\(\)+-\/*=]'
variables = {}
def print_error(error_code): def print_error(error_code):
@@ -24,6 +26,8 @@ def print_error(error_code):
print("You have two operators next to each other.") print("You have two operators next to each other.")
case 4: case 4:
print("One of your values is improperly formatted.") print("One of your values is improperly formatted.")
case 5:
print("Uninitialized variable.")
def check_errors(expr): def check_errors(expr):
expr_small = expr.replace(" ", "") # Remove spaces from the string, to make it easier to parse expr_small = expr.replace(" ", "") # Remove spaces from the string, to make it easier to parse
@@ -54,9 +58,10 @@ def check_errors(expr):
expr = parse(expr) expr = parse(expr)
for val in expr: for val in expr:
if val.count('.') > 1: if val.count('.') > 1: # A value can have at most 1 period
return 4 return 4
if val.isalpha() and not val in variables and val != expr[0]: # If the token is a string, and isn't in the dictionary, and isn't the variable at index 0 (e.g. 'x' in 'x = 4')
return 5
return 0 return 0
@@ -66,6 +71,12 @@ def evaluate(subexpr): # Evaluate a tokenized expression, that contains no paran
print(subexpr) print(subexpr)
for index, val in enumerate(subexpr): # Replace variables with their values
if str(val).isalpha():
subexpr[index] = variables[val]
print(subexpr)
if (len(subexpr) == 1): if (len(subexpr) == 1):
return float(subexpr[0]) return float(subexpr[0])
@@ -113,12 +124,28 @@ def find_inner(subexpr):
def main(): def main():
while True: while True:
variable = ''
expr = input() expr = input()
errno = check_errors(expr) errno = check_errors(expr)
if errno != 0: if errno != 0:
print_error(errno) print_error(errno)
continue # If an error was generated, print an error message and continue on to the next iteration of the loop continue # If an error was generated, print an error message and continue on to the next iteration of the loop
expr = find_inner(expr)
expr_tokenized = parse(expr)
if expr_tokenized[0].isalpha() and expr_tokenized[1] == '=': # If the expression assigns a value to a variable
variable = expr_tokenized[0] # The first token is the variable
expr_tokenized.pop(0) # Remove the first and second tokens
expr_tokenized.pop(0)
expr = find_inner(''.join(expr_tokenized))
variables.update({variable: expr})
else:
expr = find_inner(expr)
print(expr) print(expr)
print(variables)
main() main()

View File

@@ -1,6 +1,6 @@
def parse(expr): def parse(expr):
opers = ['+', '-', '*', '/'] opers = ['+', '-', '*', '/', '=']
num_par = 0 num_par = 0
tokenized = [] tokenized = []
@@ -9,19 +9,19 @@ def parse(expr):
while index < len(expr): while index < len(expr):
if expr[index] in opers: if expr[index] in opers:
tokenized.append(expr[index]) tokenized.append(expr[index])
index += 1
elif expr[index].isdigit() or expr[index] == '.': elif expr[index].isdigit() or expr[index] == '.':
while (index < len(expr)) and (expr[index].isdigit() or expr[index] == '.'): while (index < len(expr)) and (expr[index].isdigit() or expr[index] == '.'):
temp_string += expr[index] temp_string += expr[index]
index += 1 index += 1
tokenized.append(temp_string) tokenized.append(temp_string)
temp_string = ""
elif expr[index] == '(': elif expr[index] == '(':
num_par = 1 num_par = 1
temp_string += expr[index] temp_string += expr[index]
index += 1 index += 1
while num_par != 0 and index < len(expr): while index < len(expr) and num_par != 0:
temp_string += expr[index] temp_string += expr[index]
if expr[index] == '(': if expr[index] == '(':
num_par += 1 num_par += 1
@@ -30,9 +30,18 @@ def parse(expr):
index += 1 index += 1
tokenized.append(temp_string) tokenized.append(temp_string)
temp_string = ""
elif expr[index].isalpha(): # If you encounter a variable
temp_string += expr[index]
index += 1
while index < len(expr) and expr[index].isalpha():
temp_string += expr[index]
index += 1
tokenized.append(temp_string)
index += 1 else:
index += 1
temp_string = ""
return tokenized return tokenized

View File

@@ -1,3 +1,3 @@
1. Implement variable assignment e.g. x = 5 ----DONE---- 1. Implement variable assignment e.g. x = 5
2. ALlow these variables to be used in future expressions ----DONE---- 2. Allow these variables to be used in future expressions
3. Implement additional error-checking 3. Implement additional error-checking