import os import shutil import xml.etree.ElementTree as ET def to_gazprea_type(ty: str): if ty == "int": return "integer" elif ty == "bool": return "boolean" elif ty == "string": return "string" elif ty == 'void': return 'void' else: raise Exception("Unknown type: " + ty) class AstParser: def __init__(self, input: str or ET.Element, from_xml: bool = False): if from_xml: self.xml = input self.input = None else: self.input = input self.xml = None self.indentation = 0 def parse(self): if os.path.isdir("/home/stormblessed/Code/gazprea_fuzzer_v0.2/ast_parser/test/.tmp"): os.system("rm -rf /home/stormblessed/Code/gazprea_fuzzer_v0.2/ast_parser/test/.tmp") os.mkdir("/home/stormblessed/Code/gazprea_fuzzer_v0.2/ast_parser/test/.tmp") else: os.mkdir("/home/stormblessed/Code/gazprea_fuzzer_v0.2/ast_parser/test/.tmp") with open("/home/stormblessed/Code/gazprea_fuzzer_v0.2/ast_parser/test/.tmp/input.in", "x") as f: f.write(self.input) os.system("/home/stormblessed/.local/bin/gazc " "/home/stormblessed/Code/gazprea_fuzzer_v0.2/ast_parser/test/.tmp/input.in " "/home/stormblessed/Code/gazprea_fuzzer_v0.2/ast_parser/test/.tmp/output.out " "/home/stormblessed/Code/gazprea_fuzzer_v0.2/ast_parser/test/.tmp/xml.xml") self.xml = ET.parse(".tmp/xml.xml") def unparse(self): """ @brief unparses the xml into valid gazprea code :return: a string of valid gazprea code """ self.input = "" for node in self.xml: self._unparse_node(node) def _unparse_node(self, node): if node.tag not in ["variable", "rhs", "lhs", "literal", "operator"]: self.input += " " * self.indentation if node.tag == "block": self._block_unparse(node) elif node.tag == "declaration": self._declaration_unparse(node) elif node.tag == "return": self._return_unparse(node) elif node.tag == "operator": self._operator_unparse(node) elif node.tag == "stream": self._stream_unparse(node) elif node.tag == "literal": self._literal_unparse(node) elif node.tag == "procedure" or node.tag == "function": self._routine_unparse(node) elif node.tag == "variable": self._variable_unparse(node) elif node.tag == "rhs" or node.tag == "lhs": self._xhs_unparse(node) elif node.tag == "literal": self._literal_unparse(node) else: raise Exception("Unknown tag: " + node.tag) def _block_unparse(self, node): self.input += "{\n" self.indentation += 4 for child in node: self._unparse_node(child) self.indentation -= 4 self.input += "}\n\n" def _declaration_unparse(self, node): variable = node.find("variable") rhs = node.find("rhs") self._variable_unparse(variable, True) self.input += "=" self._unparse_node(rhs) self.input += ";\n" def _variable_unparse(self, node, is_declaration = False): if is_declaration: mut = node.get("mut") type = to_gazprea_type(node.get("type")) name = node.get("name") self.input += "{} {} {} ".format(mut, type, name) else: self.input += " {} ".format(node.get("name")) def _stream_unparse(self, node): for child in node: self._unparse_node(child) self.input += "-> {};\n".format(node.get("type")) def _literal_unparse(self, node): self.input += " {} ".format(node.get("value")) def _xhs_unparse(self, node): for child in node: self._unparse_node(child) def _operator_unparse(self, node): self._xhs_unparse(node.find("lhs")) self.input += "{}".format(node.get("op")) self._xhs_unparse(node.find("rhs")) def _return_unparse(self, node): self.input += "return" for child in node: self._unparse_node(child) self.input += ";\n" def _routine_unparse(self, node): return_type = "" if node.get("return_type") != "": return_type = "returns " + to_gazprea_type(node.get("return_type")) self.input += "{} {}{} {} ".format( node.tag, node.get("name"), node.get("args"), return_type, ) for child in node: self._unparse_node(child) # cls.input += "}\n\n" #blocks are already there if __name__ == '__main__': input = """ function art() returns integer { return 3; } procedure main() returns integer { integer b = art(); integer a = 1; a * 42 -> std_output; return 0; } """ parser = AstParser(input) parser.parse()