Семантические действия
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import random
|
||||
import re
|
||||
from collections import OrderedDict
|
||||
from typing import Callable
|
||||
|
||||
from prettytable import PrettyTable
|
||||
|
||||
@@ -8,7 +9,11 @@ from prettytable import PrettyTable
|
||||
class Grammar:
|
||||
EPSILON: str = "epsilon"
|
||||
|
||||
def __init__(self, text: str):
|
||||
def __init__(
|
||||
self,
|
||||
text: str,
|
||||
semantic_action: Callable[[int, tuple[str, list[str]]], None] | None = None,
|
||||
):
|
||||
self.productions: OrderedDict[str, list[list[str]]] = OrderedDict()
|
||||
self.start_symbol: str = ""
|
||||
self._parse_productions(text)
|
||||
@@ -33,6 +38,9 @@ class Grammar:
|
||||
self.rule_numbers[(nt, tuple(rule))] = rule_idx
|
||||
rule_idx += 1
|
||||
|
||||
# Semantic action callback
|
||||
self.semantic_action = semantic_action
|
||||
|
||||
def _parse_productions(self, text: str):
|
||||
for line in text.splitlines():
|
||||
line = line.strip()
|
||||
@@ -309,6 +317,10 @@ class Grammar:
|
||||
rule_number = self.rule_numbers[(top, tuple(production))]
|
||||
rules_applied.append(rule_number)
|
||||
|
||||
# Execute semantic action if provided
|
||||
if self.semantic_action:
|
||||
self.semantic_action(rule_number, (top, production))
|
||||
|
||||
# Добавляем правило в стек в обратном порядке
|
||||
for symbol in reversed(production):
|
||||
stack.append(symbol)
|
||||
@@ -399,3 +411,25 @@ class Grammar:
|
||||
steps.append(current)
|
||||
|
||||
return steps
|
||||
|
||||
|
||||
class ActionsList:
|
||||
def __init__(self, actions: list[Callable[[int, tuple[str, list[str]]], None]]):
|
||||
self.actions = actions
|
||||
|
||||
def __call__(self, rule_number: int, rule_tuple: tuple[str, list[str]]) -> None:
|
||||
self.actions[rule_number - 1](rule_number, rule_tuple)
|
||||
|
||||
|
||||
class ActionsListWithAppliedCount:
|
||||
def __init__(
|
||||
self, actions: list[Callable[[int, int, tuple[str, list[str]]], None]]
|
||||
):
|
||||
self.actions = actions
|
||||
self.applied_counters = [0] * len(actions)
|
||||
|
||||
def __call__(self, rule_number: int, rule_tuple: tuple[str, list[str]]) -> None:
|
||||
self.applied_counters[rule_number - 1] += 1
|
||||
self.actions[rule_number - 1](
|
||||
rule_number, self.applied_counters[rule_number - 1], rule_tuple
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user