我正在尝试创建一个布尔逻辑解析器 - 例如 A & B | !C。 我为此制作了一个解析器,最终以 pygame 显示的维恩图结束。 (代码如下)。 但是,这不支持括号。
我想要做的是按照需要评估的顺序记录每个括号术语的开始和结束,如下所示: ((a & b) | c) | (c 和!b) = [[1, 7], [0, 12], [16, 23]]
我该如何做到这一点(没有模块)? 我有信心一旦获得这些信息我就可以评估方程。
代码:
def parse(expression, sets, total, classifications):
# First split the expression down into the terms
terms = expression.split(" ")
operators = []
arrays = []
# Replace A, B, C with their corresponding arrays, inverse if necessary.
for index, term in enumerate(terms):
# Do not change operators but record indices.
if term == "&" or term == "|":
arrays.append(term)
operators.append(index)
is_not = "!" in term
term = term.strip("!")
# If the term contains a '!' character, instead append the complement of that set.
if term in sets.keys():
if is_not:
arrays.append(complement(sets[term], total))
else:
arrays.append(sets[term])
# [[1, 2, 3], "&", [3, 4, 5]] for example.
for operator in operators:
# We know that for each operator, there is a set on either side.
set_1 = arrays[operator - 1]
logic = arrays[operator]
set_2 = arrays[operator + 1]
# Combine the sets in either way.
if logic == "&":
result = intersection(set_1, set_2)
elif logic == "|":
result = union(set_1, set_2)
# Remove the old sets & operator, add the combined set.
for i in range(3): arrays.pop(operator - 1)
arrays.insert(operator - 1, result)
# Account for the size of the array shrinking.
for index in range(len(operators)):
operators[index] -= 2
# Parsing done, clean up array.
sections = []
arrays = arrays[0]
# Figure out which sections must be rendered.
for number in arrays:
sections.append(classifications[number])
return sections
地点:
total = [1, 2, 3, 4, 5, 6, 7, 8]
sets = {
"a":[1, 2, 3, 5],
"b":[2, 3, 4, 8],
"c":[3, 4, 5, 6]
}
# The sets were carefully chosen to ensure each set has 2 numbers corresponding toeach of the
other sets, 1 number corresponding
# to all three sets, and 1 number that is unique to that set. There is also 1 number (8)
that is not in any sets.
# This way, sections can be shader based on whether or not that number is present.
classifications = {
1:"a",
2:"ab",
3:"abc",
4:"bc",
5:"ac",
6:"c",
7:"none",
8:"b"
}
您可以实现一个跟踪左括号和右括号位置的函数:
def find_parentheses_spans(expression):
stack = []
spans = []
for index, char in enumerate(expression):
if char == '(':
stack.append(index)
elif char == ')':
start = stack.pop() # Get the position of the matching '('
spans.append([start, index])
# Optional: sort spans if needed, based on the starting index
spans.sort(key=lambda x: x[0])
return spans
expression = "((a & b) | c) | (c & !b)"
spans = find_parentheses_spans(expression)
print(spans)