Михаил Бурлуцкий
Ученик
(106)
4 месяца назад
Чтобы построить дерево разбора регулярного выражения на Python, нам нужно реализовать алгоритм, который будет учитывать приоритеты операций, правильно обрабатывать ассоциативность, и строить дерево, представляющее структуру выражения.
### Шаги решения:
1. **Рассахаривание опции (`?`)**: Опцию `?` нужно преобразовать в альтернативу с пустым аргументом. Например, `a?` -> `(a|)`.
2. **Парсинг выражения с учетом приоритетов**: Необходимо разбить выражение на компоненты, учитывая приоритеты операций: итерация (`*`), конкатенация (которая неявная), и альтернатива (`|`).
3. **Построение дерева**: Для каждого оператора создается соответствующий узел дерева, где операторы (`*`, `|`, конкатенация) будут внутренними узлами, а символы — листами.
### Попробуй это:
```python
class Node:
def __init__(self, value, left=None, right=None):
self.value = value # Значение узла (оператор или символ)
self.left = left # Левый потомок
self.right = right # Правый потомок
def __repr__(self):
return f"Node({self.value}, {self.left}, {self.right})"
def parse_expression(expression):
def parse_alternative(expr):
# Разбираем альтернативу
parts = []
current = []
depth = 0
for char in expr:
if char == '(':
depth += 1
elif char == ')':
depth -= 1
elif char == '|' and depth == 0:
parts.append(''.join(current))
current = []
continue
current.append(char)
parts.append(''.join(current))
if len(parts) > 1:
node = Node('|', parse_concatenation(parts[0]), parse_concatenation(parts[1]))
for part in parts[2:]:
node = Node('|', node, parse_concatenation(part))
return node
else:
return parse_concatenation(parts[0])
def parse_concatenation(expr):
# Разбираем конкатенацию
nodes = []
i = 0
while i < len(expr):
if expr[i] == '(':
depth = 1
j = i + 1
while j < len(expr) and depth > 0:
if expr[j] == '(':
depth += 1
elif expr[j] == ')':
depth -= 1
j += 1
nodes.append(parse_alternative(expr[i + 1:j - 1]))
i = j
elif expr[i].isalpha():
nodes.append(Node(expr[i]))
i += 1
elif expr[i] == '*':
last_node = nodes.pop()
nodes.append(Node('*', last_node))
i += 1
else:
i += 1
node = nodes[0]
for next_node in nodes[1:]:
node = Node('.', node, next_node)
return node
return parse_alternative(expression)
def print_tree(node, depth=0):
if node is not None:
print_tree(node.right, depth + 1)
print(' ' * 4 * depth + f'-> {node.value}')
print_tree(node.left, depth + 1)
# Пример использования
regex = "a|ba|bc*a"
tree = parse_expression(regex)
print_tree(tree)
```
###