192def get_canonical_collection(gr):
193
194
195
196
197 dfa = lr_zero.get_automaton(gr)
198 kstates = [lr_zero.kernels(st) for st in dfa.states]
199 n_states = len(kstates)
200
201
202
203 table = [{item: LrZeroItemTableEntry() for item in kstates[i]} for i in range(n_states)]
204 table[0][(0, 0)].lookaheads.add(grammar.EOF_SYMBOL)
205
206 for i_state_id in range(n_states):
207 state_symbols = [x[1] for x, y in dfa.goto.items() if x[0] == i_state_id]
208
209 for i_item in kstates[i_state_id]:
210 closure_set = closure(gr, [(i_item, grammar.FREE_SYMBOL)])
211
212 for sym in state_symbols:
213 j_state_id = dfa.goto[(i_state_id, sym)]
214
215
216
217 for ((prod_index, dot), next_symbol) in closure_set:
218 pname, pbody = gr.productions[prod_index]
219 if dot == len(pbody) or pbody[dot] != sym:
220 continue
221
222 j_item = (prod_index, dot + 1)
223 if next_symbol == grammar.FREE_SYMBOL:
224 table[i_state_id][i_item].propagates_to.add((j_state_id, j_item))
225 else:
226 table[j_state_id][j_item].lookaheads.add(next_symbol)
227
228
229
230 repeat = True
231 while repeat:
232 repeat = False
233
234 for i_state_id in range(len(table)):
235 for i_item, i_cell in table[i_state_id].items():
236
237 for j_state_id, j_item in i_cell.propagates_to:
238
239 j_cell = table[j_state_id][j_item]
240 j_cell_lookaheads_len = len(j_cell.lookaheads)
241 j_cell.lookaheads.update(i_cell.lookaheads)
242
243 if j_cell_lookaheads_len < len(j_cell.lookaheads):
244 repeat = True
245
246
247
248 result = [
set()
for i
in range(n_states)]
249 for i_state_id in range(n_states):
250
251 for i_item, i_cell in table[i_state_id].items():
252 for sym in i_cell.lookaheads:
253 item_set = (i_item, sym)
254 result[i_state_id].add(item_set)
255
256 result[i_state_id] = closure(gr, result[i_state_id])
257
258 return result
259
260