22Representation of a recursive automaton
33"""
44
5- from typing import AbstractSet , Union
5+ from typing import Dict , Set , AbstractSet , Optional , Any
66
77from pyformlang .finite_automaton .finite_automaton import to_symbol
88from pyformlang .finite_automaton .symbol import Symbol
@@ -28,15 +28,16 @@ class RecursiveAutomaton:
2828
2929 def __init__ (self ,
3030 start_box : Box ,
31- boxes : AbstractSet [Box ]):
32- self ._nonterminal_to_box = {}
31+ boxes : AbstractSet [Box ]) -> None :
32+ self ._nonterminal_to_box : Dict [ Symbol , Box ] = {}
3333 if start_box not in boxes :
34- self ._nonterminal_to_box [to_symbol (start_box .nonterminal )] = start_box
35- self ._start_nonterminal = to_symbol (start_box .nonterminal )
34+ self ._nonterminal_to_box [
35+ to_symbol (start_box .nonterminal )] = start_box
36+ self ._start_nonterminal : Symbol = to_symbol (start_box .nonterminal )
3637 for box in boxes :
3738 self ._nonterminal_to_box [to_symbol (box .nonterminal )] = box
3839
39- def get_box_by_nonterminal (self , nonterminal : Union [ Symbol , str ]) :
40+ def get_box_by_nonterminal (self , nonterminal : Any ) -> Optional [ Box ] :
4041 """
4142 Box by nonterminal
4243
@@ -54,15 +55,13 @@ def get_box_by_nonterminal(self, nonterminal: Union[Symbol, str]):
5455 nonterminal = to_symbol (nonterminal )
5556 if nonterminal in self ._nonterminal_to_box :
5657 return self ._nonterminal_to_box [nonterminal ]
57-
5858 return None
5959
60- def get_number_boxes (self ):
60+ def get_number_boxes (self ) -> int :
6161 """ Size of set of boxes """
62-
6362 return len (self ._nonterminal_to_box )
6463
65- def to_dot (self ):
64+ def to_dot (self ) -> str :
6665 """ Create dot representation of recursive automaton """
6766 dot_string = 'digraph "" {'
6867 for box in self ._nonterminal_to_box .values ():
@@ -71,31 +70,28 @@ def to_dot(self):
7170 return dot_string
7271
7372 @property
74- def nonterminals (self ) -> set :
73+ def nonterminals (self ) -> Set [ Symbol ] :
7574 """ The set of nonterminals """
76-
7775 return set (self ._nonterminal_to_box .keys ())
7876
7977 @property
80- def boxes (self ) -> dict :
78+ def boxes (self ) -> Dict [ Symbol , Box ] :
8179 """ The set of boxes """
82-
8380 return self ._nonterminal_to_box
8481
8582 @property
8683 def start_nonterminal (self ) -> Symbol :
8784 """ The start nonterminal """
88-
8985 return self ._start_nonterminal
9086
9187 @property
92- def start_box (self ):
88+ def start_box (self ) -> Box :
9389 """ The start box """
94-
9590 return self .boxes [self .start_nonterminal ]
9691
9792 @classmethod
98- def from_regex (cls , regex : Regex , start_nonterminal : Union [Symbol , str ]):
93+ def from_regex (cls , regex : Regex , start_nonterminal : Any ) \
94+ -> "RecursiveAutomaton" :
9995 """ Create a recursive automaton from regular expression
10096
10197 Parameters
@@ -115,14 +111,17 @@ def from_regex(cls, regex: Regex, start_nonterminal: Union[Symbol, str]):
115111 return RecursiveAutomaton (box , {box })
116112
117113 @classmethod
118- def from_ebnf (cls , text , start_nonterminal : Union [Symbol , str ] = Symbol ("S" )):
119- """ Create a recursive automaton from ebnf (ebnf = Extended Backus-Naur Form)
114+ def from_ebnf (cls , text : str , start_nonterminal : Any = Symbol ("S" )) \
115+ -> "RecursiveAutomaton" :
116+ """ Create a recursive automaton from ebnf \
117+ (ebnf = Extended Backus-Naur Form)
120118
121119 Parameters
122120 -----------
123121 text : str
124122 The text of transform
125- start_nonterminal : :class:`~pyformlang.finite_automaton.Symbol` | str, optional
123+ start_nonterminal : \
124+ :class:`~pyformlang.finite_automaton.Symbol` | str, optional
126125 The start nonterminal, S by default
127126
128127 Returns
@@ -155,10 +154,11 @@ def from_ebnf(cls, text, start_nonterminal: Union[Symbol, str] = Symbol("S")):
155154 for head , body in productions .items ():
156155 boxes .add (Box (Regex (body ).to_epsilon_nfa ().minimize (),
157156 to_symbol (head )))
158- start_box = Box (Regex (productions [start_nonterminal .value ]).to_epsilon_nfa ().minimize (), start_nonterminal )
157+ start_box = Box (Regex (productions [start_nonterminal .value ]) \
158+ .to_epsilon_nfa ().minimize (), start_nonterminal )
159159 return RecursiveAutomaton (start_box , boxes )
160160
161- def is_equals_to (self , other ) :
161+ def is_equal_to (self , other : "RecursiveAutomaton" ) -> bool :
162162 """
163163 Check whether two recursive automata are equals by boxes.
164164 Not equivalency in terms of formal languages theory, just mapping boxes
@@ -173,9 +173,9 @@ def is_equals_to(self, other):
173173 are_equivalent : bool
174174 Whether the two recursive automata are equals or not
175175 """
176- if not isinstance (other , RecursiveAutomaton ):
177- return False
178176 return self .boxes == other .boxes
179177
180- def __eq__ (self , other ):
181- return self .is_equals_to (other )
178+ def __eq__ (self , other : Any ) -> bool :
179+ if not isinstance (other , RecursiveAutomaton ):
180+ return False
181+ return self .is_equal_to (other )
0 commit comments