From eb8a47a5f15f6d5cf745def6ada71d41785870f6 Mon Sep 17 00:00:00 2001 From: ayrton Date: Sun, 19 Nov 2023 11:05:52 -0700 Subject: [PATCH] Modified Unparsing Style Took 30 minutes --- ast_parser/gaz_unparser.py | 71 ++++++++++--------- ast_parser/general_unparser.py | 6 ++ ast_parser/python_unparser.py | 62 +++++++++++++++++ ast_parser/test/test_unparse.py | 120 ++++++++++++++++---------------- fuzzer.py | 4 +- gazprea_fuzzer.py | 4 +- 6 files changed, 167 insertions(+), 100 deletions(-) diff --git a/ast_parser/gaz_unparser.py b/ast_parser/gaz_unparser.py index ecdbae1..9be45d1 100644 --- a/ast_parser/gaz_unparser.py +++ b/ast_parser/gaz_unparser.py @@ -63,30 +63,29 @@ def to_gaz_op(param): return param -class AstParser(GeneralUnparser): +class GazUnparser(GeneralUnparser): def __init__(self, input: str or ET.Element, from_xml: bool = False): + self.indentation = 0 if from_xml: self.xml = input - self.input = None + self.source = None else: - self.input = input + self.source = input self.xml = None - self.indentation = 0 - def unparse(self): """ @brief unparses the xml into valid gazprea code :return: a string of valid gazprea code """ - self.input = "" + self.source = "" for node in self.xml: self.unparse_node(node) def unparse_node(self, node): if node.tag not in [GAZ_VAR_TAG, GAZ_RHS_TAG, GAZ_LHS_TAG, GAZ_LIT_TAG, GAZ_OPERATOR_TAG]: - self.input += " " * self.indentation + self.source += " " * self.indentation if node.tag == GAZ_BLOCK_TAG: self.unparse_block(node) @@ -107,7 +106,7 @@ class AstParser(GeneralUnparser): elif node.tag == GAZ_VAR_TAG: self.unparse_variable(node) elif node.tag == GAZ_RHS_TAG or node.tag == GAZ_LHS_TAG: - self._xhs_unparse(node) + self.unparse_xhs(node) elif node.tag == GAZ_LIT_TAG: self.unparse_literal(node) elif node.tag == GAZ_ASSIGNMENT_TAG: @@ -120,23 +119,23 @@ class AstParser(GeneralUnparser): raise Exception("Unknown tag: " + node.tag) def unparse_block(self, node): - self.input += "{\n" + self.source += "{\n" self.indentation += 4 for child in node: self.unparse_node(child) self.indentation -= 4 if node.get(GAZ_TY_KEY) is None: - self.input += "}\n\n" + self.source += "}\n\n" elif node.get(GAZ_TY_KEY) in [GAZ_TRUE_BLOCK_TAG, GAZ_FALSE_BLOCK_TAG]: - self.input += "}" + self.source += "}" def unparse_declaration(self, node): variable = node.find(GAZ_VAR_TAG) rhs = node.find(GAZ_RHS_TAG) self.unparse_variable(variable, True) - self.input += " = " + self.source += " = " self.unparse_node(rhs) - self.input += ";\n" + self.source += ";\n" def unparse_variable(self, node, is_declaration = False): if is_declaration: @@ -144,9 +143,9 @@ class AstParser(GeneralUnparser): type = to_gazprea_type(node.get(GAZ_TY_KEY)) name = node.get(GAZ_NAME_KEY) - self.input += "{} {} {}".format(mut, type, name) + self.source += "{} {} {}".format(mut, type, name) else: - self.input += "{}".format(node.get(GAZ_NAME_KEY)) + self.source += "{}".format(node.get(GAZ_NAME_KEY)) def unparse_stream(self, node): if node.get(GAZ_TY_KEY) == GAZ_OUT_STREAM: @@ -158,31 +157,31 @@ class AstParser(GeneralUnparser): for child in node: self.unparse_node(child) - self.input += "<- {};\n".format(GAZ_IN_STREAM) + self.source += "<- {};\n".format(GAZ_IN_STREAM) def unparse_outstream(self, node): for child in node: self.unparse_node(child) - self.input += " -> {};\n".format(GAZ_OUT_STREAM) + self.source += " -> {};\n".format(GAZ_OUT_STREAM) def unparse_literal(self, node): - self.input += "{}".format(to_gaz_value(node.get(GAZ_VAL_KEY))) + self.source += "{}".format(to_gaz_value(node.get(GAZ_VAL_KEY))) - def _xhs_unparse(self, node): + def unparse_xhs(self, node): for child in node: self.unparse_node(child) def unparse_operator(self, node): - self._xhs_unparse(node.find(GAZ_LHS_TAG)) - self.input += " {} ".format(to_gaz_op(node.get("op"))) - self._xhs_unparse(node.find(GAZ_RHS_TAG)) + self.unparse_xhs(node.find(GAZ_LHS_TAG)) + self.source += " {} ".format(to_gaz_op(node.get("op"))) + self.unparse_xhs(node.find(GAZ_RHS_TAG)) def unparse_return(self, node): - self.input += "return " + self.source += "return " for child in node: self.unparse_node(child) - self.input += ";\n" + self.source += ";\n" def unparse_routine(self, node): return_type = "" @@ -196,7 +195,7 @@ class AstParser(GeneralUnparser): args = self.unparse_argument(args) - self.input += "{} {}{} {} ".format( + self.source += "{} {}{} {} ".format( node.tag, node.get(GAZ_NAME_KEY), args, @@ -208,7 +207,7 @@ class AstParser(GeneralUnparser): continue self.unparse_node(child) - # cls.input += "}\n\n" #blocks are already there + # cls.source += "}\n\n" #blocks are already there def unparse_argument(self, nodes): if len(nodes) == 0: @@ -224,37 +223,37 @@ class AstParser(GeneralUnparser): def unparse_assignment(self, element_in: ET.Element): self.unparse_variable(element_in.find(GAZ_VAR_TAG), False) - self.input += " = " + self.source += " = " self.unparse_node(element_in.find(GAZ_RHS_TAG)) - self.input += ";\n" + self.source += ";\n" def unparse_conditional(self, element_in: ET.Element): - self.input += "if (" + self.source += "if (" i = 0 for node in element_in: if node.tag == GAZ_IF_TAG: - self.input += " else " + self.source += " else " self.unparse_conditional(node) elif node.tag != GAZ_BLOCK_TAG: self.unparse_node(node) - self.input += ") " + self.source += ") " elif node.tag == GAZ_BLOCK_TAG: if node.get(GAZ_TY_KEY) == GAZ_TRUE_BLOCK_TAG: self.unparse_node(node) elif node.get(GAZ_TY_KEY) == GAZ_FALSE_BLOCK_TAG: - self.input += " else " + self.source += " else " self.unparse_node(node) else: self.unparse_node(node) i += 1 def unparse_loop(self, element_in: ET.Element): - self.input += "loop (" + self.source += "loop (" i = 0 for node in element_in: if node.tag != GAZ_BLOCK_TAG: self.unparse_node(node) - self.input += ") " + self.source += ") " elif node.tag == GAZ_BLOCK_TAG: self.unparse_node(node) i += 1 @@ -269,8 +268,8 @@ class AstParser(GeneralUnparser): pass def unparse_unary(self, element_in: ET.Element): - self.input += " {}".format(to_gaz_op(element_in.get("op"))) - self._xhs_unparse(element_in.find(GAZ_RHS_TAG)) + self.source += " {}".format(to_gaz_op(element_in.get("op"))) + self.unparse_xhs(element_in.find(GAZ_RHS_TAG)) def unparse_expression(self, element_in: ET.Element): pass diff --git a/ast_parser/general_unparser.py b/ast_parser/general_unparser.py index c57740f..1c7af75 100644 --- a/ast_parser/general_unparser.py +++ b/ast_parser/general_unparser.py @@ -1,6 +1,8 @@ import xml.etree.ElementTree as ET from abc import ABC, abstractmethod +from constants import * + class GeneralUnparser(ABC): @abstractmethod @@ -79,4 +81,8 @@ class GeneralUnparser(ABC): def unparse_variable(self, element_in: ET.Element): pass + @abstractmethod + def unparse_xhs(self, element_in: ET.Element): + pass + diff --git a/ast_parser/python_unparser.py b/ast_parser/python_unparser.py index e69de29..d9dd415 100644 --- a/ast_parser/python_unparser.py +++ b/ast_parser/python_unparser.py @@ -0,0 +1,62 @@ +from xml.etree import ElementTree as ET + +from ast_parser.general_unparser import GeneralUnparser +from constants import * + + +class PythonUnparser(GeneralUnparser): + + def unparse_xhs(self, element_in: ET.Element): + pass + + def unparse_top_block(self, element_in: ET.Element): + pass + + def unparse_block(self, element_in: ET.Element): + pass + + def unparse_routine(self, element_in: ET.Element): + pass + + def unparse_argument(self, element_in: ET.Element): + pass + + def unparse_statement(self, element_in: ET.Element): + pass + + def unparse_expression(self, element_in: ET.Element): + pass + + def unparse_declaration(self, element_in: ET.Element): + pass + + def unparse_operator(self, element_in: ET.Element): + pass + + def unparse_unary(self, element_in: ET.Element): + pass + + def unparse_stream(self, element_in: ET.Element): + pass + + def unparse_assignment(self, element_in: ET.Element): + pass + + def unparse_conditional(self, element_in: ET.Element): + pass + + def unparse_loop(self, element_in: ET.Element): + pass + + def unparse_routine_call(self, element_in: ET.Element): + pass + + def unparse_return(self, element_in: ET.Element): + pass + + def unparse_literal(self, element_in: ET.Element): + pass + + def unparse_variable(self, element_in: ET.Element): + pass + diff --git a/ast_parser/test/test_unparse.py b/ast_parser/test/test_unparse.py index adb2930..b200a34 100644 --- a/ast_parser/test/test_unparse.py +++ b/ast_parser/test/test_unparse.py @@ -1,6 +1,6 @@ import unittest -from ast_parser.gaz_unparser import AstParser +from ast_parser.gaz_unparser import GazUnparser import xml.etree.ElementTree as ET @@ -8,61 +8,61 @@ class TestParseCode(unittest.TestCase): def test_unparse_variable_regular(self): input = '' - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual("a", parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual("a", parser.source) def test_unparse_variable_declaration(self): input = '' - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_variable(parser.xml, True) - self.assertIsNotNone(parser.input) - self.assertEqual("var integer a", parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual("var integer a", parser.source) def test_unparse_rhs_single(self): input = '' - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual("1", parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual("1", parser.source) def test_unparse_declaration(self): input = '' - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual("var integer a = 1;\n", parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual("var integer a = 1;\n", parser.source) def test_unparse_stream(self): input = ' ' - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual("a * 42 -> std_output;\n", parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual("a * 42 -> std_output;\n", parser.source) def test_unparse_block(self): input = ' ' - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual("{\n var integer a = 1;\n a * 42 -> std_output;\n return 0;\n}\n\n", parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual("{\n var integer a = 1;\n a * 42 -> std_output;\n return 0;\n}\n\n", parser.source) def test_unparse_assignment(self): with open("xml/assignment.xml", "r") as f: input = f.read() - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual("C = 30;\n", parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual("C = 30;\n", parser.source) def test_unparse_conditional(self): # TODO test the else-if statements with open("xml/conditional.xml", "r") as f: @@ -71,13 +71,13 @@ class TestParseCode(unittest.TestCase): with open("xml/conditional.out", "r") as f: output = f.read() - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual(output, parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual(output, parser.source) def test_unparse_loop(self): with open("xml/loop.xml", "r") as f: @@ -86,27 +86,27 @@ class TestParseCode(unittest.TestCase): with open("xml/loop.out", "r") as f: output = f.read() - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual(output, parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual(output, parser.source) def test_unparse_operation_single(self): input = ' ' - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual("a * 42", parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual("a * 42", parser.source) def test_unparse_return(self): input = ' ' - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual("return 0;\n", parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual("return 0;\n", parser.source) def test_unparse_unary(self): with open("xml/unary.xml", "r") as f: @@ -115,42 +115,42 @@ class TestParseCode(unittest.TestCase): with open("xml/unary.out", "r") as f: output = f.read() - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual(output, parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual(output, parser.source) def test_unparse_routine(self): input = '' - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) + self.assertIsNotNone(parser.source) i = ' ' * parser.indentation - self.assertEqual("procedure main() returns integer {\n var integer a = 1;\n a * 42 -> std_output;\n return 0;\n}\n\n", parser.input) + self.assertEqual("procedure main() returns integer {\n var integer a = 1;\n a * 42 -> std_output;\n return 0;\n}\n\n", parser.source) def test_unparse_args(self): with open("xml/many_args.xml", 'r') as f: input = f.read() with open("xml/many_args.out", 'r') as f: output = f.read() - parser = AstParser(ET.fromstring(input), True) - parser.input = "" + parser = GazUnparser(ET.fromstring(input), True) + parser.source = "" parser.unparse_node(parser.xml) - self.assertIsNotNone(parser.input) - self.assertEqual(output, parser.input) + self.assertIsNotNone(parser.source) + self.assertEqual(output, parser.source) def test_unparse_code(self): with open("xml/test.xml", "r") as input: - parser = AstParser(ET.fromstring(input.read()), True) + parser = GazUnparser(ET.fromstring(input.read()), True) parser.unparse() - self.assertIsNotNone(parser.input) + self.assertIsNotNone(parser.source) with open("input.in", "r") as input: i = input.read() - self.assertEqual(i, parser.input) + self.assertEqual(i, parser.source) if __name__ == "__main__": diff --git a/fuzzer.py b/fuzzer.py index 4070caa..2997480 100644 --- a/fuzzer.py +++ b/fuzzer.py @@ -21,8 +21,8 @@ class GazpreaFuzzer: def fuzz(self): self.generator.generate_ast() - self.parser = AstParser(self.generator.ast, True) + self.parser = GazUnparser(self.generator.ast, True) self.parser.unparse() self.ast = self.generator.ast - self.source = self.parser.input + self.source = self.parser.source diff --git a/gazprea_fuzzer.py b/gazprea_fuzzer.py index 8f6e5bd..b5292ce 100644 --- a/gazprea_fuzzer.py +++ b/gazprea_fuzzer.py @@ -31,7 +31,7 @@ class Fuzzer(): os.mkdir("fuzzer/debug") os.mkdir("fuzzer/instream") os.mkdir("fuzzer/outputs") - with open("fuzzer/input/name{}.in".format(i), 'w') as f: + with open("fuzzer/source/name{}.in".format(i), 'w') as f: f.write(self.fuzzer.source) with open("fuzzer/debug/name{}.out".format(i), 'w') as f: f.write(pretty) @@ -46,7 +46,7 @@ if __name__ == '__main__': description='Procedurally generate a test case for Gazprea' ) parser.add_argument('-b', '--batch_size', type=int, required=False, - help="generate BATCH cases (fuzzer/input/nameX.in, /instream/..., /outputs/...)") + help="generate BATCH cases (fuzzer/source/nameX.in, /instream/..., /outputs/...)") parser.add_argument('--seed', type=int, required=False, action="store", help="rng seed") parser.add_argument('config_file', type=str, action="store",