diff src/cTranslator.py @ 6:168d60b03e2c

add dotTranslator(Translator), that can translate from DFA or NFA into Dot-file(Dot is graph generater using tex.)
author ryoma <shinya@firefly.cr.ie.u-ryukyu.ac.jp>
date Fri, 02 Jul 2010 02:43:28 +0900
parents 11fba907c0af
children a28f87d353bb
line wrap: on
line diff
--- a/src/cTranslator.py	Thu Jul 01 00:40:51 2010 +0900
+++ b/src/cTranslator.py	Fri Jul 02 02:43:28 2010 +0900
@@ -1,12 +1,14 @@
 #!/usr/bin/env python
 
-import sys
 from dfareg import Regexp, CallGraph
 from translator import Translator
 
 class CTranslator(Translator):
     """
     CTranslator
+    This Calss 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)
@@ -14,20 +16,22 @@
     >>> CTranslator(string, dfacg).translate()
     >>> CTranslator(string, nfacg).translate()
     """
-    def __init__(self, regexp, cg, stream=sys.stdout):
+    def __init__(self, regexp, cg):
         self.regexp = regexp
         self.cg = cg
-        self.stream = stream
+        self.stream = None
         self.funType = 'void '
         self.callType = ''
         self.breakStatement = '\t\t\tbreak;'
         self.debug = False
 
     def translateFromCallGraph(self):
+        def prefix(string):
+            return "state_"+string
         # self.emit C-source code
         self.emit("#include <stdio.h>\n")
         for k in self.cg.map.iterkeys():
-            self.emit(self.funType + "state_" + k + "(char* s);\n")
+            self.emit(self.funType + prefix(k) + "(char* s);\n")
         self.emit(self.funType + 'accept(char* s);\n')
         self.emit(self.funType + 'reject(char* s);\n')
         self.emit("""
@@ -36,14 +40,14 @@
 \tputs(\"number of state: %d\");
 \tprintf(\"string: %%s\\n\", argv[1]);
 \t%s%s(argv[1]);
-""" % (self.regexp, len(self.cg.states), self.callType, "state_"+self.cg.start))
+""" % (self.regexp, len(self.cg.states), self.callType, prefix(self.cg.start)))
         if self.cg.type is "NFA" : self.emit("\treject(argv[1]);\n")
         self.emit("""
 \treturn 0;
 }\n\n""")
 
         for k, v in self.cg.map.iteritems():
-            self.emit(self.funType + "state_" + k + "(char* s) {\n")
+            self.emit(self.funType + prefix(k) + "(char* s) {\n")
             if self.debug: self.emit("\tprintf(\"state: %s, input: %%s\\n\", s);\n" % (k))
             if self.cg.type is "NFA":
                 sLocal = "s_local"
@@ -51,7 +55,7 @@
                 # epsilon-transition
                 for ss in (ss for i,ss in v.iteritems() if i == ''):
                     for s in ss:
-                        self.emit("\t%s%s(%s);\n" % (self.callType, "state_"+s, sLocal))
+                        self.emit("\t%s%s(%s);\n" % (self.callType, prefix(s), sLocal))
             else:
                 sLocal = "s"
 
@@ -61,7 +65,7 @@
                 if input != '':
                     self.emit("\t\tcase '%s': \n" % (input))
                     for nextState in nextStates:
-                        self.emit("\t\t\t%s%s(%s);\n" % (self.callType, "state_"+nextState, sLocal))
+                        self.emit("\t\t\t%s%s(%s);\n" % (self.callType, prefix(nextState), sLocal))
                     if self.breakStatement != '' : self.emit(self.breakStatement+'\n')
 
             if k in self.cg.accepts :
@@ -81,7 +85,7 @@
 \tprintf(\"\\nstring does not match regexp. \\n\\n\");
 }\n""" % self.funType)
 
-def main():
+def test():
     import doctest
     doctest.testmod()
     '''
@@ -90,4 +94,4 @@
     ct.translate()
     '''
 
-if __name__ == '__main__' : main()
+if __name__ == '__main__' : test()