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