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

grammar and regex evaluation tweaks

parent 6202b25d
......@@ -17,6 +17,13 @@ tasks = {'DFA': 'DFA',
'GRA': 'Regulární gramatika',
'REG': 'Regulární výraz'}
convs = {'DFA': 'DFA',
'TOT': 'Totální DFA',
'MIN': 'Minimální DFA',
'EFA': 'NFA (s ε-kroky)',
'NFA': 'NFA bez ε-kroků',
'GRA': 'Regulární gramatika'}
types = {'DFA': 'DFA',
'EFA': 'NFA (s ε-kroky)',
'GRA': 'Regulární gramatika',
......@@ -30,6 +37,9 @@ class TypeForm(FlaskForm):
class TaskForm(FlaskForm):
make = RadioField('Task', choices=list(tasks.items()), default='DFA', coerce=str)
class ConvertForm(FlaskForm):
make = RadioField('Convert', choices=list(convs.items()), default='DFA', coerce=str)
@bp.route('/compare', methods=('GET', 'POST'))
def compare():
......
from typing import List, Dict, Tuple, Optional, Union, Set, TypeVar
from copy import deepcopy
from lib.common import State, Character, Eps, Terminal, Nonterminal, Emptyset
from lib.reg import DFA, NFA, RegGrammar
from lib.grammars_cfg import CFG
......@@ -39,29 +40,33 @@ class Parser:
return "{" + ','.join(set(map(lambda x: x.name, collection))) + "}"
def reggrammar_to_str(self, reg: RegGrammar, full: bool = False) -> str:
rules = self.rules_to_str(reg.rules)
nonterminals = deepcopy(reg.nonterminals).difference({reg.init})
nonterminals = [reg.init] + list(nonterminals)
rules = self.rules_to_str(reg.rules, nonterminals)
if not full:
return rules
# full - verbose description of DFA - only for development, dismiss later
nonterminals = self.names_to_str(reg.nonterminals)
nonterminals_names = self.names_to_str(reg.nonterminals)
terminals = self.names_to_str(reg.terminals)
return f"Grammar: ({nonterminals}, {terminals}, P, {reg.init.name})\n{self.rules_to_str(reg.rules)}"
return f"Grammar: ({nonterminals_names}, {terminals}, P, {reg.init.name})\n{self.rules_to_str(reg.rules, nonterminals)}"
def cfg_to_str(self, gra: CFG, full: bool = False) -> str:
rules = self.rules_to_str(gra.rules)
nonterminals = deepcopy(gra.nonterminals).difference({gra.init})
nonterminals = [gra.init] + list(nonterminals)
rules = self.rules_to_str(gra.rules, nonterminals)
if not full:
return rules
# full - verbose description of DFA - only for development, dismiss later
nonterminals = self.names_to_str(gra.nonterminals)
nonterminals_names = self.names_to_str(gra.nonterminals)
terminals = self.names_to_str(gra.terminals)
return f"Grammar: ({nonterminals}, {terminals}, P, {gra.init.name})\n{self.rules_to_str(gra.rules)}"
return f"Grammar: ({nonterminals_names}, {terminals}, P, {gra.init.name})\n{self.rules_to_str(gra.rules, nonterminals)}"
def rules_to_str(self, rules: Union[CFG.Rules, RegGrammar.Rules]) -> str:
def rules_to_str(self, rules: Union[CFG.Rules, RegGrammar.Rules], nonterminals: List[Nonterminal]) -> str:
out = ""
for nonterminal in rules:
if len(rules[nonterminal]) == 0:
for nonterminal in nonterminals:
if nonterminal not in rules:
continue
rewritten = ' | '.join(set(map(lambda x: self.rewrite_variant(x), rules[nonterminal])))
out += f"{nonterminal.name} -> {rewritten}\n"
......
......@@ -36,7 +36,6 @@ class NFA(NFA):
rules: RegGrammar.Rules = dict()
init = Nonterminal(nfa.init.name)
for state in nfa.states:
nonterminals.add(Nonterminal(state.name))
for character in nfa.characters:
......@@ -55,7 +54,7 @@ class NFA(NFA):
if nfa.init in nfa.final:
new_init = Nonterminal("<newinit>")
rules[new_init] = {Eps()}
rules[new_init].add(rules[init])
rules[new_init].update(rules[init])
init = new_init
nonterminals.add(init)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment