Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Решите пж задачу на языке питон

Маша Б Ученик (118), закрыт 4 месяца назад
Задание: на вход программе подаётся регулярное выражение, содержащее буквы латинского алфавита, круглые скобки, альтернативу, итерацию и опцию (вопросительный знак). Ассоциативность учитывается, т.е. выражения вида abc(a|b|) корректны. Тут же демонстрируется, что у альтернативы могут быть и пустые аргументы. Приоритеты тоже учитываются: итерация имеет максимальный приоритет, на втором месте конкатенация, слабее всех - альтернатива. Т.е. a|ba|bc*a читаем как (a)|(ba)|(b(c*)a). Необходимо построить (бинарное) дерево разбора регулярного выражения, сохраняющее его семантику. Метки узлов - конкатенация, альтернатива (опцию рассахариваем до альтернативы), итерация (у итерации только один потомок), пустая метка или буква (листовые метки).
Лучший ответ
λ Искусственный Интеллект (254575) 5 месяцев назад
синтаксический разбор. это сложно.
спросите к киберфорум ру в ветке Питон.
Остальные ответы
Михаил Бурлуцкий Ученик (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)
```

###
Похожие вопросы