changeset 21:a24acddedf89

rename files to follow PEP. and debug llvm_trnslator.py.
author Ryoma SHINYA <shinya@firefly.cr.ie.u-ryukyu.ac.jp>
date Mon, 05 Jul 2010 19:54:27 +0900
parents de33e445fcc7
children 5149b48b22a9
files src/__init__.py src/cTranslator.py src/c_translator.py src/cbcTranslator.py src/cbc_translator.py src/converter.py src/dotTranslator.py src/dot_translator.py src/llvm_bench.py src/llvm_translator.py
diffstat 10 files changed, 271 insertions(+), 245 deletions(-) [+]
line wrap: on
line diff
--- a/src/__init__.py	Mon Jul 05 18:42:11 2010 +0900
+++ b/src/__init__.py	Mon Jul 05 19:54:27 2010 +0900
@@ -1,2 +1,5 @@
+#!/usr/bin/env python
+
+from dfareg import Regexp
 def compile(regexp):
     return Regexp(regexp)
--- a/src/cTranslator.py	Mon Jul 05 18:42:11 2010 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-#!/Usr/bin/env python
-
-from dfareg import Regexp, CallGraph
-from translator import Translator
-
-class CTranslator(Translator):
-    """CTranslator
-    This Class can translate from DFA or NFA into C source code.
-    DFA: A simple state transition as tail call (also can implement with CbC).
-    NFA: using stack, deepening depth-first search.
-    >>> string = '(A|B)*C'
-    >>> reg = Regexp(string)
-    >>> dfacg = CallGraph(reg.dfa)
-    >>> nfacg = CallGraph(reg.nfa)
-    >>> CTranslator(string, dfacg).translate()
-    >>> CTranslator(string, nfacg).translate()
-    """
-    def __init__(self, regexp, cg):
-        Translator.__init__(self, regexp, cg)
-        self.funType = 'void '
-        self.callType = ''
-        self.breakStatement = '\t\t\tbreak;'
-        self.debug = False
-        if self.cg.type == "DFA":
-            self.name_hash = self.create_name_hash()
-
-    def modify_state_name(self, state_name):
-        if state_name == "accept" or state_name == "reject":
-            return state_name
-        if self.cg.type == "DFA":
-            return "state_"+self.name_hash[state_name]
-        else:
-            return "state_"+state_name
-
-    def emit_accept_state(self):
-        self.emit ("""
-%saccept(char* s) {
-\tprintf(\"\\nstring matches regexp. \\n\\n\");
-}\n""" % self.funType)
-
-    def emit_reject_state(self):
-        self.emit ("""
-%sreject(char* s) {
-\tprintf(\"\\nstring does not match regexp. \\n\\n\");
-}\n""" % self.funType)
-
-    def emit_driver(self):
-        self.emit("""
-int main(int argc, char* argv[]) {
-\tputs(\"regexp: %s\");
-\tputs(\"number of state: %d\");
-\tprintf(\"string: %%s\\n\", argv[1]);
-\t%s%s(argv[1]);
-""" % (self.regexp, len(self.cg.states), self.callType, self.modify_state_name(self.cg.start)))
-        if self.cg.type == "NFA":
-            self.emit("\treject(argv[1]);\n")
-        self.emit("""
-\treturn 0;
-}\n\n""")
-
-    def emit_switch(self, case, default=None):
-        self.emit("\tswitch(s++) {\n")
-
-        for input, next_states in case.iteritems():
-            if input != '':
-                self.emit("\t\tcase '%s': \n" % (input))
-                for next_state in next_states:
-                    self.emit("\t\t\t%s%s(s);\n" % (self.callType, self.modify_state_name(next_state)))
-                if self.breakStatement != '': self.emit(self.breakStatement+'\n')
-
-        if default:
-            self.emit( """\t\tdefault:\n\t\t\t%s%s(NULL);\n""" % (self.callType, default))
-        self.emit("\t}\n")
-
-
-    def emit_state(self, cur_state, transition):
-        self.emit(self.funType + self.modify_state_name(cur_state) + "(char* s) {\n")
-        if self.debug:
-            self.emit("\tprintf(\"state: %s, input: %%s\\n\", s);\n" % (cur_state))
-        if self.cg.type == "NFA":
-            if '' in transition:
-                epsilon_transition = transition.pop('')
-                for n in epsilon_transition:
-                    self.emit("\t%s%s(s);\n" % (self.callType, self.modify_state_name(n)))
-
-        if cur_state in self.cg.accepts:
-            transition['\\0'] = ["accept"]
-
-        if transition:
-            if self.cg.type == "DFA":
-                self.emit_switch(transition, default="reject")
-            else:
-                self.emit_switch(transition)
-        self.emit("}\n\n")
-
-    def emit_initialization(self):
-        self.emit("#include <stdio.h>\n\n")
-        for state in self.cg.map.iterkeys():
-            self.emit(self.funType + self.modify_state_name(state) + "(char* s);\n")
-        self.emit(self.funType + 'accept(char* s);\n')
-        self.emit(self.funType + 'reject(char* s);\n')
-
-    def emit_from_callgraph(self):
-        # self.emit C-source code
-        self.emit_initialization()
-        self.emit_driver()
-
-        for cur_state, transition in self.cg.map.iteritems():
-            self.emit_state(cur_state, transition)
-
-        self.emit_accept_state()
-        self.emit_reject_state()
-
-def test():
-    import doctest
-    doctest.testmod()
-
-if __name__ == '__main__': test()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/c_translator.py	Mon Jul 05 19:54:27 2010 +0900
@@ -0,0 +1,118 @@
+#!/Usr/bin/env python
+
+from dfareg import Regexp, CallGraph
+from translator import Translator
+
+class CTranslator(Translator):
+    """CTranslator
+    This Class can translate from DFA or NFA into C source code.
+    DFA: A simple state transition as tail call (also can implement with CbC).
+    NFA: using stack, deepening depth-first search.
+    >>> string = '(A|B)*C'
+    >>> reg = Regexp(string)
+    >>> dfacg = CallGraph(reg.dfa)
+    >>> nfacg = CallGraph(reg.nfa)
+    >>> CTranslator(string, dfacg).translate()
+    >>> CTranslator(string, nfacg).translate()
+    """
+    def __init__(self, regexp, cg):
+        Translator.__init__(self, regexp, cg)
+        self.funType = 'void '
+        self.callType = ''
+        self.breakStatement = '\t\t\tbreak;'
+        self.debug = False
+        if self.cg.type == "DFA":
+            self.name_hash = self.create_name_hash()
+
+    def modify_state_name(self, state_name):
+        if state_name == "accept" or state_name == "reject":
+            return state_name
+        if self.cg.type == "DFA":
+            return "state_"+self.name_hash[state_name]
+        else:
+            return "state_"+state_name
+
+    def emit_accept_state(self):
+        self.emit ("""
+%saccept(char* s) {
+\tprintf(\"\\nstring matches regexp. \\n\\n\");
+}\n""" % self.funType)
+
+    def emit_reject_state(self):
+        self.emit ("""
+%sreject(char* s) {
+\tprintf(\"\\nstring does not match regexp. \\n\\n\");
+}\n""" % self.funType)
+
+    def emit_driver(self):
+        self.emit("""
+int main(int argc, char* argv[]) {
+\tputs(\"regexp: %s\");
+\tputs(\"number of state: %d\");
+\tprintf(\"string: %%s\\n\", argv[1]);
+\t%s%s(argv[1]);
+""" % (self.regexp, len(self.cg.states), self.callType, self.modify_state_name(self.cg.start)))
+        if self.cg.type == "NFA":
+            self.emit("\treject(argv[1]);\n")
+        self.emit("""
+\treturn 0;
+}\n\n""")
+
+    def emit_switch(self, case, default=None):
+        self.emit("\tswitch(s++) {\n")
+
+        for input, next_states in case.iteritems():
+            if input != '':
+                self.emit("\t\tcase '%s': \n" % (input))
+                for next_state in next_states:
+                    self.emit("\t\t\t%s%s(s);\n" % (self.callType, self.modify_state_name(next_state)))
+                if self.breakStatement != '': self.emit(self.breakStatement+'\n')
+
+        if default:
+            self.emit( """\t\tdefault:\n\t\t\t%s%s(NULL);\n""" % (self.callType, default))
+        self.emit("\t}\n")
+
+
+    def emit_state(self, cur_state, transition):
+        self.emit(self.funType + self.modify_state_name(cur_state) + "(char* s) {\n")
+        if self.debug:
+            self.emit("\tprintf(\"state: %s, input: %%s\\n\", s);\n" % (cur_state))
+        if self.cg.type == "NFA":
+            if '' in transition:
+                epsilon_transition = transition.pop('')
+                for n in epsilon_transition:
+                    self.emit("\t%s%s(s);\n" % (self.callType, self.modify_state_name(n)))
+
+        if cur_state in self.cg.accepts:
+            transition['\\0'] = ["accept"]
+
+        if transition:
+            if self.cg.type == "DFA":
+                self.emit_switch(transition, default="reject")
+            else:
+                self.emit_switch(transition)
+        self.emit("}\n\n")
+
+    def emit_initialization(self):
+        self.emit("#include <stdio.h>\n\n")
+        for state in self.cg.map.iterkeys():
+            self.emit(self.funType + self.modify_state_name(state) + "(char* s);\n")
+        self.emit(self.funType + 'accept(char* s);\n')
+        self.emit(self.funType + 'reject(char* s);\n')
+
+    def emit_from_callgraph(self):
+        # self.emit C-source code
+        self.emit_initialization()
+        self.emit_driver()
+
+        for cur_state, transition in self.cg.map.iteritems():
+            self.emit_state(cur_state, transition)
+
+        self.emit_accept_state()
+        self.emit_reject_state()
+
+def test():
+    import doctest
+    doctest.testmod()
+
+if __name__ == '__main__': test()
--- a/src/cbcTranslator.py	Mon Jul 05 18:42:11 2010 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-
-from dfareg import Regexp, CallGraph
-from cTranslator import CTranslator
-
-class CbCTranslateExeption(Exception):
-    pass
-
-class CbCTranslator(CTranslator):
-    """
-    CbCTranslator
-    >>> string = \"(A|B)*C\"
-    >>> reg = Regexp(string)
-    >>> dfacg = CallGraph(reg.dfa)
-    >>> ct = CbCTranslator(string, dfacg)
-    >>> ct.translate()
-    >>> ct.debug = True
-    >>> ct.translate()
-    """
-    def __init__(self, regexp, cg):
-        if cg.type == "NFA": raise CbCTranslateExeption("can't translate CbC from NFA")
-        CTranslator.__init__(self, regexp, cg)
-        self.funType = '__code '
-        self.callType = 'goto '
-        self.breakStatement = ''
-
-def test():
-    import doctest
-    doctest.testmod()
-
-if __name__ == '__main__' : test()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cbc_translator.py	Mon Jul 05 19:54:27 2010 +0900
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+from dfareg import Regexp, CallGraph
+from c_translator import CTranslator
+
+class CbCTranslateExeption(Exception):
+    pass
+
+class CbCTranslator(CTranslator):
+    """
+    CbCTranslator
+    >>> string = \"(A|B)*C\"
+    >>> reg = Regexp(string)
+    >>> dfacg = CallGraph(reg.dfa)
+    >>> ct = CbCTranslator(string, dfacg)
+    >>> ct.translate()
+    >>> ct.debug = True
+    >>> ct.translate()
+    """
+    def __init__(self, regexp, cg):
+        if cg.type == "NFA": raise CbCTranslateExeption("can't translate CbC from NFA")
+        CTranslator.__init__(self, regexp, cg)
+        self.funType = '__code '
+        self.callType = 'goto '
+        self.breakStatement = ''
+
+def test():
+    import doctest
+    doctest.testmod()
+
+if __name__ == '__main__' : test()
--- a/src/converter.py	Mon Jul 05 18:42:11 2010 +0900
+++ b/src/converter.py	Mon Jul 05 19:54:27 2010 +0900
@@ -2,9 +2,9 @@
 
 import sys
 from dfareg import Regexp, CallGraph
