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)
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})
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)
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)