| 1 |
1 |
import re |
| 2 |
2 |
|
|
3 |
# Constant |
|
4 |
MAX_RECURSION_DEPTH = 25 |
|
5 |
|
| 3 |
6 |
def template(rmap, **kwargs): |
|
7 |
|
|
8 |
tmp_symb_id = 0 |
|
9 |
|
|
10 |
# 1) Deal with the input. Could be either a string or file |
| 4 |
11 |
FILE = 'file' |
| 5 |
12 |
STRING = 'string' |
| 6 |
13 |
|
| 17 |
24 |
else: |
| 18 |
25 |
assert(False) |
| 19 |
26 |
|
| 20 |
|
ph_re = re.compile('@\{(\w+)\}') |
| 21 |
|
ph_list = ph_re.findall(text) |
|
27 |
# 2) Replace until we cannot replace no more. |
|
28 |
symb_re = re.compile('\@\{(\w+?)\}') |
|
29 |
repeat_re = re.compile('\@\@\[(.+?)\]') |
|
30 |
for i in xrange(MAX_RECURSION_DEPTH): |
|
31 |
new_text = text |
| 22 |
32 |
|
| 23 |
|
for ph in ph_list: |
| 24 |
|
if ph in rmap: |
| 25 |
|
replace = rmap[ph] |
| 26 |
|
else: |
| 27 |
|
replace = '' |
| 28 |
|
text = re.sub('@\{' + ph + '\}', replace, text) |
| 29 |
|
return text; |
|
33 |
# 2.1) Get occurances list |
|
34 |
symb_list = symb_re.findall(text) |
|
35 |
repeat_list = repeat_re.findall(text) |
|
36 |
# 2.3) Process all repeated symbols |
|
37 |
for rep in repeat_list: |
|
38 |
# 2.3.1) Parse the rule |
|
39 |
(rule, body) = rep.split(':') |
|
40 |
if '@' in body: |
|
41 |
continue |
|
42 |
body = body.split(',') |
|
43 |
replace = [] |
|
44 |
# 2.3.2) Build the unrolling |
|
45 |
for i in xrange(len(body)): |
|
46 |
tmp_symb = 'TMP_{0}_{1}'.format(tmp_symb_id, i) |
|
47 |
tmp_symb_id += 1 |
|
48 |
rmap[tmp_symb] = body[i] |
|
49 |
replace.append(re.sub('@', '@{' + tmp_symb + '}', rule)) |
|
50 |
# 2.3.3) Substitute |
|
51 |
new_text = re.sub(re.escape('@@[' + rep + ']'),\ |
|
52 |
'\n'.join(replace),\ |
|
53 |
new_text) |
|
54 |
# 2.2) Process all simple sybmols |
|
55 |
for symb in symb_list: |
|
56 |
if symb in rmap: |
|
57 |
replace = rmap[symb] |
|
58 |
else: |
|
59 |
print "Cannot find definition for @{" + symb + "}" |
|
60 |
replace = '#BAD SYMBOL#' |
|
61 |
new_text = re.sub('@\{' + symb + '\}', replace, new_text) |
|
62 |
|
|
63 |
# Unchanged? |
|
64 |
if new_text == text: |
|
65 |
return text |
|
66 |
text = new_text |
|
67 |
return text + '\n#MAX DEPTH#'; |
| 30 |
68 |
|
| 31 |
69 |
def rewrite(rmap, infile, outfile): |
| 32 |
70 |
text = template(rmap, file=infile) |
| 20 |
20 |
</generator> |
| 21 |
21 |
|
| 22 |
22 |
<so> |
| 23 |
|
<pao_h>templates/pao_h.tmpl</pao_h> |
| 24 |
|
<pao_cpp>templates/pao_cpp.tmpl</pao_cpp> |
|
23 |
<pao_h_tmpl>templates/pao_h.tmpl</pao_h_tmpl> |
|
24 |
<pao_cpp_tmpl>templates/pao_cpp.tmpl</pao_cpp_tmpl> |
|
25 |
<pao_h_gen>gen/gen_pao.h</pao_h_gen> |
|
26 |
<pao_cpp_gen>gen/gen_pao.cpp</pao_cpp_gen> |
| 25 |
27 |
<pao_args> |
| 26 |
|
<pao_header_file>gen_pao.h</pao_header_file> |
| 27 |
|
<pao_body_file>gen_pao.h</pao_body_file> |
| 28 |
28 |
<pao_class>TestPaoClass</pao_class> |
| 29 |
29 |
<pao_state_datatype>int i;</pao_state_datatype> |
| 30 |
30 |
<pao_add_func>this->i++;</pao_add_func> |
| 31 |
31 |
<pao_merge_func>this->i += add_agg->i;</pao_merge_func> |
| 32 |
32 |
</pao_args> |
| 33 |
|
<mapper_h>templates/mapper_h.tmpl</mapper_h> |
| 34 |
|
<mapper_cpp>templates/mapper_cpp.tmpl</mapper_cpp> |
|
33 |
<mapper_h_tmpl>templates/mapper_h.tmpl</mapper_h_tmpl> |
|
34 |
<mapper_cpp_tmpl>templates/mapper_cpp.tmpl</mapper_cpp_tmpl> |
|
35 |
<mapper_h_gen>gen/gen_mapper.h</mapper_h_gen> |
|
36 |
<mapper_cpp_gen>gen/gen_mapper.cpp</mapper_cpp_gen> |
| 35 |
37 |
<mapper_args> |
| 36 |
38 |
<mapper_class>TestMapperClass</mapper_class> |
| 37 |
39 |
<mapper_state_datatype> </mapper_state_datatype> |
| 38 |
40 |
<mapper_map_func>sleep(1);</mapper_map_func> |
| 39 |
|
<mapper_part_func> </mapper_part_func> |
|
41 |
<mapper_part_func>long key_id = atoi(key); |
|
42 |
return key_id % @{partition_number};</mapper_part_func> |
|
43 |
<mapper_header_list>stdlib.h,stdio.h</mapper_header_list> |
|
44 |
<partition_number>10</partition_number> |
| 40 |
45 |
</mapper_args> |
| 41 |
46 |
</so> |
|
47 |
|
|
48 |
|
|
49 |
|
| 42 |
50 |
</document> |
| 3 |
3 |
import sys |
| 4 |
4 |
import MicroTemplate as mt |
| 5 |
5 |
|
| 6 |
|
# Main |
| 7 |
6 |
if len(sys.argv) != 2: |
| 8 |
7 |
print 'Usage: python generator.py <XML config file>' |
| 9 |
8 |
quit() |
| 10 |
9 |
|
| 11 |
|
# Parse the XML file |
|
10 |
# 1) Parse the XML file |
| 12 |
11 |
dom = xml.parse(sys.argv[1]) |
| 13 |
12 |
|
| 14 |
|
# Generate the PAO file |
| 15 |
|
pao_h_template = getText(dom, ['pao_h']) |
| 16 |
|
pao_cpp_template = getText(dom, ['pao_cpp']) |
|
13 |
# 2) Generate the PAO file |
|
14 |
# 2.1) Get file names |
|
15 |
pao_h_tmpl = getText(dom, ['pao_h_tmpl']) |
|
16 |
pao_cpp_tmpl = getText(dom, ['pao_cpp_tmpl']) |
|
17 |
pao_h_gen = getText(dom, ['pao_h_gen']) |
|
18 |
pao_cpp_gen = getText(dom, ['pao_cpp_gen']) |
|
19 |
# 2.2) Get the substitution list |
| 17 |
20 |
pao_sub = getAttrList(dom, ['pao_args']) |
| 18 |
|
pao_sub['pao_header'] = 'gen_pao.h' |
| 19 |
|
mt.rewrite(pao_sub, pao_h_template, 'gen_pao.h') |
| 20 |
|
mt.rewrite(pao_sub, pao_cpp_template, 'gen_pao.cpp') |
|
21 |
# 2.3) Force file naming |
|
22 |
pao_sub['pao_header'] = pao_h_gen |
|
23 |
# 2.4) Sub and write |
|
24 |
mt.rewrite(pao_sub, pao_h_tmpl, pao_h_gen) |
|
25 |
mt.rewrite(pao_sub, pao_cpp_tmpl, pao_cpp_gen) |
| 21 |
26 |
|
| 22 |
|
# Generate the Mapper file |
| 23 |
|
mapper_h_template = getText(dom, ['mapper_h']) |
| 24 |
|
mapper_cpp_template = getText(dom, ['mapper_cpp']) |
|
27 |
# 3) Generate the Mapper file |
|
28 |
# 3.1) Get file names |
|
29 |
mapper_h_tmpl = getText(dom, ['mapper_h_tmpl']) |
|
30 |
mapper_cpp_tmpl = getText(dom, ['mapper_cpp_tmpl']) |
|
31 |
mapper_h_gen = getText(dom, ['mapper_h_gen']) |
|
32 |
mapper_cpp_gen = getText(dom, ['mapper_cpp_gen']) |
|
33 |
# 3.2) Get substitution list |
| 25 |
34 |
mapper_sub = getAttrList(dom, ['mapper_args']) |
| 26 |
|
mapper_sub['mapper_header'] = 'gen_mapper.h' |
| 27 |
|
mt.rewrite(mapper_sub, mapper_h_template, 'gen_mapper.h') |
| 28 |
|
mt.rewrite(mapper_sub, mapper_cpp_template, 'gen_mapper.cpp') |
|
35 |
# 3.3) Force file naming |
|
36 |
mapper_sub['mapper_header'] = mapper_h_gen |
|
37 |
mt.rewrite(mapper_sub, mapper_h_tmpl, mapper_h_gen) |
|
38 |
mt.rewrite(mapper_sub, mapper_cpp_tmpl, mapper_cpp_gen) |