-from cTranslator import CTranslator
-from cbcTranslator import CbCTranslator
-from dotTranslator import DotTranslator
+from c_translator import CTranslator
+from cbc_translator import CbCTranslator
+from dot_translator import DotTranslator
 from llvm_translator import LLVMTranslator
 from optparse import OptionParser
 
--- a/src/dotTranslator.py	Mon Jul 05 18:42:11 2010 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-
-import re
-from translator import Translator
-from dfareg import CallGraph, 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)
-    >>> dfacg = CallGraph(reg.dfa)
-    >>> nfacg = CallGraph(reg.nfa)
-    >>> DotTranslator(string, dfacg).translate()
-    >>> DotTranslator(string, nfacg).translate()
-    """
-    def __init__(self, regexp, cg):
-        Translator.__init__(self, regexp, cg)
-        if self.cg.type == "DFA":
-            self.name_hash = self.create_name_hash()
-
-    def modify_state_name(self, state_name):
-        if self.cg.type == "DFA":
-            return "s"+self.name_hash[state_name]
-        else:
-            return "s"+state_name
-
-    def emit_from_callgraph(self):
-        self.emit('''
-digraph G{
-\td2tdocpreamble = "\\usetikzlibrary{automata}";
-\td2tfigpreamble = "\\tikzstyle{every state}= \\
-\t[draw=blue!50,very thick,shape=circle, fill=blue!20]";
-\tnode [style="state"];
-\tedge [lblstyle="fill=blue!20", style="arrows=->", topath="bend left"];
-''')
-
-        self.emit("\t%s [style=\"state, initial\"]\n" % (self.modify_state_name(self.cg.start)))
-        for accept in self.cg.accepts:
-            self.emit("\t%s [style=\"state, accepting\"]\n" % (self.modify_state_name(accept)))
-
-        for cur_state, trans in self.cg.map.iteritems():
-            for input, next_states in trans.iteritems():
-                if input == "" : input = "$\\varepsilon$"
-                for next_state in next_states:
-                    self.emit("\t%s -> %s [texlbl=\"%s\"]\n"
-                              % (self.modify_state_name(cur_state), self.modify_state_name(next_state), input))
-
-        self.emit("}")
-
-
-def test():
-    import doctest
-    doctest.testmod()
-    '''
-    reg = Regexp("(A|B)*C")
-    ct = CTranslator(reg.regexp, CallGraph(reg.dfa))
-    ct.translate()
-    '''
-
-if __name__ == '__main__' : test()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dot_translator.py	Mon Jul 05 19:54:27 2010 +0900
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+import re
+from translator import Translator
+from dfareg import CallGraph, 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)
+    >>> dfacg = CallGraph(reg.dfa)
+    >>> nfacg = CallGraph(reg.nfa)
+    >>> DotTranslator(string, dfacg).translate()
+    >>> DotTranslator(string, nfacg).translate()
+    """
+    def __init__(self, regexp, cg):
+        Translator.__init__(self, regexp, cg)
+        if self.cg.type == "DFA":
+            self.name_hash = self.create_name_hash()
+
+    def modify_state_name(self, state_name):
+        if self.cg.type == "DFA":
+            return "s"+self.name_hash[state_name]
+        else:
+            return "s"+state_name
+
+    def emit_from_callgraph(self):
+        self.emit('''
+digraph G{
+\td2tdocpreamble = "\\usetikzlibrary{automata}";
+\td2tfigpreamble = "\\tikzstyle{every state}= \\
+\t[draw=blue!50,very thick,shape=circle, fill=blue!20]";
+\tnode [style="state"];
+\tedge [lblstyle="fill=blue!20", style="arrows=->", topath="bend left"];
+''')
+
+        self.emit("\t%s [style=\"state, initial\"]\n" % (self.modify_state_name(self.cg.start)))
+        for accept in self.cg.accepts:
+            self.emit("\t%s [style=\"state, accepting\"]\n" % (self.modify_state_name(accept)))
+
+        for cur_state, trans in self.cg.map.iteritems():
+            for input, next_states in trans.iteritems():
+                if input == "" : input = "$\\varepsilon$"
+                for next_state in next_states:
+                    self.emit("\t%s -> %s [texlbl=\"%s\"]\n"
+                              % (self.modify_state_name(cur_state), self.modify_state_name(next_state), input))
+
+        self.emit("}")
+
+
+def test():
+    import doctest
+    doctest.testmod()
+    '''
+    reg = Regexp("(A|B)*C")
+    ct = CTranslator(reg.regexp, CallGraph(reg.dfa))
+    ct.translate()
+    '''
+
+if __name__ == '__main__' : test()
--- a/src/llvm_bench.py	Mon Jul 05 18:42:11 2010 +0900
+++ b/src/llvm_bench.py	Mon Jul 05 19:54:27 2010 +0900
@@ -4,15 +4,16 @@
 from optparse import OptionParser
 from timeit import Timer
 from dfareg import Regexp
