comparison src/cTranslator.py @ 5:11fba907c0af

add Translater(object), that can translate C/CbC source code from NFA or DFA(CbC can translate from DFA). and refactoring, refactoring, refactoring... not implimented translation-DotFile.
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Thu, 01 Jul 2010 00:40:51 +0900
parents
children 168d60b03e2c
comparison
equal deleted inserted replaced
4:7e47839a54ad 5:11fba907c0af
1 #!/usr/bin/env python
2
3 import sys
4 from dfareg import Regexp, CallGraph
5 from translator import Translator
6
7 class CTranslator(Translator):
8 """
9 CTranslator
10 >>> string = \"(A|B)*C\"
11 >>> reg = Regexp(string)
12 >>> dfacg = CallGraph(reg.dfa)
13 >>> nfacg = CallGraph(reg.nfa)
14 >>> CTranslator(string, dfacg).translate()
15 >>> CTranslator(string, nfacg).translate()
16 """
17 def __init__(self, regexp, cg, stream=sys.stdout):
18 self.regexp = regexp
19 self.cg = cg
20 self.stream = stream
21 self.funType = 'void '
22 self.callType = ''
23 self.breakStatement = '\t\t\tbreak;'
24 self.debug = False
25
26 def translateFromCallGraph(self):
27 # self.emit C-source code
28 self.emit("#include <stdio.h>\n")
29 for k in self.cg.map.iterkeys():
30 self.emit(self.funType + "state_" + k + "(char* s);\n")
31 self.emit(self.funType + 'accept(char* s);\n')
32 self.emit(self.funType + 'reject(char* s);\n')
33 self.emit("""
34 int main(int argc, char* argv[]) {
35 \tputs(\"regexp: %s\");
36 \tputs(\"number of state: %d\");
37 \tprintf(\"string: %%s\\n\", argv[1]);
38 \t%s%s(argv[1]);
39 """ % (self.regexp, len(self.cg.states), self.callType, "state_"+self.cg.start))
40 if self.cg.type is "NFA" : self.emit("\treject(argv[1]);\n")
41 self.emit("""
42 \treturn 0;
43 }\n\n""")
44
45 for k, v in self.cg.map.iteritems():
46 self.emit(self.funType + "state_" + k + "(char* s) {\n")
47 if self.debug: self.emit("\tprintf(\"state: %s, input: %%s\\n\", s);\n" % (k))
48 if self.cg.type is "NFA":
49 sLocal = "s_local"
50 self.emit("\tchar* %s = s;\n" % (sLocal))
51 # epsilon-transition
52 for ss in (ss for i,ss in v.iteritems() if i == ''):
53 for s in ss:
54 self.emit("\t%s%s(%s);\n" % (self.callType, "state_"+s, sLocal))
55 else:
56 sLocal = "s"
57
58 self.emit("\tswitch(*%s++) {\n" % (sLocal))
59
60 for input, nextStates in v.iteritems():
61 if input != '':
62 self.emit("\t\tcase '%s': \n" % (input))
63 for nextState in nextStates:
64 self.emit("\t\t\t%s%s(%s);\n" % (self.callType, "state_"+nextState, sLocal))
65 if self.breakStatement != '' : self.emit(self.breakStatement+'\n')
66
67 if k in self.cg.accepts :
68 self.emit( """\t\tcase '\\0':\n\t\t\t%saccept(%s);\n%s\n""" % (self.callType, sLocal, self.breakStatement))
69 if self.cg.type is "DFA":
70 self.emit("\t\tdefault: %sreject(%s);\n\t}\n" % (self.callType, sLocal))
71 else:
72 self.emit("\t}\n")
73 self.emit("}\n\n")
74
75 self.emit ("""
76 %saccept(char* s) {
77 \tprintf(\"\\nstring matches regexp. \\n\\n\");
78 }\n""" % self.funType)
79 self.emit ("""
80 %sreject(char* s) {
81 \tprintf(\"\\nstring does not match regexp. \\n\\n\");
82 }\n""" % self.funType)
83
84 def main():
85 import doctest
86 doctest.testmod()
87 '''
88 reg = Regexp("(A|B)*C")
89 ct = CTranslator(reg.regexp, CallGraph(reg.dfa))
90 ct.translate()
91 '''
92
93 if __name__ == '__main__' : main()