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(None, None)]
27 root = y_tab.yyparse(ast.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 = ast.Context()
41 #context.translate_identifier['BEGIN'] = 'self.BEGIN'
42 #context.translate_identifier['yylval'] = 'ref_data.yylval'
43 #context.translate_identifier['yytext'] = 'self.yytext'
44 #context.translate_identifier['yy_pop_state'] = 'self.yy_pop_state'
45 #context.translate_identifier['yy_push_state'] = 'self.yy_push_state'
48 with open('a.c', 'w') as fout:
49 def extract(i, parent, indent):
50 if i.tag == 'AST_Section1Or2_CodeBlock':
52 assert node.tag == 'AST_Text'
55 elif i.tag == 'AST_Section2_Rule_Action':
56 if len(i) == 0: # continued actions
57 assert parent.tag == 'AST_Section2_Rule'
58 assert len(parent) == 3
62 element.get_text(parent, 2).rstrip('\t ') + ' /*COLUMN32*/ '
66 assert node.tag == 'AST_Text'
68 elif i.tag == 'AST_Section3':
74 for j in range(1, len(i) + 1):
75 element.set_text(i, j, element.get_text(i, j).rstrip() + '\n')
76 elif i.tag == 'AST_Section1_StartConditions':
78 assert j.tag == 'AST_Name'
79 text = element.get_text(j, 0)
80 context.translate_identifier[text] = 'DFA.{0:s}'.format(text)
82 i.tag == 'AST_Section2_Rule' or
83 i.tag == 'AST_Section2_Rule_FLexRule'
85 element.set_text(i, 0, element.get_text(i, 0).lstrip('\t '))
86 elif i.tag == 'AST_Section2_CompoundRule':
91 indent + element.get_text(i, 0).lstrip('\t ')
93 for j in range(1, len(i)):
97 #element.get_text(i, j).rstrip('\t ') + child_indent
98 my_rstrip(element.get_text(i, j), child_indent)
103 indent + element.get_text(i, len(i)).lstrip('\t ')
106 extract(j, i, child_indent)
108 assert len(node) == 0
109 text = element.get_text(node, 0)
113 k = text.index('\n', j) + 1
118 (line[:10] == '#include <' and line[-4:] == '.h>\n') or
119 (line[:10] == '#include "' and line[-4:] == '.h"\n')
121 name = line[10:-4].replace('/', '.')
128 @@@ IMPORT END\n'''.format(
129 line[10:-4].replace('/', '.'),
137 actions.append((node, parent, indent, initial))
138 extract(root, None, '')
140 os.system('gcc -I tests/flex_h -E a.c >a.i')
141 with open('a.i') as fin:
142 for node, parent, indent, initial in actions:
144 line = fin.readline()
145 while line != '@@@\n':
149 (line == '\n' and len(lines) and lines[-1] == '\n')
152 elif line[:11] == '@@@ IMPORT(' and line[-2:] == ')\n':
153 # make the importing look like a function call in the C code:
154 #lines.append('import("{0:s}");\n'.format(line[11:-2]))
155 line = fin.readline()
156 while line != '@@@ IMPORT END\n':
158 line = fin.readline()
161 line = fin.readline()
162 text = ''.join(lines)
165 context.indent = indent
166 text = c_to_python(context, text)
168 assert parent.tag == 'AST_Section2_Rule'
169 assert len(parent) == 3
170 prefix = element.get_text(parent, 2).rstrip('\t ')
171 context.indent = indent
174 'void a(void) {{\n{0:s}}}\n'.format(text)
176 assert text[:len(indent) + 10] == '\n{0:s}def a():\n'.format(indent)
177 text = text[len(indent) + 10:]
182 elif text.index('\n') == len(text) - 1:
183 prefix += ' /*COLUMN32*/ '
184 text = text.lstrip('\t ')
187 text = '{{\n{0:s}{1:s}}}\n'.format(
191 element.set_text(parent, 2, prefix)
192 element.set_text(node, 0, text)
194 xml.etree.ElementTree.ElementTree(root).write(
196 encoding = 'unicode' # strangely does not seem to default to this