-from reg2llvm import RegLLVM
+from dfareg import Regexp, CallGraph
+from llvm_translator import LLVMTranslator
 
 myusage = "%prog [-O] [-p] [-s string] [-r regexp] [-E]"
 psr = OptionParser(usage=myusage)
-psr.add_option("-O", action="store_true", dest="optimizeFlag", default=False, help="optimimzation")
-psr.add_option("-L", action="store_true", dest="implLabel", default=False, help="impliment with label")
-psr.add_option("-E", action="store_true", dest="executeFlag", default=False, help="execute Module")
-psr.add_option("-p", action="store_true", dest="printFlag", default=False, help="print module")
-psr.add_option("-g", action="store_true", dest="dumpFlag", default=False, help="add debug stmt to module")
+psr.add_option("-O", action="store_true", dest="optimize", default=False, help="optimimzation")
+psr.add_option("-L", action="store_true", dest="label", default=False, help="impliment with label")
+psr.add_option("-E", action="store_true", dest="execute", default=False, help="execute Module")
+psr.add_option("-p", action="store_true", dest="print_", default=False, help="print module")
+psr.add_option("-g", action="store_true", dest="debug", default=False, help="add debug stmt to module")
 psr.add_option("-n", action="store", type="int", dest="number", default=1000, help="number of eval", metavar="INT")
 psr.add_option("-r", action="store", type="string", dest="regexp", default="(A|B)*C", help="regexp", metavar="FILE")
 psr.add_option("-s", action="store", type="string", dest="string", default="A"+"B"*500+"C", help="string", metavar="FILE")
