Exemple #1
0
    def test_epsilon(self):
        statement = NonTerminal("Statement")
        expression = NonTerminal("Expression")
        epsilon = Epsilon()
        semicolon = Terminal(CHARACTER, ";")
        plus = Terminal(CHARACTER, "+")
        minus = Terminal(CHARACTER, "-")

        production = Productions({
            statement: [[expression, semicolon]],
            expression: [[plus], [minus], [epsilon]],
        })

        production.set_start_symbol(statement)

        fs = FirstPlusSet(production)
        fs.compute()

        real_result = fs.first_plus_set

        expect_result = {
            NonTerminal("Statement"): {
                Terminal(CHARACTER, "+"): 0,
                Terminal(CHARACTER, "-"): 0,
                Terminal(CHARACTER, ";"): 0,
            },
            NonTerminal("Expression"): {
                Terminal(CHARACTER, "+"): 0,
                Terminal(CHARACTER, "-"): 1,
                Terminal(CHARACTER, ";"): 2,
            },
        }

        self.assertEqual(real_result, expect_result)
Exemple #2
0
    def generate_production(self):
        formal_production = Productions()

        for lhs_lexeme in self.production_dict:
            lhs_symbol = NonTerminal(lhs_lexeme.value)
            production_list = []
            formal_production[lhs_symbol] = production_list

            if lhs_lexeme == self.start_symbol:
                formal_production.start_symbol = lhs_symbol

            productions = self.production_dict[lhs_lexeme]
            for production in productions:
                production_symbols = []
                production_list.append(production_symbols)
                for rhs_symbol in production:
                    if rhs_symbol.type_ == EPSILON:
                        production_symbols.append(Epsilon())
                    elif rhs_symbol.type_ == NON_TERMINAL:
                        production_symbols.append(NonTerminal(rhs_symbol.value))
                    elif rhs_symbol.type_ == TERMINAL:
                        production_symbols.append(
                            Terminal(type_=None, data=rhs_symbol.value)
                        )

        return formal_production
    def test_conception(self):
        statement = NonTerminal("Statement")
        expression = NonTerminal("Expression")
        semicolon = Terminal(CHARACTER, ";")
        production = Productions({statement: [[expression, semicolon]]})

        production.print_as_bnf()

        self.assertEqual(production.terminals, {semicolon})
        self.assertEqual(production.non_terminals, {statement, expression})
Exemple #4
0
    def test_conception(self):
        statement = NonTerminal("Statement")
        expression = NonTerminal("Expression")
        semicolon = Terminal(CHARACTER, ";")
        plus = Terminal(CHARACTER, "+")
        minus = Terminal(CHARACTER, "-")

        production = Productions(
            {statement: [[expression, semicolon]], expression: [[plus], [minus]]}
        )

        production.set_start_symbol(statement)

        fs = FirstSet(production)
        fs.compute()
        print(fs.first_set)
    def test_real(self):
        """
        Goal -> Expr ;
        Expr -> Term ExprTwo ;
        ExprTwo -> '+' Term ExprTwo
                 | '-' Term ExprTwo
                 | ϵ ;
        Term -> Factor TermTwo ;
        TermTwo -> '*' Factor TermTwo
                 | '/' Factor TermTwo
                 | ϵ ;
        Factor -> '(' Expr ')'
                | 'num'
                | 'name' ;
        """

        """
        Extended Backus-Naur form:

        Goal -> Expr
        Expr -> Term ExprTwo
        ExprTwo -> + Term ExprTwo | - Term ExprTwo | EPSILON
        Term -> Factor TermTwo
        TermTwo -> * Factor TermTwo | / Factor TermTwo | EPSILON
        Factor -> ( Expr ) | num | name
        """
        goal = NonTerminal("Goal")
        expr = NonTerminal("Expr")
        expr_two = NonTerminal("ExprTwo")
        term = NonTerminal("Term")
        term_two = NonTerminal("TermTwo")
        factor = NonTerminal("Factor")
        epsilon = Epsilon()
        name = Terminal(CHARACTER, "name")
        num = Terminal(CHARACTER, "num")
        plus = Terminal(CHARACTER, "+")
        minus = Terminal(CHARACTER, "-")
        div = Terminal(CHARACTER, "/")
        asteroid = Terminal(CHARACTER, "*")
        open_parenthesis = Terminal(CHARACTER, "(")
        close_parenthesis = Terminal(CHARACTER, ")")
        eof = EOF()

        production = Productions(
            {
                goal: [[expr]],
                expr: [[term, expr_two]],
                expr_two: [[plus, term, expr_two], [minus, term, expr_two], [epsilon]],
                term: [[factor, term_two]],
                term_two: [
                    [asteroid, factor, term_two],
                    [div, factor, term_two],
                    [epsilon],
                ],
                factor: [[open_parenthesis, expr, close_parenthesis], [num], [name]],
            }
        )

        production.set_start_symbol(goal)

        fs = FirstSet(production)
        fs.compute()
        first_set = fs.first_set

        fs = FollowSet(production, first_set)
        fs.compute()
        real_result = fs.follow_set

        expect_result = {
            NonTerminal("Goal"): {EOF()},
            NonTerminal("Expr"): {Terminal(CHARACTER, ")"), EOF()},
            NonTerminal("ExprTwo"): {Terminal(CHARACTER, ")"), EOF()},
            NonTerminal("Term"): {
                EOF(),
                Terminal(CHARACTER, "+"),
                Terminal(CHARACTER, "-"),
                Terminal(CHARACTER, ")"),
            },
            NonTerminal("TermTwo"): {
                EOF(),
                Terminal(CHARACTER, "+"),
                Terminal(CHARACTER, "-"),
                Terminal(CHARACTER, ")"),
            },
            NonTerminal("Factor"): {
                EOF(),
                Terminal(CHARACTER, "+"),
                Terminal(CHARACTER, "-"),
                Terminal(CHARACTER, "/"),
                Terminal(CHARACTER, "*"),
                Terminal(CHARACTER, ")"),
            },
        }

        self.assertEqual(real_result, expect_result)
