view pyrect/translator/dot_translator.py @ 55:4ae288b37591

ddd analyzer. analyzer can analyzing to regexp max-length.
author Ryoma SHINYA <shinya@firefly.cr.ie.u-ryukyu.ac.jp>
date Tue, 26 Oct 2010 16:37:43 +0900
parents abb0691e792a
children 20a1c25d1fc9
line wrap: on
line source

#!/usr/bin/env python

import re

from translator import Translator
from pyrect.regexp import Regexp

class DotTranslator(Translator):
    """
    DotToranslator
    This Class can translate from DFA or NFA into Dot
    Dot is Graph-generater using TeX.
    --code/graph/makepdf.sh is generate graph script.
    >>> string = \"(A|B)*C\"
    >>> reg = Regexp(string)
    >>> DotTranslator(reg, 'DFA').translate()
    >>> DotTranslator(reg, 'NFA').translate()
    """
    def __init__(self, regexp, fa="DFA"):
        Translator.__init__(self, regexp)
        if fa == "NFA":
            self.cg = regexp.nfacg
        else:
            self.cg = regexp.dfacg
        self.fill_color = "lightsteelblue1"
        self.frame_color = "navyblue"

    def state_name(self, name):
        return "q"+name

    def emit_from_callgraph(self):
        color = "fillcolor=%s, style=filled, color = %s" % (self.fill_color, self.frame_color)
        self.emit('digraph G{'), self.indent()
        self.emit(  'rankdir=LR')
        self.emit(  'regex [shape=plaintext, label="%s"]' % self.regexp.regexp)

        # emit transition
        for state in self.cg.states:
            if state in self.cg.accepts:
                self.emit("%s [shape=doublecircle, %s]" % (self.state_name(state), color))
            else:
                self.emit("%s [shape=circle, %s]" % (self.state_name(state), color))

        # edge to start state
        self.emit("start [shape=point]")
        self.emit("start -> %s" % self.state_name(self.cg.start))
        self.emit()

        for cur_state, trans in self.cg.map.iteritems():
            for input, next_states in trans.iteritems():
                if self.cg.type == "DFA":
                    next_states = [next_states]
                for next_state in next_states:
                    self.emit("%s -> %s [label=\"%s\"]"
                              % (self.state_name(cur_state), self.state_name(next_state), input))
        self.dedent()
        self.emit("}", 2)

def test():
    import doctest
    doctest.testmod()
    '''
    reg = Regexp("(A|B)*C")
    ct = CTranslator(reg.regexp, CallGraph(reg.dfa))
    ct.translate()
    '''

if __name__ == '__main__' : test()