Esempio n. 1
0
    def test_item_partition_goto(self):
        rule_set = LALRRuleSet()  # example grammar on EC pp.120
        goal, list_, pair = rule_set.new_nt(3)
        rule_set.add_rule(goal, d(nt(list_)))
        rule_set.add_rule(list_, d(nt(list_), nt(pair)))
        rule_set.add_rule(list_, d(nt(pair)))
        rule_set.add_rule(pair, d(t('('), nt(pair), t(')')))
        rule_set.add_rule(pair, d(t('('), t(')')))
        rule_set.mark_goal(goal)

        cc3 = {
            (pair, 0, 1): {eof, '('},
            (pair, 1, 1): {eof, '('},
            (pair, 0, 0): {')'},
            (pair, 1, 0): {')'}
        }

        partitions = rule_set.item_partition_goto(cc3)
        self.assertEqual(
            partitions, {
                ('nt', pair): {
                    (pair, 0, 1): {eof, '('}
                },
                ('t', '('): {
                    (pair, 0, 0): {')'},
                    (pair, 1, 0): {')'}
                },
                ('t', ')'): {
                    (pair, 1, 1): {eof, '('}
                }
            })
Esempio n. 2
0
 def test_item_closure_with_eps(self):
     rule_set = LALRRuleSet()
     S, M = rule_set.new_nt(2)
     rule_set.add_rule(S, d(t('if'), t('B'), nt(M), nt(S)))
     rule_set.add_rule(S, d(t('A')))
     rule_set.add_rule(M, d(t(epsilon)))
     item_set = {(S, 0, 2): {eof}}
     result = rule_set.item_closure(item_set)
     self.assertEqual(result, {(S, 0, 2): {eof}, (M, 0, 1): {'if', 'A'}})
Esempio n. 3
0
def build_test_rule():
    rule_set = LALRRuleSet()  # example grammar on EC pp.120
    goal, list_, pair = rule_set.new_nt(3)
    rule_set.add_rule(goal, d(nt(list_)))
    rule_set.add_rule(list_, d(nt(list_), nt(pair)))
    rule_set.add_rule(list_, d(nt(pair)))
    rule_set.add_rule(pair, d(t('('), nt(pair), t(')')))
    rule_set.add_rule(pair, d(t('('), t(')')))
    rule_set.mark_goal(goal)
    return rule_set
Esempio n. 4
0
    def test_calc_ambiguous_table_2(self):
        rule_set = LALRRuleSet()  # example grammar on EC pp.136
        stmt = rule_set.new_nt(1)[0]
        rule_set.add_rule(stmt, d(t('if'), nt(stmt)))
        rule_set.add_rule(stmt, d(t('if'), nt(stmt), t('else'), nt(stmt)))
        rule_set.add_rule(stmt, d(t('assign')))
        rule_set.mark_goal(stmt)

        with self.assertRaises(LALRTableBuildError):
            action, goto = rule_set.calc_parse_table()
Esempio n. 5
0
    def test_calc_parse_table(self):
        rule_set = LALRRuleSet()  # example grammar on EC pp.120
        goal, list_, pair = rule_set.new_nt(3)
        rule_set.add_rule(goal, d(nt(list_)))
        rule_set.add_rule(list_, d(nt(list_), nt(pair)))
        rule_set.add_rule(list_, d(nt(pair)))
        rule_set.add_rule(pair, d(t('('), nt(pair), t(')')))
        rule_set.add_rule(pair, d(t('('), t(')')))
        rule_set.mark_goal(goal)

        cc, action, goto = rule_set.calc_parse_table()
        correct_action = [{
            '(': (Action.shift, )
        }, {
            '(': (Action.shift, ),
            eof: (Action.accept, 0, 0)
        }, {
            '(': (Action.reduce, 1, 1),
            eof: (Action.reduce, 1, 1)
        }, {
            '(': (Action.shift, ),
            ')': (Action.shift, )
        }, {
            '(': (Action.reduce, 1, 0),
            eof: (Action.reduce, 1, 0)
        }, {
            ')': (Action.shift, )
        }, {
            '(': (Action.reduce, 2, 1),
            eof: (Action.reduce, 2, 1),
            ')': (Action.reduce, 2, 1)
        }, {
            '(': (Action.reduce, 2, 0),
            eof: (Action.reduce, 2, 0),
            ')': (Action.reduce, 2, 0)
        }]

        correct_goto = [{
            ('nt', 1): 1,
            ('nt', 2): 2,
            ('t', '('): 3
        }, {
            ('nt', 2): 4,
            ('t', '('): 3
        }, {}, {
            ('nt', 2): 5,
            ('t', '('): 3,
            ('t', ')'): 6
        }, {}, {
            ('t', ')'): 7
        }, {}, {}]

        self.assertIsomorphic(action, goto, correct_action, correct_goto)
