Esempio n. 1
0
 def test_given_last_unprocessed_reference_then_lookaheads_of_parent(
         self) -> None:
     grammar = Grammar(Rule('A', ['x', 'B']), Rule('A', ['B', 'x']),
                       Rule('B', ['x']))
     state = RuleState(0, 1, {'a'})
     self.assertEqual({RuleState(2, 0, {'a'})},
                      state.follow_states(grammar))
Esempio n. 2
0
 def test_given_reference_followed_by_reference_then_lookahead_is_first_set(
         self) -> None:
     grammar = Grammar(Rule('A', ['B', 'X']), Rule('B', ['x']),
                       Rule('X', ['a']), Rule('X', ['b']))
     state = RuleState(0, 0, {'x'})
     self.assertEqual({RuleState(1, 0, {'a', 'b'})},
                      state.follow_states(grammar))
Esempio n. 3
0
 def test_given_states_followed_by_terminals_then_complete_closure(
         self) -> None:
     grammar = Grammar(Rule('A', ['X', 'a']), Rule('A', ['A', 'X']),
                       Rule('X', ['x']))
     result = closure_for(grammar, RuleState(0, 1, {'$'}),
                          RuleState(1, 2, {'$'}))
     self.assertEqual({RuleState(0, 1, {'$'}),
                       RuleState(1, 2, {'$'})}, result)
Esempio n. 4
0
 def test_given_states_followed_by_recursion_then_closure_includes_all_lookaheads(
         self) -> None:
     grammar = Grammar(Rule('A', ['a', 'A']), Rule('A', ['A', 'A']))
     result = closure_for(grammar, RuleState(0, 1, {'$'}))
     expected = {
         RuleState(0, 1, {'$'}),
         RuleState(1, 0, {'$', 'a'}),
         RuleState(0, 0, {'$', 'a'})
     }
     self.assertEqual(expected, result)
Esempio n. 5
0
 def test_given_states_followed_by_references_then_closure_includes_references(
         self) -> None:
     grammar = Grammar(Rule('A', ['x', 'B']), Rule('B', ['C']),
                       Rule('C', ['x']))
     result = closure_for(grammar, RuleState(0, 1, {'$'}))
     expected = {
         RuleState(0, 1, {'$'}),
         RuleState(1, 0, {'$'}),
         RuleState(2, 0, {'$'})
     }
     self.assertEqual(expected, result)
Esempio n. 6
0
def closure(*states: Tuple[int, int, str]) -> Closure:
    from typing import FrozenSet
    from cmaj.parser.closure import RuleState
    from cmaj.parser.grammar import Grammar

    def unpack_lookaheads(terminals: str) -> FrozenSet[str]:
        return frozenset(
            {Grammar.AUGMENTED_EOF if ch == '$' else ch
             for ch in terminals})

    return frozenset({
        RuleState(rule_index, num_processed, unpack_lookaheads(lookaheads))
        for rule_index, num_processed, lookaheads in states
    })
Esempio n. 7
0
 def test_given_states_in_cycles_then_closure_includes_all_lookaheads(
         self) -> None:
     grammar = Grammar(Rule('C', ['A']), Rule('A', ['B', 'B']),
                       Rule('B', ['C']), Rule('C', ['c']), Rule('A', ['a']),
                       Rule('B', ['b']))
     result = closure_for(grammar, RuleState(1, 1, {'$'}))
     expected = {
         RuleState(1, 1, {'$'}),
         RuleState(2, 0, {'$', 'c', 'a', 'b'}),
         RuleState(5, 0, {'$', 'c', 'a', 'b'}),
         RuleState(0, 0, {'$', 'c', 'a', 'b'}),
         RuleState(3, 0, {'$', 'c', 'a', 'b'}),
         RuleState(1, 0, {'$', 'c', 'a', 'b'}),
         RuleState(4, 0, {'$', 'c', 'a', 'b'})
     }
     self.assertEqual(expected, result)
Esempio n. 8
0
def graph_for(grammar: Grammar) -> ClosureGraph:
    from cmaj.parser.closure import closure_for, successors_for
    graph = ClosureGraph()
    fringe = {closure_for(grammar, RuleState.start(grammar))}
    while fringe:
        source = fringe.pop()
        graph.add_closure(source)

        successors = successors_for(grammar, source)
        fringe |= {
            target
            for target in successors.values() if target not in graph
        }
        for symbol, target in successors.items():
            graph.add_edge(source, symbol, target)
    return graph
