def fsm_diagram(grammar, start_symbol=START_SYMBOL): from graphviz import Digraph from IPython.display import display def left_align(label): return dot_escape(label.replace('\n', r'\l')).replace(r'\\l', '\\l') dot = Digraph(comment="Grammar as Finite State Machine") symbols = deque([start_symbol]) symbols_seen = set() while len(symbols) > 0: symbol = symbols.popleft() symbols_seen.add(symbol) dot.node(symbol, dot_escape(unicode_escape(symbol))) for expansion in grammar[symbol]: nts = nonterminals(expansion) if len(nts) > 0: target_symbol = nts[-1] if target_symbol not in symbols_seen: symbols.append(target_symbol) label = expansion.replace(target_symbol, '') dot.edge(symbol, target_symbol, left_align(unicode_escape(label))) return display(dot)
def annotate_node(dot, nid, symbol, ann): if nid in a_nodes: dot.node( repr(nid), "%s (%s)" % (dot_escape(unicode_escape(symbol)), a_nodes[nid])) else: dot.node(repr(nid), dot_escape(unicode_escape(symbol)))
def update_new_state(self): if self.log_gui_exploration: print("In new state", unicode_escape(self.state_symbol), unicode_escape(repr(self.state))) state_grammar = self.miner.mine_state_grammar( grammar=self.grammar, state_symbol=self.state_symbol) del state_grammar[START_SYMBOL] del state_grammar[GUIGrammarMiner.START_STATE] self.set_grammar(extend_grammar(self.grammar, state_grammar))
def default_node_attr(dot, nid, symbol, ann): dot.node(repr(nid), dot_escape(unicode_escape(symbol)))