@@ -27,7 +27,7 @@ def __repr__(self):
2727 f"{ self .num_latches } { self .num_outputs } { self .num_ands } "
2828
2929
30- NOT_DONE_PARSING_ERROR = "Lines exhausted before parsing ended !\n {}"
30+ NOT_DONE_PARSING_ERROR = "Parsing rules exhausted at line {} !\n {}"
3131DONE_PARSING_ERROR = "Lines exhausted before parsing ended!\n {}"
3232
3333
@@ -59,9 +59,9 @@ class SymbolTable:
5959@attr .s (auto_attribs = True )
6060class State :
6161 header : Optional [Header ] = None
62- inputs : SortedSet = attr .ib (factory = SortedSet )
63- outputs : list = attr .ib (factory = list )
64- latches : SortedSet = attr .ib (factory = SortedSet )
62+ inputs : List [ str ] = attr .ib (factory = list )
63+ outputs : List [ str ] = attr .ib (factory = list )
64+ latches : List [ str ] = attr .ib (factory = list )
6565 symbols : SymbolTable = attr .ib (factory = SymbolTable )
6666 comments : Optional [List [str ]] = None
6767 nodes : SortedDict = attr .ib (factory = SortedDict )
@@ -113,15 +113,16 @@ def parse_header(state, line) -> bool:
113113 return True
114114
115115
116- IO_PATTERN = re .compile (r"(\d+)\n" )
116+ IO_PATTERN = re .compile (r"(\d+)\s*\ n" )
117117
118118
119119def parse_input (state , line ) -> bool :
120120 match = IO_PATTERN .match (line )
121+
121122 if match is None or state .remaining_inputs <= 0 :
122123 return False
123124 lit = int (line )
124- state .inputs .add (lit )
125+ state .inputs .append (lit )
125126 state .nodes [lit ] = set ()
126127 return True
127128
@@ -153,15 +154,15 @@ def parse_latch(state, line) -> bool:
153154 elems = elems [:2 ] + (0 ,)
154155 elems = fn .lmap (int , elems )
155156
156- state .latches .add (Latch (* elems ))
157+ state .latches .append (Latch (* elems ))
157158 state .nodes [elems [0 ]] = set () # Add latch in as source.
158159 lit = elems [1 ] # Add latchout to dependency graph.
159160 if lit & 1 :
160161 state .nodes [lit ] = {lit ^ 1 }
161162 return True
162163
163164
164- AND_PATTERN = re .compile (r"(\d+) (\d+) (\d+)\n" )
165+ AND_PATTERN = re .compile (r"(\d+) (\d+) (\d+)\s*\ n" )
165166
166167
167168def parse_and (state , line ) -> bool :
@@ -182,7 +183,7 @@ def parse_and(state, line) -> bool:
182183 return True
183184
184185
185- SYM_PATTERN = re .compile (r"([ilo])(\d+) (.*)\n" )
186+ SYM_PATTERN = re .compile (r"([ilo])(\d+) (.*)\s*\ n" )
186187
187188
188189def parse_symbol (state , line ) -> bool :
@@ -234,12 +235,12 @@ def parse(lines, to_aig: bool = True):
234235 parsers = parse_seq ()
235236 parser = next (parsers )
236237
237- for line in lines :
238+ for i , line in enumerate ( lines ) :
238239 while not parser (state , line ):
239240 parser = next (parsers , None )
240241
241242 if parser is None :
242- raise ValueError (NOT_DONE_PARSING_ERROR .format (state ))
243+ raise ValueError (NOT_DONE_PARSING_ERROR .format (i + 1 , state ))
243244
244245 if parser not in (parse_header , parse_output , parse_comment , parse_symbol ):
245246 raise ValueError (DONE_PARSING_ERROR .format (state ))
@@ -249,6 +250,9 @@ def parse(lines, to_aig: bool = True):
249250 assert state .remaining_outputs == 0
250251 assert state .remaining_latches == 0
251252
253+ if len (state .inputs ) != len (set (state .inputs )):
254+ raise ValueError ("Duplicated inputs detected." )
255+
252256 # Complete Symbol Table.
253257 inputs = bidict (finish_table (state .symbols .inputs , state .inputs ))
254258 outputs = finish_table (state .symbols .outputs , state .outputs )
0 commit comments