Esempio n. 6
0
    def test_item_advance(self):
        rule_set = LALRRuleSet()  # example grammar on EC pp.120
        goal, list_, pair = rule_set.new_nt(3)
        rule_set.add_rule(goal, d(nt(list_)))
        rule_set.add_rule(list_, d(nt(list_), nt(pair)))
        rule_set.add_rule(list_, d(nt(pair)))
        rule_set.add_rule(pair, d(t('('), nt(pair), t(')')))
        rule_set.add_rule(pair, d(t('('), t(')')))
        rule_set.mark_goal(goal)

        item_set = {(pair, 0, 0): {')'}, (pair, 1, 0): {')'}}
        result = rule_set.item_advance(item_set)
        self.assertEqual(result, {(pair, 0, 1): {')'}, (pair, 1, 1): {')'}})
Esempio n. 7
0
    def test_calc_LALR_conflict_table(self):
        rule_set = LALRRuleSet()  # example grammar on stanford handout pp.3
        S, B, C = rule_set.new_nt(3)
        rule_set.add_rule(S, d(t('a'), nt(B), t('c')))
        rule_set.add_rule(S, d(t('b'), nt(C), t('c')))
        rule_set.add_rule(S, d(t('a'), nt(C), t('d')))
        rule_set.add_rule(S, d(t('b'), nt(B), t('d')))
        rule_set.add_rule(B, d(t('e')))
        rule_set.add_rule(C, d(t('e')))
        rule_set.mark_goal(S)

        with self.assertRaises(LALRTableBuildError):
            action, goto = rule_set.calc_parse_table()
Esempio n. 8
0
 def test_calc_initial(self):
     rule_set = LALRRuleSet()  # example grammar on stanford handout pp.1
     S, X = rule_set.new_nt(2)
     rule_set.add_rule(S, d(nt(X), nt(X)))
     rule_set.add_rule(X, d(t('a'), nt(X)))
     rule_set.add_rule(X, d(t('b')))
     rule_set.mark_goal(S)
     initial = rule_set.calc_initial()
     self.assertEqual(initial, {
         (S, 0, 0): {eof},
         (X, 0, 0): {'a', 'b'},
         (X, 1, 0): {'a', 'b'}
     })
Esempio n. 9
0
    def test_calc_parse_table_2(self):
        rule_set = LALRRuleSet()  # example grammar on stanford handout pp.1
        S, X = rule_set.new_nt(2)
        rule_set.add_rule(S, d(nt(X), nt(X)))
        rule_set.add_rule(X, d(t('a'), nt(X)))
        rule_set.add_rule(X, d(t('b')))
        rule_set.mark_goal(S)

        cc, action, goto = rule_set.calc_parse_table()
        correct_action = [{
            'a': (Action.shift, ),
            'b': (Action.shift, )
        }, {
            'a': (Action.shift, ),
            'b': (Action.shift, )
        }, {
            'a': (Action.shift, ),
            'b': (Action.shift, )
        }, {
            'a': (Action.reduce, 1, 1),
            'b': (Action.reduce, 1, 1),
            eof: (Action.reduce, 1, 1)
        }, {
            eof: (Action.accept, 0, 0)
        }, {
            'a': (Action.reduce, 1, 0),
            'b': (Action.reduce, 1, 0),
            eof: (Action.reduce, 1, 0)
        }]

        correct_goto = [{
            ('nt', X): 1,
            ('t', 'a'): 2,
            ('t', 'b'): 3
        }, {
            ('nt', X): 4,
            ('t', 'a'): 2,
            ('t', 'b'): 3
        }, {
            ('nt', X): 5,
            ('t', 'a'): 2,
            ('t', 'b'): 3
        }, {}, {}, {}]

        self.assertIsomorphic(action, goto, correct_action, correct_goto)
