Пример #1
0
    def test_grammar(self):
        with open('tests/test_grammar.txt') as grammar_file:
            self.G = Grammar(grammar_file.read())
            self.assertDictEqual(
                {'E': {('E', '+', 'T'), ('T',)}, 'T': {('T', '*', 'F'), ('F',)}, 'F': {('(', 'E', ')'), ('id',)}},
                self.G.grammar)
            self.assertEqual('E', self.G.start)
            self.assertSetEqual({'+', '*', '(', ')', 'id'}, self.G.terminals)
            self.assertSetEqual({'E', 'T', 'F'}, self.G.nonterminals)
            self.assertSetEqual({'+', '*', '(', ')', 'id', 'E', 'T', 'F'}, self.G.symbols)

        self.grammar_str = ["""E -> E + T
e -> T
T -> T * F | F
F -> ( E )
F -> id""", """E -> E ^ + T
E -> T
T -> T * F | F
F -> ( E )
F -> id"""]

        with self.assertRaises(ValueError):
            Grammar(self.grammar_str[0])

        with self.assertRaises(ValueError):
            Grammar(self.grammar_str[1])
Пример #2
0
    def test_LR_parser(self):
        expected_results = [
            'ERROR: unrecognized symbol -',
            'ERROR: input cannot be parsed by given grammar', 'accept'
        ]

        for i, w in enumerate(['id - id', '+ id', 'id + id * id']):
            with self.subTest(w=w):
                results = self.slr_parser.LR_parser(w)
                self.assertEqual(expected_results[i], results['action'][-1])

        grammar_strs = [
            """S -> L = R | R
L -> * R | id
R -> L""", """E -> T | F
T -> id
F -> id"""
        ]
        expected_results = [
            'ERROR: shift-reduce conflict at state ',
            'ERROR: reduce-reduce conflict at state '
        ]

        for i, w in enumerate(['id = id', 'id']):
            with self.subTest(w=w):
                G = Grammar(grammar_strs[i])
                slr_parser = SLRParser(G)
                results = slr_parser.LR_parser(w)
                self.assertIn(expected_results[i], results['action'][-1])
Пример #3
0
    def test_CLOSURE(self):
        self.assertDictEqual(
            {
                "E'": {('.', 'E')},
                'E': {('.', 'E', '+', 'T'), ('.', 'T')},
                'T': {('.', 'T', '*', 'F'), ('.', 'F')},
                'F': {('.', '(', 'E', ')'), ('.', 'id')}
            },
            self.slr_parser.CLOSURE({
                self.slr_parser.G_prime.start:
                {('.', self.slr_parser.G_prime.start[:-1])}
            }))

        grammar_str = """E -> + E"""

        with self.subTest(grammar_str=grammar_str):
            G = Grammar(grammar_str)
            slr_parser = SLRParser(G)

            self.assertDictEqual({
                'E': {('.', '+', 'E')},
                "E'": {('.', 'E')}
            },
                                 slr_parser.CLOSURE({
                                     slr_parser.G_prime.start:
                                     {('.', slr_parser.G_prime.start[:-1])}
                                 }))
Пример #4
0
    def __init__(self, G):
        self.G_prime = Grammar(f"{G.start}' -> {G.start}\n{G.grammar_str}")
        self.max_G_prime_len = len(max(self.G_prime.grammar, key=len))
        self.G_indexed = []

        for head, bodies in self.G_prime.grammar.items():
            for body in bodies:
                self.G_indexed.append([head, body])

        self.first, self.follow = first_follow(self.G_prime)
        self.C = self.items(self.G_prime)
        self.action = list(self.G_prime.terminals) + ['$']
        self.goto = list(self.G_prime.nonterminals - {self.G_prime.start})
        self.parse_table_symbols = self.action + self.goto
        self.parse_table = self.construct_table()