Exemple #6
0
    def test_real(self):
        """
        Goal -> Expr ;
        Expr -> Term ExprTwo ;
        ExprTwo -> '+' Term ExprTwo
                 | '-' Term ExprTwo
                 | ϵ ;
        Term -> Factor TermTwo ;
        TermTwo -> '*' Factor TermTwo
                 | '/' Factor TermTwo
                 | ϵ ;
        Factor -> '(' Expr ')'
                | 'num'
                | 'name' ;
        """

        """
        Extended Backus-Naur form:

        Goal -> Expr
        Expr -> Term ExprTwo
        ExprTwo -> + Term ExprTwo | - Term ExprTwo | EPSILON
        Term -> Factor TermTwo
        TermTwo -> * Factor TermTwo | / Factor TermTwo | EPSILON
        Factor -> ( Expr ) | num | name
        """
        goal = NonTerminal("Goal")
        expr = NonTerminal("Expr")
        expr_two = NonTerminal("ExprTwo")
        term = NonTerminal("Term")
        term_two = NonTerminal("TermTwo")
        factor = NonTerminal("Factor")
        epsilon = Epsilon()
        name = Terminal(CHARACTER, "name")
        num = Terminal(CHARACTER, "num")
        plus = Terminal(CHARACTER, "+")
        minus = Terminal(CHARACTER, "-")
        div = Terminal(CHARACTER, "/")
        asteroid = Terminal(CHARACTER, "*")
        open_parenthesis = Terminal(CHARACTER, "(")
        close_parenthesis = Terminal(CHARACTER, ")")
        eof = EOF()

        production = Productions(
            {
                goal: [[expr]],
                expr: [[term, term_two]],
                expr_two: [[plus, term, expr_two], [minus, term, expr_two], [epsilon]],
                term: [[factor, term_two]],
                term_two: [
                    [asteroid, factor, term_two],
                    [div, factor, term_two],
                    [epsilon],
                ],
                factor: [[open_parenthesis, expr, close_parenthesis], [num], [name]],
            }
        )

        production.set_start_symbol(goal)

        fs = FirstSet(production)
        fs.compute()
        real_result = fs.first_set

        expect_result = {
            eof: SymbolSet({eof}),
            plus: SymbolSet({plus}),
            minus: SymbolSet({minus}),
            epsilon: SymbolSet({epsilon}),
            asteroid: SymbolSet({asteroid}),
            div: SymbolSet({div}),
            open_parenthesis: SymbolSet({open_parenthesis}),
            close_parenthesis: SymbolSet({close_parenthesis}),
            num: SymbolSet({num}),
            name: SymbolSet({name}),
            expr_two: SymbolSet({plus, minus, epsilon}),
            term_two: SymbolSet({asteroid, div, epsilon}),
            factor: SymbolSet({open_parenthesis, num, name}),
            term: SymbolSet({open_parenthesis, num, name}),
            expr: SymbolSet({open_parenthesis, num, name}),
            goal: SymbolSet({open_parenthesis, num, name}),
        }

        # pprint.pprint(real_result)

        self.maxDiff = None
        self.assertEqual(real_result, expect_result)