Commit ea92d615 authored by Kateřina Sloupová's avatar Kateřina Sloupová
Browse files

tests - tasks from is (only correct solutions so far); few tweaks

parent 2e639286
Loading
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3,3 +3,5 @@
*.swo
*~
__pycache__
.idea
.pytest_cache
+2 −2
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ def dfa_transform(string: str, automaton_type: str) -> reg.DFA:
    except reg.ParsingError as ex:
        print("Chyba při parsování.")
        exit(1)
    except Exception as ex:
    #except Exception as ex:
        print("Chyba při parsování.")
        exit(1)

@@ -211,7 +211,7 @@ def main():
        task_prefix, teacher_string = teacher_string.split(":", 1)
        teacher_type, task = get_task(task_prefix)

        if teacher_type == "DFA":
        if teacher_type == "DFA" or teacher_type == "NFA":
            dfa_task(teacher_type=teacher_type, teacher_string=teacher_string,
                     task=task, student_string=student_string)
        elif teacher_type == "CFG":
+29 −20
Original line number Diff line number Diff line
@@ -23,12 +23,21 @@ class RegGrammar:
        assert self.check()

    @staticmethod
    def reggrammar_from_cfg(cfg: CFG) -> RegGrammar:
        try:
    def from_cfg(cfg: CFG) -> RegGrammar:
        if cfg.is_regular():
                return RegGrammar(cfg.nonterminals, cfg.terminals, cfg.rules, cfg.init)
        except: # I don't know
            pass
            reg_rules : RegGrammar.Rules = {}
            for nonterminal in cfg.rules:
                for rule in cfg.rules[nonterminal]:
                    new_rule = rule
                    # rule of type Tuple[Terminal] becomes of type Terminal, others are OK
                    if isinstance(rule, tuple) and len(rule) == 1:
                        new_rule = rule[0]
                    reg_rules.setdefault(nonterminal, set()).add(new_rule)

            return RegGrammar(cfg.nonterminals, cfg.terminals, reg_rules, cfg.init)

        # exception


    # unused formal requirements check, regular grammars specific (rule variants)
    def check(self) -> bool:
@@ -48,38 +57,38 @@ class RegGrammar:
        return True

    def reggrammar_to_nfa(self) -> NFA:

        init = State(self.init.name)
        states: Set[State] = set()
        for nonterminal in self.nonterminals:
            states.add(State(nonterminal.name))

        final = State("new_final")  # TODO assert that name is unique, as for hell in make_total
        states.add(final)

        init = State(self.init.name)

        characters: Set[Character] = set()
        for terminal in self.terminals:
            characters.add(Character(terminal.name))

        final = State("new_final")  # TODO assert that name is unique, as for hell in make_total
        states.add(final)
        transition: Dict[Tuple[State, Character], Set[State]] = dict()

        for nonterminal in self.rules:
            state = State(nonterminal.name)
            for rule in self.rules[nonterminal]:

                # rule A -> a becomes d(A, a) = final
                if isinstance(rule, Terminal):  # TODO and a is not \eps
                if isinstance(rule, Terminal):
                    character = Character(rule.name)
                    transition.setdefault((state, character), set()).add(final)

                # rule A -> aB becomes d(A, a) = B
                elif (state, rule[0]) in transition:
                elif isinstance(rule, Tuple):
                    character = Character(rule[0].name)
                    transition[state, character].add(State(rule[1].name))
                else:
                    character = Character(rule[0].name)
                    transition[state, character] = {State(rule[1].name)}
                    transition.setdefault((state, character), set()).add(State(rule[1].name))

        final_states = {final}
        for rule in self.rules[self.init]:
            if isinstance(rule, Eps):
                final_states.add(init)

        # TODO if init -> \eps: nfa.final.add(nfa.init)
        # I need to know how to treat \eps
        nfa = NFA(states, characters, transition, init, {final})
        nfa = NFA(states, characters, transition, init, final_states)
        return nfa
 No newline at end of file
+2 −2
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ class CFG:
                    if nonterminal == self.init and not self.is_nonterminal_used(nonterminal):
                        continue
                    else:
                        print("Gramatika není regulární: výskyt epsilon u neterminálu, který se vyskytuje na pravé straně některého pravidla.")
                        #print("Gramatika není regulární: výskyt epsilon u neterminálu, který se vyskytuje na pravé straně některého pravidla.")
                        return False

                if isinstance(rule, tuple):  # TODO nicer
@@ -170,7 +170,7 @@ class CFG:
                       (len(rule) == 2 and isinstance(rule[0], Terminal) and isinstance(rule[1], Nonterminal)):
                        continue

                print("Gramatika není regulární: špatný tvar pravé strany některého z pravidel.")
                #print("Gramatika není regulární: špatný tvar pravé strany některého z pravidel.")
                return False
        return True

+7 −6
Original line number Diff line number Diff line
@@ -115,8 +115,9 @@ class Parser:

        return CFG(listener.nonterminals, listener.terminals, listener.rules, listener.init)

    def str_to_reggrammar(self):
        pass
    def str_to_reggrammar(self, string: str) -> RegGrammar:
        cfg = self.str_to_cfg(string)
        return RegGrammar.from_cfg(cfg)

    def str_to_dfa(self, string: str) -> DFA:
        listener = self.common_parse(string, DFALexer, DFAParser, DFAListener)
@@ -205,6 +206,7 @@ class NFAListener(NFAListener):
        self.efa = False

    def exitInit(self, ctx):
        if ctx.statename() is not None:
            state = State(str(ctx.statename().STATE()))
            self.init = state
            self.states.add(state)
@@ -212,7 +214,6 @@ class NFAListener(NFAListener):
    def exitProduction(self, ctx):
        state = State(str(ctx.statename(0).STATE()))
        self.states.add(state)

        dest_states = set()
        i = 0
        while ctx.stateset().statename(i) is not None:
Loading