Пример #5
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('grammar_file',
                        type=argparse.FileType('r'),
                        help='text file to be used as grammar')
    parser.add_argument('-g', action='store_true', help='generate automaton')
    parser.add_argument(
        'tokens',
        help='tokens to be parsed - all tokens are separated with spaces')
    args = parser.parse_args()

    G = Grammar(args.grammar_file.read())
    slr_parser = SLRParser(G)
    slr_parser.print_info()
    results = slr_parser.LR_parser(args.tokens)
    slr_parser.print_LR_parser(results)

    if args.g:
        slr_parser.generate_automaton()
Пример #6
0
 def setUp(self):
     with open('tests/test_grammar.txt') as grammar_file:
         self.G = Grammar(grammar_file.read())
         self.slr_parser = SLRParser(self.G)
Пример #7
0
    def test_items(self):
        self.assertCountEqual([{
            "E'": {('.', 'E')},
            'E': {('.', 'E', '+', 'T'), ('.', 'T')},
            'T': {('.', 'T', '*', 'F'), ('.', 'F')},
            'F': {('.', '(', 'E', ')'), ('.', 'id')}
        }, {
            'F': {('id', '.')}
        }, {
            "E'": {('E', '.')},
            'E': {('E', '.', '+', 'T')}
        }, {
            'T': {('F', '.')}
        }, {
            'E': {('T', '.')},
            'T': {('T', '.', '*', 'F')}
        }, {
            'F': {('(', '.', 'E', ')'), ('.', '(', 'E', ')'), ('.', 'id')},
            'E': {('.', 'E', '+', 'T'), ('.', 'T')},
            'T': {('.', 'T', '*', 'F'), ('.', 'F')}
        }, {
            'E': {('E', '+', '.', 'T')},
            'T': {('.', 'T', '*', 'F'), ('.', 'F')},
            'F': {('.', '(', 'E', ')'), ('.', 'id')}
        }, {
            'T': {('T', '*', '.', 'F')},
            'F': {('.', '(', 'E', ')'), ('.', 'id')}
        }, {
            'F': {('(', 'E', '.', ')')},
            'E': {('E', '.', '+', 'T')}
        }, {
            'E': {('E', '+', 'T', '.')},
            'T': {('T', '.', '*', 'F')}
        }, {
            'T': {('T', '*', 'F', '.')}
        }, {
            'F': {('(', 'E', ')', '.')}
        }], self.slr_parser.items(self.slr_parser.G_prime))

        grammar_str = """E -> E + T | E - T
E -> T
T -> T * F | T / F | F
F -> ( E )
F -> id"""

        with self.subTest(grammar_str=grammar_str):
            G = Grammar(grammar_str)
            slr_parser = SLRParser(G)
            self.assertCountEqual([{
                "E'": {('.', 'E')},
                'E': {('.', 'E', '+', 'T'), ('.', 'E', '-', 'T'), ('.', 'T')},
                'T': {('.', 'T', '*', 'F'), ('.', 'T', '/', 'F'), ('.', 'F')},
                'F': {('.', '(', 'E', ')'), ('.', 'id')}
            }, {
                'F': {('id', '.')}
            }, {
                'T': {('F', '.')}
            }, {
                'E': {('T', '.')},
                'T': {('T', '.', '*', 'F'), ('T', '.', '/', 'F')}
            }, {
                'F': {('(', '.', 'E', ')'), ('.', '(', 'E', ')'), ('.', 'id')},
                'E': {('.', 'E', '+', 'T'), ('.', 'E', '-', 'T'), ('.', 'T')},
                'T': {('.', 'T', '*', 'F'), ('.', 'T', '/', 'F'), ('.', 'F')}
            }, {
                "E'": {('E', '.')},
                'E': {('E', '.', '+', 'T'), ('E', '.', '-', 'T')}
            }, {
                'T': {('T', '/', '.', 'F')},
                'F': {('.', '(', 'E', ')'), ('.', 'id')}
            }, {
                'T': {('T', '*', '.', 'F')},
                'F': {('.', '(', 'E', ')'), ('.', 'id')}
            }, {
                'F': {('(', 'E', '.', ')')},
                'E': {('E', '.', '+', 'T'), ('E', '.', '-', 'T')}
            }, {
                'E': {('E', '+', '.', 'T')},
                'T': {('.', 'T', '*', 'F'), ('.', 'T', '/', 'F'), ('.', 'F')},
                'F': {('.', '(', 'E', ')'), ('.', 'id')}
            }, {
                'E': {('E', '-', '.', 'T')},
                'T': {('.', 'T', '*', 'F'), ('.', 'T', '/', 'F'), ('.', 'F')},
                'F': {('.', '(', 'E', ')'), ('.', 'id')}
            }, {
                'T': {('T', '/', 'F', '.')}
            }, {
                'T': {('T', '*', 'F', '.')}
            }, {
                'F': {('(', 'E', ')', '.')}
            }, {
                'E': {('E', '+', 'T', '.')},
                'T': {('T', '.', '*', 'F'), ('T', '.', '/', 'F')}
            }, {
                'E': {('E', '-', 'T', '.')},
                'T': {('T', '.', '*', 'F'), ('T', '.', '/', 'F')}
            }], slr_parser.items(slr_parser.G_prime))