@@ -20,12 +21,17 @@
 
 print "regexp = \"%s\", string = \"%s\", loop = %d" % (opts.regexp, opts.string, opts.number)
 
-regLLVM = RegLLVM("regllvm", opts.regexp, opts.string, opts.implLabel, opts.optimizeFlag, opts.dumpFlag)
+reg = Regexp(opts.regexp)
+dfacg = CallGraph(reg.dfa)
+llvmt = LLVMTranslator(reg.regexp, dfacg)
+llvmt.string = opts.string
+llvmt.debug = opts.debug
+llvmt.optimize = opts.optimize
 
-if (opts.printFlag):   regLLVM.print_module()
+if opts.print_: llvmt.translate()
 
-if (opts.executeFlag):
-    print "LLVM  :", Timer(setup='from __main__ import regLLVM', stmt='regLLVM.execute()').timeit(opts.number)
+if opts.execute:
+    print "LLVM  :", Timer(setup='from __main__ import llvmt', stmt='llvmt.execute()').timeit(opts.number)
 
     reg = re.compile("^%s$" % opts.regexp)
     print "re    :", Timer(setup='from __main__ import reg', stmt='reg.search("%s")' % opts.string).timeit(opts.number)
--- a/src/llvm_translator.py	Mon Jul 05 18:42:11 2010 +0900
+++ b/src/llvm_translator.py	Mon Jul 05 19:54:27 2010 +0900
@@ -14,6 +14,7 @@
     >>> reg = Regexp(string)
     >>> dfacg = CallGraph(reg.dfa)
     >>> lt = LLVMTranslator(string, dfacg)
