Skip to content

Commit b4e2f4d

Browse files
committed
unify terminal representations
1 parent de224bc commit b4e2f4d

File tree

15 files changed

+70
-102
lines changed

15 files changed

+70
-102
lines changed

pyformlang/cfg/cfg_variable_converter.py

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,56 @@
22

33
from typing import Dict, List, AbstractSet, Tuple, Optional, Hashable
44

5-
from ..objects.cfg_objects import Variable, CFGObjectConvertible
5+
from ..objects.formal_object import FormalObject
6+
from ..objects.cfg_objects import Variable
67

78

89
class CFGVariableConverter:
910
"""A CFG Variable Converter"""
1011

1112
def __init__(self,
12-
states: AbstractSet[CFGObjectConvertible],
13-
stack_symbols: AbstractSet[CFGObjectConvertible]) -> None:
13+
states: AbstractSet[FormalObject],
14+
stack_symbols: AbstractSet[FormalObject]) -> None:
1415
self._counter = 0
15-
self._inverse_states_d: Dict[CFGObjectConvertible, int] = {}
16+
self._inverse_states_d: Dict[FormalObject, int] = {}
1617
self._counter_state = 0
1718
for self._counter_state, state in enumerate(states):
1819
self._inverse_states_d[state] = self._counter_state
19-
state.index_cfg_converter = self._counter_state
20+
state.index = self._counter_state
2021
self._counter_state += 1
21-
self._inverse_stack_symbol_d: Dict[CFGObjectConvertible, int] = {}
22+
self._inverse_stack_symbol_d: Dict[FormalObject, int] = {}
2223
self._counter_symbol = 0
2324
for self._counter_symbol, symbol in enumerate(stack_symbols):
2425
self._inverse_stack_symbol_d[symbol] = self._counter_symbol
25-
symbol.index_cfg_converter = self._counter_symbol
26+
symbol.index = self._counter_symbol
2627
self._counter_symbol += 1
2728
self._conversions: List[List[List[Tuple[bool, Optional[Variable]]]]] \
2829
= [[[(False, None) for _ in range(len(states))]
2930
for _ in range(len(stack_symbols))] for _ in
3031
range(len(states))]
3132

32-
def _get_state_index(self, state: CFGObjectConvertible) -> int:
33+
def _get_state_index(self, state: FormalObject) -> int:
3334
"""Get the state index"""
34-
if state.index_cfg_converter is None:
35+
if state.index is None:
3536
if state not in self._inverse_states_d:
3637
self._inverse_states_d[state] = self._counter_state
3738
self._counter_state += 1
38-
state.index_cfg_converter = self._inverse_states_d[state]
39-
return state.index_cfg_converter
39+
state.index = self._inverse_states_d[state]
40+
return state.index
4041

41-
def _get_symbol_index(self, symbol: CFGObjectConvertible) -> int:
42+
def _get_symbol_index(self, symbol: FormalObject) -> int:
4243
"""Get the symbol index"""
43-
if symbol.index_cfg_converter is None:
44+
if symbol.index is None:
4445
if symbol not in self._inverse_stack_symbol_d:
4546
self._inverse_stack_symbol_d[symbol] = self._counter_symbol
4647
self._counter_symbol += 1
47-
symbol.index_cfg_converter = self._inverse_stack_symbol_d[symbol]
48-
return symbol.index_cfg_converter
48+
symbol.index = self._inverse_stack_symbol_d[symbol]
49+
return symbol.index
4950

5051
def to_cfg_combined_variable(self,
51-
state0: CFGObjectConvertible,
52-
stack_symbol: CFGObjectConvertible,
53-
state1: CFGObjectConvertible) -> Variable:
52+
state0: FormalObject,
53+
stack_symbol: FormalObject,
54+
state1: FormalObject) -> Variable:
5455
""" Conversion used in the to_pda method """
5556
i_stack_symbol, i_state0, i_state1 = self._get_indexes(
5657
stack_symbol, state0, state1)
@@ -74,19 +75,19 @@ def _create_new_variable(self,
7475
return temp
7576

7677
def set_valid(self,
77-
state0: CFGObjectConvertible,
78-
stack_symbol: CFGObjectConvertible,
79-
state1: CFGObjectConvertible) -> None:
78+
state0: FormalObject,
79+
stack_symbol: FormalObject,
80+
state1: FormalObject) -> None:
8081
"""Set valid"""
8182
i_stack_symbol, i_state0, i_state1 = self._get_indexes(
8283
stack_symbol, state0, state1)
8384
prev = self._conversions[i_state0][i_stack_symbol][i_state1]
8485
self._conversions[i_state0][i_stack_symbol][i_state1] = (True, prev[1])
8586