Пример #8
0
    def test_first_follow(self):
        grammar_strs = [
            """E -> E + T
E -> T
T -> T * F | F
F -> ( E )
F -> id""", """E -> T E'
E' -> + T E' | ^
T -> F T'
T' -> * F T' | ^
F -> ( E ) | id""", """E -> T X
X -> + E
X -> ^
T -> int Y
T -> ( E )
Y -> * T
Y -> ^""", """S -> a B D h
B -> c C
C -> b C | ^
D -> E F
E -> g | ^
F -> f | ^""", """S -> A
A -> a B | A d
B -> b
C -> g""", """S -> ( L ) | a
L -> S L'
L' -> , S L' | ^""", """S -> A a A b | B b B a
A -> ^
B -> ^""", """S -> A C B | C b B | B a
A -> d a | B C
B -> g | ^
C -> h | ^"""
        ]

        with self.subTest(grammar_str=grammar_strs[0]):
            G = Grammar(grammar_strs[0])
            first, follow = first_follow(G)
            self.assertSetEqual({'(', 'id'}, first['E'])
            self.assertSetEqual({'(', 'id'}, first['T'])
            self.assertSetEqual({'(', 'id'}, first['F'])
            self.assertSetEqual({'$', '+', ')'}, follow['E'])
            self.assertSetEqual({'$', '+', '*', ')'}, follow['T'])
            self.assertSetEqual({'$', '+', '*', ')'}, follow['F'])

        with self.subTest(grammar_str=grammar_strs[1]):
            G = Grammar(grammar_strs[1])
            first, follow = first_follow(G)
            self.assertSetEqual({'(', 'id'}, first['E'])
            self.assertSetEqual({'(', 'id'}, first['T'])
            self.assertSetEqual({'(', 'id'}, first['F'])
            self.assertSetEqual({'+', '^'}, first["E'"])
            self.assertSetEqual({'*', '^'}, first["T'"])
            self.assertSetEqual({')', '$'}, follow['E'])
            self.assertSetEqual({')', '$'}, follow["E'"])
            self.assertSetEqual({'+', ')', '$'}, follow['T'])
            self.assertSetEqual({'+', ')', '$'}, follow["T'"])
            self.assertSetEqual({'+', '*', ')', '$'}, follow['F'])

        with self.subTest(grammar_str=grammar_strs[2]):
            G = Grammar(grammar_strs[2])
            first, follow = first_follow(G)
            self.assertSetEqual({'('}, first['('])
            self.assertSetEqual({')'}, first[')'])
            self.assertSetEqual({'+'}, first['+'])
            self.assertSetEqual({'*'}, first['*'])
            self.assertSetEqual({'int'}, first['int'])
            self.assertSetEqual({'^', '*'}, first['Y'])
            self.assertSetEqual({'^', '+'}, first['X'])
            self.assertSetEqual({'int', '('}, first['T'])
            self.assertSetEqual({'int', '('}, first['E'])
            self.assertSetEqual({')', '$', '+'}, follow['Y'])
            self.assertSetEqual({')', '$'}, follow['X'])
            self.assertSetEqual({')', '$', '+'}, follow['T'])
            self.assertSetEqual({')', '$'}, follow['E'])

        with self.subTest(grammar_str=grammar_strs[3]):
            G = Grammar(grammar_strs[3])
            first, follow = first_follow(G)
            self.assertSetEqual({'a'}, first['S'])
            self.assertSetEqual({'c'}, first['B'])
            self.assertSetEqual({'b', '^'}, first['C'])
            self.assertSetEqual({'g', 'f', '^'}, first['D'])
            self.assertSetEqual({'g', '^'}, first['E'])
            self.assertSetEqual({'f', '^'}, first['F'])
            self.assertSetEqual({'$'}, follow['S'])
            self.assertSetEqual({'g', 'f', 'h'}, follow['B'])
            self.assertSetEqual({'g', 'f', 'h'}, follow['C'])
            self.assertSetEqual({'h'}, follow['D'])
            self.assertSetEqual({'f', 'h'}, follow['E'])
            self.assertSetEqual({'h'}, follow['F'])

        with self.subTest(grammar_str=grammar_strs[4]):
            G = Grammar(grammar_strs[4])
            first, follow = first_follow(G)
            self.assertSetEqual({'a'}, first['S'])
            self.assertSetEqual({'a'}, first['A'])
            self.assertSetEqual({'b'}, first['B'])
            self.assertSetEqual({'g'}, first['C'])
            self.assertSetEqual({'$'}, follow['S'])
            self.assertSetEqual({'$', 'd'}, follow['A'])
            self.assertSetEqual({'$', 'd'}, follow['B'])
            self.assertSetEqual(set(), follow['C'])

        with self.subTest(grammar_str=grammar_strs[5]):
            G = Grammar(grammar_strs[5])
            first, follow = first_follow(G)
            self.assertSetEqual({'(', 'a'}, first['S'])
            self.assertSetEqual({'(', 'a'}, first['L'])
            self.assertSetEqual({',', '^'}, first["L'"])
            self.assertSetEqual({'$', ',', ')'}, follow['S'])
            self.assertSetEqual({')'}, follow['L'])
            self.assertSetEqual({')'}, follow["L'"])

        with self.subTest(grammar_str=grammar_strs[6]):
            G = Grammar(grammar_strs[6])
            first, follow = first_follow(G)
            self.assertSetEqual({'a', 'b'}, first['S'])
            self.assertSetEqual({'^'}, first['A'])
            self.assertSetEqual({'^'}, first['B'])
            self.assertSetEqual({'$'}, follow['S'])
            self.assertSetEqual({'a', 'b'}, follow['A'])
            self.assertSetEqual({'a', 'b'}, follow['B'])

        with self.subTest(grammar_str=grammar_strs[7]):
            G = Grammar(grammar_strs[7])
            first, follow = first_follow(G)
            self.assertSetEqual({'d', 'g', 'h', '^', 'b', 'a'}, first['S'])
            self.assertSetEqual({'d', 'g', 'h', '^'}, first['A'])
            self.assertSetEqual({'g', '^'}, first['B'])
            self.assertSetEqual({'h', '^'}, first['C'])
            self.assertSetEqual({'$'}, follow['S'])
            self.assertSetEqual({'h', 'g', '$'}, follow['A'])
            self.assertSetEqual({'$', 'a', 'h', 'g'}, follow['B'])
            self.assertSetEqual({'g', '$', 'b', 'h'}, follow['C'])