+    >>> lt.debug = True
     >>> lt.translate()
     >>> isinstance(lt.execute(), llvm.ee.GenericValue)
     True
@@ -29,14 +30,13 @@
 
     def __init__(self, regexp, cg): #(self, modName, regexp, string, self.impl_label, optimized, debug):
         Translator.__init__(self, regexp, cg)
-        self.mod = Module.new(self.cg.type)
         self.optimize = False
         self.debug = False
         self.impl_label = False
-        self.matchp_str = self.new_str_const("ABC")
-        self.debug_str = self.new_str_const("state: %s, arg: %c(int %d)\n")
+        self.string = "ABC"
         if self.cg.type == "DFA":
             self.name_hash = self.create_name_hash()
+        self.compiled = False
 
     def modify_state_name(self, state_name):
         if self.cg.type == "DFA":
@@ -44,7 +44,10 @@
         else:
             return state_name
 
-    def emit_from_callgraph(self):
+    def _compile(self):
+        self.llvm_module = Module.new(self.cg.type)
+        self.matchp_str = self.new_str_const(self.string)
+        self.debug_str = self.new_str_const("state: %s, arg: %c(int %d)\n")
         def optional_func_decl(fun):
             fun.calling_convertion = CC_X86_FASTCALL
             fun.args[0].name = "index"
