Solution to hwk7prob2
16 removals
50 lines
32 additions
63 lines
"""Detect matching of parentheses in an expression"""
"""Detect matching of parentheses in an expression"""
# MCS 260 Fall 2021 Lecture 17
# MCS 260 Fall 2021 Lecture 17
# Read expression (which should include parentheses)
# Read expression (which should include parentheses/brackets)
s = input("Expression: ")
s = input("Expression: ")
# We'll use a stack to keep track of all the "("
# We'll use a stack to keep track of all the "(" or "["
# that haven't been matched with ")" yet. Every
# that haven't been matched with ")" or "]" yet. Every
# new "(" we see gets pushed, and every ")" we see
# new opening delimiter we see gets pushed, and every closing
# closes whatever is at the top of the stack.
# delimiter we see closes whatever is at the top of the stack.
currently_open = []
currently_open = []
# We want both the characters of s and their positions
# We want both the characters of s and their positions
# so we use enumerate()
# so we use enumerate()
for i,c in enumerate(s):
for i,c in enumerate(s):
# c is character from s
# c is character from s
# i is the position (0-based index) of that character in s
# i is the position (0-based index) of that character in s
if c == "(":
if c == "(" or c == "[":
# New left paren opened; push it
# New left paren/bracket opened; push it
currently_open.append(i)
currently_open.append([c,i])
elif c == ")":
elif c == ")" or c == "]":
# Right paren closes whatever left paren is at the
# Right delim closes whatever left delim is at the
# top of the stack. But we need to make sure the
# top of the stack. But we need to make sure the
# stack is nonempty before trying to pop.
# stack is nonempty before trying to pop.
try:
try:
currently_open.pop()
# i0 and c0 are the corresponding i and c
# for the opening paren/bracket
c0, i0 = currently_open.pop()
if (c0 == "(" and c == "]") or (c0=="[" and c == ")"):
print("Error:")
print(s)
print(" "*i0 + "^ has mismatched delimiter types")
print("First delimiter is " + c0)
print("Second delimiter is " + c)
exit()
else:
print("Matching delimiters found: " + s[i0:i+1])
except IndexError:
except IndexError:
# Error because there was no "(" on the
# Error because there was no opening delim on the
# stack to match this ")"
# stack to match the closing delimiter
print("Error:")
print("Error:")
print(s)
print(s)
print(" "*i + "^ does not match any preceding (")
print(" "*i + "^ does not match any preceding (")
exit()
exit()
# are there any parentheses open?
# are there any delimiters open?
# If so, it means that there is a ( with no match
# If so, it means that there is a ( or [ with no match
if len(currently_open) > 0:
if len(currently_open) > 0:
print("Error:")
print("Error:")
print(s)
print(s)
print(" "*currently_open.pop() + "^ is not matched by any following )")
print(" "*currently_open.pop() + "^ is not matched by any following )")
else:
else:
print("Parentheses matched successfully.")
print("Delimiters matched successfully.")
# Examples of what we expect the error messages to look like:
# Examples of what we expect the error messages to look like:
# (1 + ((2+3) - 5
# (1 + ((2+3) - 5
# ^ is not matched by any following )
# ^ is not matched by any following )
# ( 1 + (3-4))) + 5
# ( 1 + (3-4))) + 5
# ^ does not match any preceding (
# ^ does not match any preceding (