Esempio n. 10
0
    def test_item_closure(self):
        rule_set = LALRRuleSet()  # example grammar on EC pp.120
        goal, list_, pair = rule_set.new_nt(3)
        rule_set.add_rule(goal, d(nt(list_)))
        rule_set.add_rule(list_, d(nt(list_), nt(pair)))
        rule_set.add_rule(list_, d(nt(pair)))
        rule_set.add_rule(pair, d(t('('), nt(pair), t(')')))
        rule_set.add_rule(pair, d(t('('), t(')')))
        rule_set.mark_goal(goal)

        item_set = {(goal, 0, 0): {eof}}
        closure = rule_set.item_closure(item_set)
        self.assertEqual(
            closure, {
                (goal, 0, 0): {eof},
                (list_, 0, 0): {eof, '('},
                (list_, 1, 0): {eof, '('},
                (pair, 0, 0): {eof, '('},
                (pair, 1, 0): {eof, '('}
            })

        item_set = {(pair, 0, 1): {eof, '('}, (pair, 1, 1): {eof, '('}}
        closure = rule_set.item_closure(item_set)
        self.assertEqual(
            closure, {
                (pair, 0, 1): {eof, '('},
                (pair, 1, 1): {eof, '('},
                (pair, 0, 0): {')'},
                (pair, 1, 0): {')'}
            })  # CC3

        item_set = {(pair, 0, 1): {')'}, (pair, 1, 1): {')'}}
        closure = rule_set.item_closure(item_set)
        self.assertEqual(
            closure, {
                (pair, 0, 0): {')'},
                (pair, 0, 1): {')'},
                (pair, 1, 0): {')'},
                (pair, 1, 1): {')'}
            })  # CC6
Esempio n. 11
0
    def parse(self, tokens, repo=None):
        tokens = iter(tokens)
        data_stack = [None]
        state_stack = [0]
        token = next(tokens)
        while True:
            state = state_stack[-1]
            if token[0] not in self.action[state]:
                raise ParseError(self.action[state].keys(), token[0])
            else:
                action = self.action[state][token[0]]
                if action[0] == Action.accept:
                    ntid, rule_id = action[1:]
                    derives = self.rule_set.nt_rules[ntid][rule_id]
                    split_point = -len(derives)
                    data_list = data_stack[split_point:]
                    if self.rule_actions[(ntid, rule_id)] is not None:
                        data = self.rule_actions[(ntid, rule_id)](data_list, repo)
                    else:
                        data = None
                    return data

                elif action[0] == Action.shift:
                    data_stack.append(token[1])
                    state_stack.append(self.goto[state][t(token[0])])
                    token = next(tokens)

                elif action[0] == Action.reduce:
                    ntid, rule_id = action[1:]
                    derives = self.rule_set.nt_rules[ntid][rule_id]
                    split_point = -pop_len(derives)
                    if split_point == 0:
                        data_list = []
                    else:
                        data_list = data_stack[split_point:]
                        data_stack = data_stack[:split_point]
                        state_stack = state_stack[:split_point]
                    # perform actions
                    if self.rule_actions[(ntid, rule_id)] is not None:
                        data = self.rule_actions[(ntid, rule_id)](data_list, repo)
                    else:
                        data = None
                    data_stack.append(data)
                    state = state_stack[-1]
                    state_stack.append(self.goto[state][nt(ntid)])
Esempio n. 12
0
eq = re_utils.atom('=', EQ)

alt_delim = re_utils.atom('|', ALT_DELIM)

nfa = re_utils.alt([name, blank, eq, alt_delim])

bnf_scanner = scanner_builder(nfa, category_info)

rule_set = LALRRuleSet()
bnf, alt, dlist = rule_set.new_nt(3)
rule_set.mark_goal(bnf)

rule_actions = {}

rule_set.add_rule(bnf, d(t(NAME), t(EQ), nt(alt)))


def rule_bnf(data_list, repo):
    return data_list[0], data_list[2]


rule_actions[(bnf, 0)] = rule_bnf
rule_set.add_rule(alt, d(nt(alt), t(ALT_DELIM), nt(dlist)))


def rule_alt(data_list, repo):
    return data_list[0] + [data_list[2]]


rule_actions[(alt, 0)] = rule_alt