7 import xml.etree.ElementTree
10 def get_text(root, i):
13 text = root.text if i == 0 else root[i - 1].tail
14 return '' if text is None else text
16 def set_text(root, i, text):
24 root[i - 1].tail = text
26 def my_rstrip(text, indent):
28 while i > 0 and text[i - 1] == '}':
31 while text[i - 1] != '{':
35 return text[:i].rstrip('\t ') + indent + text[i:]
37 def c_to_python(context, text):
39 lex_yy.yy_buffer_stack = [lex_yy.YYBufferState()]
42 root = y_tab.yyparse(t_def.AST.TranslationUnit)
44 root.translate_translation_unit(context)
45 return ''.join(context.lines)
47 root = xml.etree.ElementTree.parse(sys.stdin).getroot()
49 context = t_def.Context()
52 with open('a.c', 'w') as fout:
53 def extract(i, parent, indent):
54 if i.tag == 'AST_Section1Or2_CodeBlock':
56 assert node.tag == 'AST_Text'
57 if parent.tag == 'AST_Section1':
62 elif i.tag == 'AST_Section2_Rule_Action':
63 if len(i) == 0: # continued actions
64 assert parent.tag == 'AST_Section2_Rule'
65 assert len(parent) == 3
69 get_text(parent, 2).rstrip('\t ') + ' /*COLUMN32*/ '
73 assert node.tag == 'AST_Text'
75 elif i.tag == 'AST_Section3':
84 get_text(i, 0).lstrip()
86 for j in range(1, len(i)):
90 '{0:s}\n{1:s}'.format(
91 get_text(i, j).strip(),
92 '\n' if j == 2 else ''
98 get_text(i, len(i)).lstrip()
100 elif i.tag == 'AST_Section1' or i.tag == 'AST_Section2':
101 # kludge, concatenate single line codeblocks to see overall meaning,
102 # hopefully we can make the scanner do this itself in Python version
105 if i[j].tag == 'AST_Section1Or2_CodeBlock':
107 pre_delimiter = get_text(i[j], 0)
108 post_delimiter = get_text(i[j], 1)
111 len(get_text(i, k).strip()) == 0 and
112 i[k].tag == 'AST_Section1Or2_CodeBlock' and
113 get_text(i[k], 0) == pre_delimiter and
114 get_text(i[k], 1) == post_delimiter
120 ''.join([get_text(i[l][0], 0) for l in range(j, k)])
125 i.tag == 'AST_Section2_Rule' or
126 i.tag == 'AST_Section2_Rule_FLexRule'
128 set_text(i, 0, get_text(i, 0).lstrip('\t '))
129 elif i.tag == 'AST_Section2_CompoundRule':
134 indent + get_text(i, 0).lstrip('\t ')
136 for j in range(1, len(i)):
140 #get_text(i, j).rstrip('\t ') + child_indent
141 my_rstrip(get_text(i, j), child_indent)
146 indent + get_text(i, len(i)).lstrip('\t ')
149 extract(j, i, child_indent)
151 assert len(node) == 0
152 text = get_text(node, 0)
156 k = text.index('\n', j) + 1
161 (line[:10] == '#include <' and line[-4:] == '.h>\n') or
162 (line[:10] == '#include "' and line[-4:] == '.h"\n')
164 name = line[10:-4].replace('/', '.')
171 @@@ IMPORT END\n'''.format(
172 line[10:-4].replace('/', '.'),
180 actions.append((node, parent, indent, initial))
181 extract(root, None, '')
184 'gcc{0:s} -E a.c >a.i'.format(
185 ''.join([' "{0:s}"'.format(i) for i in sys.argv[1:]])
188 with open('a.i') as fin:
189 for node, parent, indent, initial in actions:
191 line = fin.readline()
192 while line != '@@@\n':
196 (line == '\n' and len(lines) and lines[-1] == '\n')
199 elif line[:11] == '@@@ IMPORT(' and line[-2:] == ')\n':
200 # make the importing look like a function call in the C code:
201 #lines.append('import("{0:s}");\n'.format(line[11:-2]))
202 line = fin.readline()
203 while line != '@@@ IMPORT END\n':
205 line = fin.readline()
208 line = fin.readline()
209 text = ''.join(lines)
212 context.indent = indent
213 text = c_to_python(context, text)
215 context.indent = indent
218 'void a(void) {{\n{0:s}}}\n'.format(text)
220 assert text[:len(indent) + 9] == '{0:s}def a():\n'.format(indent)
221 text = text[len(indent) + 9:]
226 elif text.index('\n') == len(text) - 1:
227 if parent.tag == 'AST_Section2_Rule':
231 get_text(parent, 2).rstrip('\t ') + ' /*COLUMN32*/ '
233 text = text.lstrip('\t ')
235 if parent.tag == 'AST_Section2_Rule':
239 get_text(parent, 2).rstrip('\t ') + ' '
241 text = '{{\n{0:s}{1:s}}}\n'.format(text, indent)
242 set_text(node, 0, text)
244 xml.etree.ElementTree.ElementTree(root).write(
246 encoding = 'unicode' # strangely does not seem to default to this