def test_kernel_collection_lalr(self): collection = kernel_collection(self.lrvalue, LALR(self.StartExtendedSymbol, 0, 0)) self.assertTrue(len(collection) == 7) states = frozenset([ frozenset([ LALR(self.StartExtendedSymbol, 0, 0), ]), frozenset([ LALR(self.StartExtendedSymbol, 0, 1), ]), frozenset([ LALR('S', 0, 1), ]), frozenset([ LALR('C', 0, 1), ]), frozenset([ LALR('C', 1, 1), ]), frozenset([ LALR('S', 0, 2), ]), frozenset([ LALR('C', 0, 2), ]), ]) self.assertTrue(states == collection)
def generate_spontaneously_lookaheads(grammar, start_item, to_id): '''Builds a LR0 table using as a seed the start_item and then tries to determinate what terminals are lookahead of each item (in which case, these lookaheads are spontaneously generated), building initially the LALR items (they are very similar to the LR0 item but can be modified adding to him lookaheads, see the documentation of LALR class in the item module). ''' goto_table = collections.defaultdict(dict) lalr_start_item = LALR( start_item.sym_production, start_item.alternative, start_item.position) lalr_start_item.add_new(grammar.EOF) kernels_lalr = kernel_collection(grammar, lalr_start_item) ids_kernes_lalr = dict() for kernels in kernels_lalr: closure_lalr = closure(kernels, grammar) ids_kernes_lalr[to_id[closure_lalr]] = kernels populate_goto_table_from_state(grammar, closure_lalr, goto_table, to_id) for id_, kernels in ids_kernes_lalr.iteritems(): for item_lalr in kernels: closure_lr1 = closure(set([LR1( item_lalr.sym_production, item_lalr.alternative, item_lalr.position, grammar.PROBE)]), grammar) for item_lr1 in closure_lr1: next_symbol = item_lr1.next_symbol(grammar) if not next_symbol: continue item_lr1_shifted = item_lr1.item_shifted(grammar) assert id_ in goto_table goto_set_id = goto_table[id_][next_symbol] goto_set = ids_kernes_lalr[goto_set_id] item_lalr_from_shifted = LALR( item_lr1_shifted.sym_production, item_lr1_shifted.alternative, item_lr1_shifted.position) assert item_lalr_from_shifted in goto_set singleton = (goto_set - (goto_set - {item_lalr_from_shifted})) assert len(singleton) == 1 item_lalr_hidden = set(singleton).pop() if item_lr1.lookahead != grammar.PROBE: item_lalr_hidden.add_new(item_lr1.lookahead) else: item_lalr.subscribe(item_lalr_hidden) return kernels_lalr, goto_table
def generate_spontaneously_lookaheads(grammar, start_item, to_id): '''Builds a LR0 table using as a seed the start_item and then tries to determinate what terminals are lookahead of each item (in which case, these lookaheads are spontaneously generated), building initially the LALR items (they are very similar to the LR0 item but can be modified adding to him lookaheads, see the documentation of LALR class in the item module). ''' goto_table = collections.defaultdict(dict) lalr_start_item = LALR(start_item.sym_production, start_item.alternative, start_item.position) lalr_start_item.add_new(grammar.EOF) kernels_lalr = kernel_collection(grammar, lalr_start_item) ids_kernes_lalr = dict() for kernels in kernels_lalr: closure_lalr = closure(kernels, grammar) ids_kernes_lalr[to_id[closure_lalr]] = kernels populate_goto_table_from_state(grammar, closure_lalr, goto_table, to_id) for id_, kernels in ids_kernes_lalr.iteritems(): for item_lalr in kernels: closure_lr1 = closure( set([ LR1(item_lalr.sym_production, item_lalr.alternative, item_lalr.position, grammar.PROBE) ]), grammar) for item_lr1 in closure_lr1: next_symbol = item_lr1.next_symbol(grammar) if not next_symbol: continue item_lr1_shifted = item_lr1.item_shifted(grammar) assert id_ in goto_table goto_set_id = goto_table[id_][next_symbol] goto_set = ids_kernes_lalr[goto_set_id] item_lalr_from_shifted = LALR(item_lr1_shifted.sym_production, item_lr1_shifted.alternative, item_lr1_shifted.position) assert item_lalr_from_shifted in goto_set singleton = (goto_set - (goto_set - {item_lalr_from_shifted})) assert len(singleton) == 1 item_lalr_hidden = set(singleton).pop() if item_lr1.lookahead != grammar.PROBE: item_lalr_hidden.add_new(item_lr1.lookahead) else: item_lalr.subscribe(item_lalr_hidden) return kernels_lalr, goto_table
def test_kernel_collection_arith(self): collection = kernel_collection(self.arith, LR0(self.StartExtendedSymbol, 0, 0)) self.assertTrue(len(collection) == 12) states = frozenset([ frozenset([ LR0(self.StartExtendedSymbol, 0, 0), ]), frozenset([ LR0(self.StartExtendedSymbol, 0, 1), LR0('E', 0, 1), ]), frozenset([ LR0('E', 1, 1), LR0('T', 0, 1), ]), frozenset([ LR0('F', 1, 1), ]), frozenset([ LR0('F', 0, 1), ]), frozenset([ LR0('T', 1, 1), ]), frozenset([ LR0('E', 0, 2), ]), frozenset([ LR0('T', 0, 2), ]), frozenset([ LR0('E', 0, 1), LR0('F', 0, 2), ]), frozenset([ LR0('E', 0, 3), LR0('T', 0, 1), ]), frozenset([ LR0('T', 0, 3), ]), frozenset([ LR0('F', 0, 3), ]), ]) self.assertTrue(states == collection)
def build_parsing_table(grammar, start_item, handle_shift_reduce = True, disable_mapping = False): '''Builds the Action and Goto tables for be used by a driver returning these tables and the id of the start state, where the driver will use as a point of start to parse. See the documentation of handler_conflict function for more info with respect the handle_shift_reduce parameter. The start_item can be an instance of Item (see the module item). This works well with LR0 and LR1 items, but with LALR items, the algorithm used is the build_parsing_table_lalr (see that function, in this module) If 'disable_mapping' is True, the internal states are identified by its hash. This is only useful for testing and should not be modified in the normal case. Preconditions: the grammar must be already processed.''' if isinstance(start_item, LALR): return build_parsing_table_lalr(grammar, start_item, handle_shift_reduce) action_table = collections.defaultdict(dict) goto_table = collections.defaultdict(dict) kernels = kernel_collection(grammar, start_item) start_set_hash = None to_id = UserFriendlyMapping(disable_mapping) for kernel in kernels: state_set = closure(kernel, grammar) populate_goto_table_from_state(grammar, state_set, goto_table, to_id) populate_action_table_from_state( grammar, state_set, action_table, handle_shift_reduce, to_id) if not start_set_hash: for item in state_set: if item == start_item: start_set_hash = to_id[state_set] return dict(action_table), dict(goto_table), start_set_hash
def build_parsing_table(grammar, start_item, handle_shift_reduce=True, disable_mapping=False): '''Builds the Action and Goto tables for be used by a driver returning these tables and the id of the start state, where the driver will use as a point of start to parse. See the documentation of handler_conflict function for more info with respect the handle_shift_reduce parameter. The start_item can be an instance of Item (see the module item). This works well with LR0 and LR1 items, but with LALR items, the algorithm used is the build_parsing_table_lalr (see that function, in this module) If 'disable_mapping' is True, the internal states are identified by its hash. This is only useful for testing and should not be modified in the normal case. Preconditions: the grammar must be already processed.''' if isinstance(start_item, LALR): return build_parsing_table_lalr(grammar, start_item, handle_shift_reduce) action_table = collections.defaultdict(dict) goto_table = collections.defaultdict(dict) kernels = kernel_collection(grammar, start_item) start_set_hash = None to_id = UserFriendlyMapping(disable_mapping) for kernel in kernels: state_set = closure(kernel, grammar) populate_goto_table_from_state(grammar, state_set, goto_table, to_id) populate_action_table_from_state(grammar, state_set, action_table, handle_shift_reduce, to_id) if not start_set_hash: for item in state_set: if item == start_item: start_set_hash = to_id[state_set] return dict(action_table), dict(goto_table), start_set_hash
def test_kernel_collection_lr_value(self): collection = kernel_collection(self.lrvalue, LR0(self.StartExtendedSymbol, 0, 0)) self.assertTrue(len(collection) == 10) states = frozenset([ frozenset([ LR0(self.StartExtendedSymbol, 0, 0), ]), frozenset([ LR0(self.StartExtendedSymbol, 0, 1), ]), frozenset([ LR0('S', 0, 1), LR0('R', 0, 1), ]), frozenset([ LR0('S', 1, 1), ]), frozenset([ LR0('L', 0, 1), ]), frozenset([ LR0('L', 1, 1), ]), frozenset([ LR0('S', 0, 2), ]), frozenset([ LR0('L', 0, 2), ]), frozenset([ LR0('R', 0, 1), ]), frozenset([ LR0('S', 0, 3), ]), ]) self.assertTrue(states == collection)
def test_canonical(self): collection = kernel_collection(self.grammar, self.start_item) self.assertTrue(len(collection) == 11) self.assertTrue(frozenset(self.kernel_states) == collection)