8687
def is_valid_and_get(self,
87-
state0: CFGObjectConvertible,
88-
stack_symbol: CFGObjectConvertible,
89-
state1: CFGObjectConvertible) -> Optional[Variable]:
88+
state0: FormalObject,
89+
stack_symbol: FormalObject,
90+
state1: FormalObject) -> Optional[Variable]:
9091
"""Check if valid and get"""
9192
i_state0 = self._get_state_index(state0)
9293
i_stack_symbol = self._get_symbol_index(stack_symbol)
@@ -102,9 +103,9 @@ def is_valid_and_get(self,
102103
return current[1]
103104

104105
def _get_indexes(self,
105-
stack_symbol: CFGObjectConvertible,
106-
state0: CFGObjectConvertible,
107-
state1: CFGObjectConvertible) \
106+
stack_symbol: FormalObject,
107+
state0: FormalObject,
108+
state1: FormalObject) \
108109
-> Tuple[int, int, int]:
109110
i_state0 = self._get_state_index(state0)
110111
i_stack_symbol = self._get_symbol_index(stack_symbol)

pyformlang/cfg/tests/test_terminal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ def test_eq(self):
3434
assert "A" == Terminal("A")
3535
assert Variable(1) == 1
3636
assert Epsilon() == FAEpsilon()
37-
assert Terminal("ABC") != Symbol("ABC")
37+
assert Terminal("ABC") == Symbol("ABC")
3838
assert State("S") != Variable("S")

pyformlang/objects/base_epsilon.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
from typing import Any
44

55
from .formal_object import FormalObject
6+
from .base_terminal import BaseTerminal
67

78
EPSILON_SYMBOLS = ["epsilon", "ɛ"]
89

910

10-
class BaseEpsilon(FormalObject):
11+
class BaseEpsilon(BaseTerminal):
1112
""" An epsilon transition
1213
1314
Examples
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
""" General terminal representation """
2+
3+
from typing import Any
4+
from abc import abstractmethod
5+
6+
from .formal_object import FormalObject
7+
8+
9+
class BaseTerminal(FormalObject):
10+
""" General terminal representation """
11+
12+
def __eq__(self, other: Any) -> bool:
13+
if isinstance(other, BaseTerminal):
14+
return self.value == other.value
15+
if isinstance(other, FormalObject):
16+
return False
17+
return self.value == other
18+
19+
def __hash__(self) -> int:
20+
return super().__hash__()
21+
22+
@abstractmethod
23+
def __repr__(self):
24+
raise NotImplementedError

pyformlang/objects/cfg_objects/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@
55
from .terminal import Terminal
66
from .epsilon import Epsilon
77
from .production import Production
8-
from .cfg_object_convertible import CFGObjectConvertible
98

109

1110
__all__ = ["CFGObject",
1211
"Variable",
1312
"Terminal",
1413
"Epsilon",
15-
"Production",
16-
"CFGObjectConvertible"]
14+
"Production"]

pyformlang/objects/cfg_objects/cfg_object.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
from abc import abstractmethod
44

5-
from .cfg_object_convertible import CFGObjectConvertible
5+
from ..formal_object import FormalObject
66

77

8-
class CFGObject(CFGObjectConvertible):
8+
class CFGObject(FormalObject):
99
""" An object in a CFG
1010
1111
Parameters

pyformlang/objects/cfg_objects/cfg_object_convertible.py

Lines changed: 0 additions & 18 deletions
This file was deleted.

pyformlang/objects/cfg_objects/terminal.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,12 @@
11
""" A terminal in a CFG """
22

3-
from typing import Any
4-
53
from .cfg_object import CFGObject
6-
from ..formal_object import FormalObject
4+
from ..base_terminal import BaseTerminal
75

86

9-
class Terminal(CFGObject):
7+
class Terminal(BaseTerminal, CFGObject):
108
""" A terminal in a CFG """
119

12-
def __eq__(self, other: Any) -> bool:
13-
if isinstance(other, Terminal):
14-
return self.value == other.value
15-
if isinstance(other, FormalObject):
16-
return False
17-
return self.value == other
18-
19-
def __hash__(self) -> int:
20-
return super().__hash__()
21-
2210
def __repr__(self) -> str:
2311
return f"Terminal({self})"
2412

pyformlang/objects/finite_automaton_objects/state.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
from typing import Any
66

77
from .finite_automaton_object import FiniteAutomatonObject
8-
from ..cfg_objects import CFGObjectConvertible
98
from ..formal_object import FormalObject
109

1110

12-
class State(CFGObjectConvertible, FiniteAutomatonObject):
11+
class State(FiniteAutomatonObject):
1312
""" A state in a finite automaton
1413
1514
Parameters

pyformlang/objects/finite_automaton_objects/symbol.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@
22
This module describe a symbol in a finite automaton.
33
"""
44

5-
from typing import Any
6-
75
from .finite_automaton_object import FiniteAutomatonObject
8-
from ..formal_object import FormalObject
6+
from ..base_terminal import BaseTerminal
97

108

11-
class Symbol(FiniteAutomatonObject):
9+
class Symbol(BaseTerminal, FiniteAutomatonObject):
1210
""" A symbol in a finite automaton
1311
1412
Parameters
@@ -23,15 +21,5 @@ class Symbol(FiniteAutomatonObject):
2321
A
2422
"""
2523

26-
def __eq__(self, other: Any) -> bool:
27-
if isinstance(other, Symbol):
28-
return self.value == other.value
29-
if isinstance(other, FormalObject):
30-
return False
31-
return self.value == other
32-
33-
def __hash__(self) -> int:
34-
return super().__hash__()
35-
3624
def __repr__(self) -> str:
3725
return f"Symbol({self})"

0 commit comments

Comments
 (0)