@@ -53,7 +56,7 @@
             optional_func_decl(state)
 
         state_ref = dict()
-        main = self.mod.add_function(
+        main = self.llvm_module.add_function(
             Type.function(self.int_t, (self.int_t,)), "main")
         optional_func_decl(main)
         main_entry = main.append_basic_block("entry")
@@ -66,10 +69,10 @@
             Builder.new(reject_state).free(index_ptr)
         else:
             # Create function - accept and reject (final state).
-            accept_state = self.mod.add_function(
+            accept_state = self.llvm_module.add_function(
                 Type.function(self.int_t, (self.int_t,)), "accept")
             optional_func_decl(accept_state)
-            reject_state = self.mod.add_function(
+            reject_state = self.llvm_module.add_function(
                 Type.function(self.int_t, (self.int_t,)), "reject")
             optional_func_decl(reject_state)
 
@@ -84,7 +87,7 @@
                 state_ref[state] = label
         else:
             for state in self.cg.map.iterkeys():
-                fun = self.mod.add_function(
+                fun = self.llvm_module.add_function(
                     Type.function(self.int_t, (self.int_t,)), state)
                 optional_func_decl(fun)
                 state_ref[state] = fun
@@ -92,13 +95,12 @@
         # emit instructions
         if (self.impl_label): emit = Builder.new(accept_state)
         else:            emit = Builder.new(accept_state.append_basic_block("entry"))
-
-        self.emit_call_printf(emit, "%s does match regexp\n", self.gep_first(emit, self.matchp_str))
+        if self.debug: self.emit_call_printf(emit, "%s does match regexp\n", self.gep_first(emit, self.matchp_str))
         emit.ret(self.const_one)
 
         if (self.impl_label): emit = Builder.new(reject_state)
         else:            emit = Builder.new(reject_state.append_basic_block("entry"))
-        self.emit_call_printf(emit, "%s does not match regexp\n", self.gep_first(emit, self.matchp_str))
+        if self.debug: self.emit_call_printf(emit, "%s does not match regexp\n", self.gep_first(emit, self.matchp_str))
         emit.ret(self.const_zero)
 
         if (self.impl_label):
@@ -115,6 +117,8 @@
                 char = emit.load(ptr)
                 si = emit.switch(char, state_ref['reject'], len(transition))
                 local_label = 0
+                if state in self.cg.accepts:
+                    transition['\\0'] = "accept"
                 for case, next_states in transition.iteritems():
                     bb = main.append_basic_block("%s_case%d" % (state, local_label))   #create default bb
                     emit = Builder.new(bb)
@@ -124,6 +128,8 @@
         else:
             for state, transition in self.cg.map.iteritems():
                 cases = dict()
+                if state in self.cg.accepts:
+                    transition['\\0'] = ["accept"]
                 for case, next_states in transition.iteritems():
                     cases[self.char_const(case)] = state_ref[next_states[0]]
                 state_fun = state_ref[state]
@@ -152,13 +158,20 @@
             ret = emit.call(state_ref[self.cg.start], (main.args[0],))
             emit.ret(ret)
 
-        self.mp = ModuleProvider.new(self.mod)
+        self.mp = ModuleProvider.new(self.llvm_module)
         if (self.optimize): self.do_optimize()
         self.ee = ExecutionEngine.new(self.mp)
         self.main = main
-        self.emit(str(self.mod))
+        self.compiled = True
+
+    def emit_from_callgraph(self):
+        if not self.compiled:
+            self._compile()
+        self.emit(str(self.llvm_module))
 
     def get_execution_engine(self):
+        if not self.compiled:
+            self._compile()
         return self.ee
 
     def do_optimize(self):
@@ -166,7 +179,7 @@
         pm = PassManager.new()
         pm.add(TargetData.new(''))
         pm.add(PASS_FUNCTION_INLINING)
-        pm.run(self.mod)
+        pm.run(self.llvm_module)
         fp = FunctionPassManager.new(self.mp)
         fp.add(TargetData.new(''))
         fp.add(PASS_BLOCK_PLACEMENT)
@@ -175,19 +188,23 @@
         fp.add(PASS_AGGRESSIVE_DCE)
         fp.add(PASS_DEAD_INST_ELIMINATION)
         fp.add(PASS_DEAD_CODE_ELIMINATION)
-        for fun in self.mod.functions:
+        for fun in self.llvm_module.functions:
             fp.run(fun)
 
     def print_module(self):
-        print self.mod
+        if not self.compiled:
+            self._compile()
+        print self.llvm_module
 
     def execute(self):
+        if not self.compiled:
+            self._compile()
         return self.ee.run_function(self.main,
                                     (GenericValue.int(self.int_t, 0),))
 
     def new_str_const(self, val):
         '''create string(array of int) as a global value '''
-        str = self.mod.add_global_variable(Type.array(self.char_t, len(val) + 1), "")
+        str = self.llvm_module.add_global_variable(Type.array(self.char_t, len(val) + 1), "")
         str.initializer = Constant.stringz(val)
         return str
 
@@ -208,9 +225,9 @@
     def emit_call_printf(self, emit, string, *args):
         '''emit libc printf function call instruction'''
         try:
-            printf = self.mod.get_function_named("printf")
+            printf = self.llvm_module.get_function_named("printf")
         except llvm.LLVMException:
-            printf = self.mod.add_function(
+            printf = self.llvm_module.add_function(
                 Type.function(Type.void(),
                               (Type.pointer(self.char_t, 0),), 1), "printf")
         if isinstance(string, str):