def closure(self) -> List[ParserItem]: result = [self._item] accumulator = [self._item] while accumulator: for item in accumulator: if item.has_next: for rule in self._grammar.rules_of(item.next): if ParserItem.item_for(rule) not in result: accumulator.append(ParserItem.item_for(rule)) result.append(ParserItem.item_for(rule)) accumulator.remove(item) return result
def __init__(self, grammar: ContextFreeGrammar): self.__grammar = grammar extended = self.__grammar.extend() item = ParserItem.item_for(extended.rules_of(NonTerminal("E"))[0]) items = Closure(item, extended).closure() self.__start = State(items, self.__grammar) self.__transitions = [] self.__states = [self.__start] self.__build(self.__start, self.__transitions, self.__states)
def test_when_generating_closure_expect_valid_items(self): # declarations: extended = self.grammar.extend() item = ParserItem.item_for(extended.rules_of(NonTerminal("E"))[0]) # when: items = Closure(item, extended).closure() # then: self.assertEqual(items, [ ParserItem.from_string('E -> . S'), ParserItem.from_string('S -> . a A') ])
def test_when_is_going_to_next_state_expect_valid_next_state(self): # declarations: extended = self.grammar.extend() item = ParserItem.item_for(extended.rules_of(NonTerminal("E"))[0]) items = Closure(item, extended).closure() state = State(items, self.grammar) # when actual = state.go_to(Symbol("a")) # then: self.assertEqual(actual.items, [ ParserItem.from_string('S -> a . A'), ParserItem.from_string('A -> . b A'), ParserItem.from_string('A -> . c') ])