Пример #1
0
 def test_book_example(self):
     """
     S -> i E t S | i E t S e S | a
     E -> b
     """
     solved = f.parse_bnf(test_data.solved_left_factoring)
     unsolved = f.parse_bnf(test_data.unsolved_left_factoring)
     g = f.remove_left_factoring(unsolved)
     self.assertEqual(solved, g)
Пример #2
0
 def test_simple(self):
     a = Grammar(start='E')
     a.add_rule(Rule('E', ('E', '+', 'T')))
     a.add_rule(Rule('E', ('T', )))
     a.add_rule(Rule('T', ('T', '*', 'F')))
     a.add_rule(Rule('T', ('F', )))
     a.add_rule(Rule('F', ('(', 'E', ')')))
     a.add_rule(Rule('F', ('id', )))
     text = str(a)
     g = f.parse_bnf(text)
     self.assertEqual(a, g)
Пример #3
0
    def test_book_example(self):
        g = f.parse_bnf(test_data.book_example)
        answers = {
            'E': {'$', ')'},
            'E\'': {'$', ')'},
            'T': {'$', ')', '+'},
            'T\'': {'$', ')', '+'},
            'F': {'$', ')', '*', '+'}
        }

        for x, first in answers.items():
            self.assertEqual(first, set(g.follow(x)))
Пример #4
0
def do_the_whole_thing(grammar_text,
                       epsilon='ε',
                       eof='$',
                       output=None,
                       verbose=True):
    file = None
    if output:
        file = open(output, 'w')
        sys.stdout = file

    vprint = print if verbose else lambda *a, **key: None  # Only print if verbose is True

    vprint("Original:")
    g = parse_bnf(grammar_text, epsilon=epsilon, eof=eof)
    vprint(g)

    vprint("\nAfter removing left-recursion:")
    g = remove_left_recursion(g)
    vprint(g)

    vprint("\nAfter removing left-factoring:")
    g = remove_left_factoring(g)
    vprint(g)

    vprint()
    for nt in g.nonterminals:
        vprint('FIRST({}) = {}'.format(nt, g.first(nt)))

    vprint()
    follow = [(nt, g.follow(nt)) for nt in g.nonterminals]

    for nt, f in follow:
        vprint('FOLLOW({}) = {}'.format(nt, f))

    vprint()
    table, ambiguous = g.parsing_table()
    vprint("Parsing Table: ")
    if ambiguous:
        vprint(
            "El lenguaje de entrada no es LL(1) debido a que se encontraron ambigüedades."
        )

    vprint()
    pprint_table(g, table)

    if file:
        file.close()
Пример #5
0
def just_do_it(req):
    errors = []
    g = None
    grammar_not_recursive = None
    grammar_not_factor = None
    parsing_table = None

    try:
        g = parse_bnf(req.form['bnf'],
                      epsilon=req.form['epsilon'],
                      eof=req.form['eof'])
        grammar_not_recursive = remove_left_recursion(g)
        grammar_not_factor = remove_left_factoring(grammar_not_recursive)
        table, ambiguous = grammar_not_factor.parsing_table()

        if ambiguous:
            errors.append(
                'El lenguaje de entrada no es LL(1) debido a que se encontraron ambigüedades.'
            )

        parsing_table = {
            'table': table,
            'terminals': sorted(set(g.terminals) - {g.epsilon}) + [g.eof],
            'nonterminals': [nt for nt in grammar_not_factor.nonterminals]
        }

    except InvalidGrammar:
        errors.append(
            'Gramática inválida. Revise las especificaciones de BNF.')
    except InvalidProduction as e:
        errors.append('Produccion invalida: {}.'.format(e.production))

    return render_template('results.html',
                           grammar=g,
                           no_recursion=grammar_not_recursive,
                           no_factor=grammar_not_factor,
                           parsing_table=parsing_table,
                           errors=errors)
Пример #6
0
    def test_book_example(self):
        g = f.parse_bnf(test_data.unsolved_left_recursion)
        # Trust me, this is the answer
        answer = {
            ("T'", '+'): Rule("T'", ('ε', )),
            ('F', 'id'): Rule('F', ('id', )),
            ("E'", '+'): Rule("E'", ('+', 'T', "E'")),
            ('E', '('): Rule('E', ('T', "E'")),
            ('T', '('): Rule('T', ('F', "T'")),
            ("E'", '$'): Rule("E'", ('ε', )),
            ("T'", '*'): Rule("T'", ('*', 'F', "T'")),
            ("T'", ')'): Rule("T'", ('ε', )),
            ("T'", '$'): Rule("T'", ('ε', )),
            ("E'", ')'): Rule("E'", ('ε', )),
            ('T', 'id'): Rule('T', ('F', "T'")),
            ('E', 'id'): Rule('E', ('T', "E'")),
            ('F', '('): Rule('F', ('(', 'E', ')'))
        }

        table, amb = g.parsing_table(is_clean=False)

        self.assertFalse(amb)
        self.assertEqual(table, answer)
Пример #7
0
 def test_check_left_factor(self):
     solved = f.parse_bnf(test_data.solved_left_factoring)
     unsolved = f.parse_bnf(test_data.unsolved_left_factoring)
     self.assertTrue(f.check_left_factors(unsolved))
     self.assertFalse(f.check_left_factors(solved))
Пример #8
0
 def test_simple_book_example(self):
     solved = f.parse_bnf(test_data.solved_left_recursion)
     unsolved = f.parse_bnf(test_data.unsolved_left_recursion)
     g = f.remove_left_recursion(unsolved)
     self.assertEqual(solved, g)
Пример #9
0
 def test_cases(self):
     for case in test_data.examples:
         g = f.parse_bnf(case)
         text = str(g)
         self.assertEqual(g, f.parse_bnf(text))
Пример #10
0
 def test_invalid_production(self):
     text = "E -> E + T | E"  # Production is the same as nonterminal
     with self.assertRaises(InvalidProduction):
         f.parse_bnf(text)
Пример #11
0
 def test_invalid_grammar(self):
     text = "INVALID"
     with self.assertRaises(InvalidGrammar):
         f.parse_bnf(text)
Пример #12
0
 def setUp(self):
     self.g = f.parse_bnf(test_data.exam_exercise)