8 import xml.etree.ElementTree
11 def my_rstrip(text, indent):
13 while i > 0 and text[i - 1] == '}':
16 while text[i - 1] != '{':
20 return text[:i].rstrip('\t ') + indent + text[i:]
22 def c_to_python(context, text):
24 lex_yy.yy_buffer_stack = [lex_yy.YYBufferState()]
27 root = y_tab.yyparse(t_def.AST.TranslationUnit)
29 root.translate_translation_unit(context)
30 return ''.join(context.lines)
32 root = xml.etree.ElementTree.parse(
34 xml.etree.ElementTree.XMLParser(
35 target = xml.etree.ElementTree.TreeBuilder(element.Element),
40 context = t_def.Context()
43 with open('a.c', 'w') as fout:
44 def extract(i, parent, indent):
45 if i.tag == 'AST_Section1Or2_CodeBlock':
47 assert node.tag == 'AST_Text'
48 if parent.tag == 'AST_Section1':
53 elif i.tag == 'AST_Section2_Rule_Action':
54 if len(i) == 0: # continued actions
55 assert parent.tag == 'AST_Section2_Rule'
56 assert len(parent) == 3
60 element.get_text(parent, 2).rstrip('\t ') + ' /*COLUMN32*/ '
64 assert node.tag == 'AST_Text'
66 elif i.tag == 'AST_Section3':
75 element.get_text(i, 0).lstrip()
77 for j in range(1, len(i)):
81 '{0:s}\n{1:s}'.format(
82 element.get_text(i, j).strip(),
83 '\n' if j == 2 else ''
89 element.get_text(i, len(i)).lstrip()
91 elif i.tag == 'AST_Section1' or i.tag == 'AST_Section2':
92 # kludge, concatenate single line codeblocks to see overall meaning,
93 # hopefully we can make the scanner do this itself in Python version
96 if i[j].tag == 'AST_Section1Or2_CodeBlock':
98 pre_delimiter = element.get_text(i[j], 0)
99 post_delimiter = element.get_text(i[j], 1)
102 len(element.get_text(i, k).strip()) == 0 and
103 i[k].tag == 'AST_Section1Or2_CodeBlock' and
104 element.get_text(i[k], 0) == pre_delimiter and
105 element.get_text(i[k], 1) == post_delimiter
111 ''.join([element.get_text(i[l][0], 0) for l in range(j, k)])
116 i.tag == 'AST_Section2_Rule' or
117 i.tag == 'AST_Section2_Rule_FLexRule'
119 element.set_text(i, 0, element.get_text(i, 0).lstrip('\t '))
120 elif i.tag == 'AST_Section2_CompoundRule':
125 indent + element.get_text(i, 0).lstrip('\t ')
127 for j in range(1, len(i)):
131 #element.get_text(i, j).rstrip('\t ') + child_indent
132 my_rstrip(element.get_text(i, j), child_indent)
137 indent + element.get_text(i, len(i)).lstrip('\t ')
140 extract(j, i, child_indent)
142 assert len(node) == 0
143 text = element.get_text(node, 0)
147 k = text.index('\n', j) + 1
152 (line[:10] == '#include <' and line[-4:] == '.h>\n') or
153 (line[:10] == '#include "' and line[-4:] == '.h"\n')
155 name = line[10:-4].replace('/', '.')
162 @@@ IMPORT END\n'''.format(
163 line[10:-4].replace('/', '.'),
171 actions.append((node, parent, indent, initial))
172 extract(root, None, '')
175 'gcc{0:s} -E a.c >a.i'.format(
176 ''.join([' "{0:s}"'.format(i) for i in sys.argv[1:]])
179 with open('a.i') as fin:
180 for node, parent, indent, initial in actions:
182 line = fin.readline()
183 while line != '@@@\n':
187 (line == '\n' and len(lines) and lines[-1] == '\n')
190 elif line[:11] == '@@@ IMPORT(' and line[-2:] == ')\n':
191 # make the importing look like a function call in the C code:
192 #lines.append('import("{0:s}");\n'.format(line[11:-2]))
193 line = fin.readline()
194 while line != '@@@ IMPORT END\n':
196 line = fin.readline()
199 line = fin.readline()
200 text = ''.join(lines)
203 context.indent = indent
204 text = c_to_python(context, text)
206 context.indent = indent
209 'void a(void) {{\n{0:s}}}\n'.format(text)
211 assert text[:len(indent) + 9] == '{0:s}def a():\n'.format(indent)
212 text = text[len(indent) + 9:]
217 elif text.index('\n') == len(text) - 1:
218 if parent.tag == 'AST_Section2_Rule':
222 element.get_text(parent, 2).rstrip('\t ') + ' /*COLUMN32*/ '
224 text = text.lstrip('\t ')
226 if parent.tag == 'AST_Section2_Rule':
230 element.get_text(parent, 2).rstrip('\t ') + ' '
232 text = '{{\n{0:s}{1:s}}}\n'.format(text, indent)
233 element.set_text(node, 0, text)
235 xml.etree.ElementTree.ElementTree(root).write(
237 encoding = 'unicode' # strangely does not seem to default to this