Esempio n. 9
0
 def test_given_lookaheads_then_closure_simplifies_lookaheads(self) -> None:
     grammar = Grammar(Rule('A', ['a']), Rule('A', ['B', 'B']),
                       Rule('B', ['b']), Rule('B', ['A', 'B']))
     result = closure_for(grammar, RuleState(1, 1, {'x', 'y'}))
     expected = {
         RuleState(1, 1, {'x', 'y'}),
         RuleState(2, 0, {'x', 'y', 'b', 'a'}),
         RuleState(3, 0, {'x', 'y', 'b', 'a'}),
         RuleState(0, 0, {'b', 'a'}),
         RuleState(1, 0, {'b', 'a'})
     }
     self.assertEqual(expected, result)
Esempio n. 10
0
 def test_given_reference_followed_by_recursion_then_lookahead_is_first_set(
         self) -> None:
     grammar = Grammar(Rule('X', ['a']), Rule('X', ['b', 'X', 'X']))
     state = RuleState(1, 1, {'x'})
     expected = {RuleState(0, 0, {'a', 'b'}), RuleState(1, 0, {'a', 'b'})}
     self.assertEqual(expected, state.follow_states(grammar))
Esempio n. 11
0
 def test_given_equal_states_then_equal(self) -> None:
     self.assertEqual(RuleState(0, 0, {'x'}), RuleState(0, 0, {'x'}))
     self.assertEqual(RuleState(1, 2, {'3', '4'}),
                      RuleState(1, 2, {'3', '4'}))
Esempio n. 12
0
 def test_given_grammar_with_single_rule_then_complete_closure(
         self) -> None:
     grammar = Grammar(Rule('X', ['x']))
     result = closure_for(grammar, RuleState(0, 0, {'$'}))
     self.assertEqual({RuleState(0, 0, {'$'})}, result)
Esempio n. 13
0
 def test_given_unprocessed_terminal_then_no_follow_states(self) -> None:
     grammar = Grammar(Rule('A', ['a']))
     state = RuleState(0, 0, {'a'})
     self.assertEqual(set(), state.follow_states(grammar))
Esempio n. 14
0
 def test_given_unprocessed_reference_then_initial_reference_states(
         self) -> None:
     grammar = Grammar(Rule('A', ['B']), Rule('B', ['b']))
     state = RuleState(0, 0, {'b'})
     self.assertEqual({RuleState(1, 0, {'b'})},
                      state.follow_states(grammar))
Esempio n. 15
0
 def test_given_equal_states_then_same_hash(self) -> None:
     self.assertEqual(hash(RuleState(1, 2, {'3', '4'})),
                      hash(RuleState(1, 2, {'3', '4'})))
Esempio n. 16
0
 def test_given_different_lookaheads_then_not_equal(self) -> None:
     self.assertNotEqual(RuleState(1, 2, {'3'}),
                         RuleState(1, 2, {'3', '4'}))
     self.assertNotEqual(RuleState(1, 2, {'0', '4'}),
                         RuleState(1, 2, {'3', '4'}))
Esempio n. 17
0
 def test_given_different_num_processed_then_not_equal(self) -> None:
     self.assertNotEqual(RuleState(1, 0, {'3', '4'}),
                         RuleState(1, 2, {'3', '4'}))
Esempio n. 18
0
 def test_given_state_followed_by_two_references_then_lookahead_of_reference(
         self) -> None:
     grammar = Grammar(Rule('A', ['B', 'B']), Rule('B', ['b']))
     result = closure_for(grammar, RuleState(0, 0, {'$'}))
     self.assertEqual({RuleState(0, 0, {'$'}),
                       RuleState(1, 0, {'b'})}, result)
Esempio n. 19
0
 def test_given_unprocessed_reference_then_not_reducible_and_next_symbol_is_reference(
         self) -> None:
     grammar = Grammar(Rule('A', ['a', 'A']))
     state = resolve(RuleState(0, 1, {'$'}), grammar)
     self.assertFalse(state.reducible)
     self.assertEqual('A', state.next_symbol)
Esempio n. 20
0
 def test_given_processed_rule_then_reducible(self) -> None:
     grammar = Grammar(Rule('A', ['a', 'A']))
     state = resolve(RuleState(0, 2, {'$'}), grammar)
     self.assertTrue(state.reducible)
Esempio n. 21
0
 def test_given_different_rule_index_then_not_equal(self) -> None:
     self.assertNotEqual(RuleState(0, 2, {'3', '4'}),
                         RuleState(1, 2, {'3', '4'}))