Compare commits
4 commits
ayrton/gen
...
main
Author | SHA1 | Date | |
---|---|---|---|
aCompetentBean | 6a7e3f98f5 | ||
ayrton | 880c8e0713 | ||
ayrton | 9f915bd80e | ||
aCompetentBean | 0d96551e82 |
|
@ -3,6 +3,7 @@ import warnings
|
||||||
|
|
||||||
from english_words import get_english_words_set
|
from english_words import get_english_words_set
|
||||||
|
|
||||||
|
from ast_generator.tiny_py_unparse import TinyPyUnparser
|
||||||
from ast_generator.utils import *
|
from ast_generator.utils import *
|
||||||
from ast_generator.utils import filter_options, _choose_option
|
from ast_generator.utils import filter_options, _choose_option
|
||||||
from constants import *
|
from constants import *
|
||||||
|
@ -141,17 +142,17 @@ class AstGenerator:
|
||||||
self.current_ast_element.append(element)
|
self.current_ast_element.append(element)
|
||||||
self.current_ast_element = element
|
self.current_ast_element = element
|
||||||
|
|
||||||
if block_type in [GAZ_PROCEDURE_TAG, GAZ_FUNCTION_TAG]:
|
|
||||||
self.generate_statements()
|
|
||||||
else:
|
|
||||||
self.generate_statements(include='declaration')
|
|
||||||
self.generate_statements(exclude='declaration')
|
|
||||||
|
|
||||||
# Generate the loop condition increment if we are in a loop
|
# Generate the loop condition increment if we are in a loop
|
||||||
if block_type == GAZ_LOOP_TAG:
|
if block_type == GAZ_LOOP_TAG:
|
||||||
self.generate_loop_condition_check(loop_var)
|
self.generate_loop_condition_check(loop_var)
|
||||||
self.generate_loop_condition_increment(loop_var)
|
self.generate_loop_condition_increment(loop_var)
|
||||||
|
|
||||||
|
if block_type not in [GAZ_PROCEDURE_TAG, GAZ_FUNCTION_TAG]:
|
||||||
|
self.generate_statements()
|
||||||
|
else:
|
||||||
|
self.generate_statements(include='declaration')
|
||||||
|
self.generate_statements(exclude='declaration')
|
||||||
|
|
||||||
if return_stmt:
|
if return_stmt:
|
||||||
self.generate_return(return_type=return_type, return_value=return_value)
|
self.generate_return(return_type=return_type, return_value=return_value)
|
||||||
if self.settings['generation-options']['generate-dead-code']:
|
if self.settings['generation-options']['generate-dead-code']:
|
||||||
|
@ -436,13 +437,66 @@ class AstGenerator:
|
||||||
self.make_scoped_element(GAZ_LOOP_TAG, [])
|
self.make_scoped_element(GAZ_LOOP_TAG, [])
|
||||||
self.current_control_flow_nesting_depth += 1
|
self.current_control_flow_nesting_depth += 1
|
||||||
|
|
||||||
self.generate_expression(GAZ_BOOL_KEY) # the loop entry condition #TODO force true
|
truthiness = self.get_truthiness()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
self.generate_expression(GAZ_BOOL_KEY) # the loop entry condition #TODO force true, if false, generate a simple block and return, no need to nest code we won't use
|
||||||
|
|
||||||
|
iterator = self.current_ast_element.iter()
|
||||||
|
next(iterator)
|
||||||
|
conditional = next(iterator)
|
||||||
|
if not self.truth_check(conditional, truthiness):
|
||||||
|
self.current_ast_element.remove(conditional)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
self.generate_block(block_type=GAZ_LOOP_TAG,
|
self.generate_block(block_type=GAZ_LOOP_TAG,
|
||||||
loop_var=init_var) # append a variable increment and prepend a break statement if var is > max loop iterations
|
loop_var=init_var) # append a variable increment and prepend a break statement if var is > max loop iterations
|
||||||
|
|
||||||
self.current_control_flow_nesting_depth -= 1
|
self.current_control_flow_nesting_depth -= 1
|
||||||
self.exit_scoped_element(parent)
|
self.exit_scoped_element(parent)
|
||||||
|
|
||||||
|
def get_truthiness(self):
|
||||||
|
return random.random() < self.settings['misc-weights']['truthiness']
|
||||||
|
|
||||||
|
def truth_check(self, element: ET.Element, truthiness: bool):
|
||||||
|
# evaluate the element
|
||||||
|
uncompiled = self.unparse_conditional_statement(element)
|
||||||
|
substr1 = uncompiled.find("**")
|
||||||
|
substr2 = uncompiled.find("**", substr1 + 1)
|
||||||
|
|
||||||
|
if -1 not in [substr1, substr2]:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# print(uncompiled)
|
||||||
|
try:
|
||||||
|
res = eval(uncompiled)
|
||||||
|
except (OverflowError, ZeroDivisionError):
|
||||||
|
res = False
|
||||||
|
|
||||||
|
# check it against truthiness and return the comparison
|
||||||
|
return res == truthiness
|
||||||
|
|
||||||
|
def unparse_conditional_statement(self, element: ET.Element):
|
||||||
|
py_unparse = TinyPyUnparser(element, True)
|
||||||
|
unparsed = ""
|
||||||
|
if element.tag == GAZ_LIT_TAG:
|
||||||
|
py_unparse.unparse_literal(element)
|
||||||
|
unparsed = py_unparse.source
|
||||||
|
elif element.tag == GAZ_OPERATOR_TAG:
|
||||||
|
py_unparse.unparse_operator(element)
|
||||||
|
unparsed = py_unparse.source
|
||||||
|
elif element.tag == GAZ_VAR_TAG:
|
||||||
|
xml = self.current_scope.resolve(element.get("name"))
|
||||||
|
py_unparse.unparse_variable(xml)
|
||||||
|
unparsed = py_unparse.source
|
||||||
|
elif element.tag == GAZ_BRACKET_TAG:
|
||||||
|
py_unparse.unparse_brackets(element)
|
||||||
|
unparsed = py_unparse.source
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown element type for conditional argument: " + element.tag)
|
||||||
|
return unparsed
|
||||||
|
|
||||||
def generate_zero_declaration(self):
|
def generate_zero_declaration(self):
|
||||||
"""
|
"""
|
||||||
@brief generate a declaration int a = 0 for some a
|
@brief generate a declaration int a = 0 for some a
|
||||||
|
|
|
@ -90,9 +90,7 @@ misc-weights:
|
||||||
type-qualifier-weights:
|
type-qualifier-weights:
|
||||||
const: 10
|
const: 10
|
||||||
var: 60
|
var: 60
|
||||||
conditional-eval:
|
truthiness: 0.9 # Probability of conditionals being true
|
||||||
true: 50
|
|
||||||
false: 50
|
|
||||||
|
|
||||||
block-termination-probability: 0.2 # probability for a block to terminate
|
block-termination-probability: 0.2 # probability for a block to terminate
|
||||||
|
|
||||||
|
|
|
@ -245,12 +245,13 @@ class TestGeneration(unittest.TestCase):
|
||||||
self.assertFalse(self.is_no_op(operator))
|
self.assertFalse(self.is_no_op(operator))
|
||||||
|
|
||||||
def test_create_global(self):
|
def test_create_global(self):
|
||||||
self.ast_gen.ast = ET.Element("block")
|
element = ET.Element("block")
|
||||||
|
self.ast_gen.ast = element
|
||||||
self.ast_gen.current_ast_element = self.ast_gen.ast
|
self.ast_gen.current_ast_element = self.ast_gen.ast
|
||||||
self.ast_gen.generate_main()
|
self.ast_gen.generate_main()
|
||||||
|
|
||||||
global_block = self.ast_gen.current_ast_element
|
global_block = element
|
||||||
global_scope = self.ast_gen.current_scope
|
global_scope = self.ast_gen.current_scope.get_top_scope()
|
||||||
|
|
||||||
self.assertIsNotNone(self.ast_gen.ast.find("procedure"))
|
self.assertIsNotNone(self.ast_gen.ast.find("procedure"))
|
||||||
self.ast_gen.current_ast_element = self.ast_gen.ast.find("procedure")
|
self.ast_gen.current_ast_element = self.ast_gen.ast.find("procedure")
|
||||||
|
@ -310,8 +311,10 @@ class TestGeneration(unittest.TestCase):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def test_print_all_current_scope_vars(self):
|
def test_print_all_current_scope_vars(self):
|
||||||
self.ast_gen.ast = ET.Element("block")
|
element = ET.Element("block")
|
||||||
self.ast_gen.current_ast_element = self.ast_gen.ast
|
self.ast_gen.ast = element
|
||||||
|
self.ast_gen.current_ast_element = element
|
||||||
|
self.ast_gen.current_scope = Scope(None)
|
||||||
self.ast_gen.generate_declaration(mut='var')
|
self.ast_gen.generate_declaration(mut='var')
|
||||||
self.ast_gen.generate_declaration(mut='var')
|
self.ast_gen.generate_declaration(mut='var')
|
||||||
self.ast_gen.generate_declaration(mut='var')
|
self.ast_gen.generate_declaration(mut='var')
|
||||||
|
@ -319,12 +322,67 @@ class TestGeneration(unittest.TestCase):
|
||||||
|
|
||||||
self.ast_gen.print_all_current_scope_vars()
|
self.ast_gen.print_all_current_scope_vars()
|
||||||
|
|
||||||
print(ET.tostring(self.ast_gen.ast))
|
|
||||||
|
# print(ET.tostring(self.ast_gen.ast))
|
||||||
|
|
||||||
streams = self.ast_gen.ast.findall("stream")
|
streams = self.ast_gen.ast.findall("stream")
|
||||||
|
|
||||||
self.assertEqual(4, len(streams))
|
self.assertEqual(4, len(streams))
|
||||||
|
|
||||||
|
def test_conditional_test_1(self):
|
||||||
|
element = ET.fromstring('<literal type="bool" value="False"/>')
|
||||||
|
|
||||||
|
self.assertIsNotNone(element)
|
||||||
|
|
||||||
|
res = self.ast_gen.truth_check(element, True)
|
||||||
|
self.assertFalse(res)
|
||||||
|
|
||||||
|
def test_conditional_test_2(self):
|
||||||
|
element = ET.fromstring('<literal type="bool" value="True"/>')
|
||||||
|
self.assertIsNotNone(element)
|
||||||
|
|
||||||
|
res = self.ast_gen.truth_check(element, True)
|
||||||
|
self.assertTrue(res)
|
||||||
|
|
||||||
|
def test_conditional_test_3(self):
|
||||||
|
with open("xml/conditional.xml", 'r') as f:
|
||||||
|
element = ET.fromstring(f.read())
|
||||||
|
|
||||||
|
self.assertIsNotNone(element)
|
||||||
|
|
||||||
|
res = self.ast_gen.truth_check(element, True)
|
||||||
|
self.assertTrue(res)
|
||||||
|
|
||||||
|
def test_conditional_test_4(self):
|
||||||
|
with open("xml/conditional_2.xml", 'r') as f:
|
||||||
|
element = ET.fromstring(f.read())
|
||||||
|
|
||||||
|
self.assertIsNotNone(element)
|
||||||
|
|
||||||
|
res = self.ast_gen.truth_check(element, True)
|
||||||
|
self.assertFalse(res)
|
||||||
|
|
||||||
|
def test_conditional_test_5(self):
|
||||||
|
with open("xml/conditional_3.xml", 'r') as f:
|
||||||
|
element = ET.fromstring(f.read())
|
||||||
|
|
||||||
|
self.assertIsNotNone(element)
|
||||||
|
|
||||||
|
res = self.ast_gen.truth_check(element, True)
|
||||||
|
self.assertTrue(res)
|
||||||
|
|
||||||
|
# def test_conditional_test_variable(self):
|
||||||
|
# element = ET.fromstring('<variable name="harold" type="int" mut="var"/>')
|
||||||
|
#
|
||||||
|
# var = Variable("harold", "int", "var")
|
||||||
|
# var.decl_xml = ET.fromstring('<literal type="bool" value="True"/>')
|
||||||
|
# self.ast_gen.current_scope.append("harold", element)
|
||||||
|
# self.assertIsNotNone(element)
|
||||||
|
#
|
||||||
|
# res = self.ast_gen.truth_check(element, True)
|
||||||
|
# self.assertTrue(res)
|
||||||
|
|
||||||
|
|
||||||
def write_ast(self):
|
def write_ast(self):
|
||||||
dom = xml.dom.minidom.parseString(ET.tostring(self.ast_gen.ast).decode('utf-8'))
|
dom = xml.dom.minidom.parseString(ET.tostring(self.ast_gen.ast).decode('utf-8'))
|
||||||
pretty: str = dom.toprettyxml()
|
pretty: str = dom.toprettyxml()
|
||||||
|
|
8
ast_generator/test/xml/conditional.xml
Normal file
8
ast_generator/test/xml/conditional.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<operator op="==" type="int">
|
||||||
|
<lhs>
|
||||||
|
<literal mut="var" type="int" value="42"/>
|
||||||
|
</lhs>
|
||||||
|
<rhs>
|
||||||
|
<literal type="int" value="42" />
|
||||||
|
</rhs>
|
||||||
|
</operator>
|
8
ast_generator/test/xml/conditional_2.xml
Normal file
8
ast_generator/test/xml/conditional_2.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<operator op="!=" type="int">
|
||||||
|
<lhs>
|
||||||
|
<literal mut="var" type="int" value="42"/>
|
||||||
|
</lhs>
|
||||||
|
<rhs>
|
||||||
|
<literal type="int" value="42" />
|
||||||
|
</rhs>
|
||||||
|
</operator>
|
15
ast_generator/test/xml/conditional_3.xml
Normal file
15
ast_generator/test/xml/conditional_3.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<operator op="!=" type="int">
|
||||||
|
<lhs>
|
||||||
|
<literal mut="var" type="int" value="False"/>
|
||||||
|
</lhs>
|
||||||
|
<rhs>
|
||||||
|
<operator op=">" type="int">
|
||||||
|
<lhs>
|
||||||
|
<literal mut="var" type="int" value="43"/>
|
||||||
|
</lhs>
|
||||||
|
<rhs>
|
||||||
|
<literal type="int" value="42" />
|
||||||
|
</rhs>
|
||||||
|
</operator>
|
||||||
|
</rhs>
|
||||||
|
</operator>
|
101
ast_generator/tiny_py_unparse.py
Normal file
101
ast_generator/tiny_py_unparse.py
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
from ast_parser.general_unparser import GeneralUnparser
|
||||||
|
|
||||||
|
|
||||||
|
import warnings
|
||||||
|
from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
|
from ast_parser.gaz_unparser import GazUnparser
|
||||||
|
from ast_parser.general_unparser import GeneralUnparser
|
||||||
|
from constants import *
|
||||||
|
|
||||||
|
|
||||||
|
def to_python_type(ty):
|
||||||
|
if ty == GAZ_INT_KEY:
|
||||||
|
return "int"
|
||||||
|
elif ty == GAZ_BOOL_KEY:
|
||||||
|
return "bool"
|
||||||
|
elif ty == GAZ_FLOAT_KEY:
|
||||||
|
return "float"
|
||||||
|
elif ty == GAZ_CHAR_KEY:
|
||||||
|
return "str"
|
||||||
|
elif ty == GAZ_STRING_KEY:
|
||||||
|
return "str"
|
||||||
|
else:
|
||||||
|
raise Exception("Unknown type: " + ty)
|
||||||
|
|
||||||
|
|
||||||
|
def to_python_op(param, ty):
|
||||||
|
if param == "negation" or param == "subtraction":
|
||||||
|
return "-"
|
||||||
|
elif param == "addition" or param == "noop":
|
||||||
|
return "+"
|
||||||
|
elif param == "multiplication":
|
||||||
|
return "*"
|
||||||
|
elif param == "division" and ty != GAZ_INT_KEY:
|
||||||
|
return "/"
|
||||||
|
elif param == "division" and ty == GAZ_INT_KEY:
|
||||||
|
return "//"
|
||||||
|
elif param == "modulo":
|
||||||
|
return "%"
|
||||||
|
elif param == "power":
|
||||||
|
return "**"
|
||||||
|
elif param == "equality":
|
||||||
|
return "=="
|
||||||
|
elif param == "inequality":
|
||||||
|
return "!="
|
||||||
|
elif param == "less-than":
|
||||||
|
return "<"
|
||||||
|
elif param == "less-than-or-equal":
|
||||||
|
return "<="
|
||||||
|
elif param == "greater-than":
|
||||||
|
return ">"
|
||||||
|
elif param == "greater-than-or-equal":
|
||||||
|
return ">="
|
||||||
|
elif param == "xor":
|
||||||
|
return "!="
|
||||||
|
else:
|
||||||
|
warnings.warn("Warning, unknown operator: " + param)
|
||||||
|
return param
|
||||||
|
|
||||||
|
|
||||||
|
class TinyPyUnparser(GeneralUnparser):
|
||||||
|
def __init__(self, ast: ET.Element, debug=False):
|
||||||
|
super().__init__(ast, debug,
|
||||||
|
endline='\n',
|
||||||
|
outstream_begin_delimiter="gprint(",
|
||||||
|
outstream_end_delimiter=", end='')",
|
||||||
|
function_return_type_indicator_predicate="->",
|
||||||
|
loop_start_delimiter="while ",
|
||||||
|
loop_end_delimiter=":",
|
||||||
|
conditional_case_delimiter="elif ",
|
||||||
|
conditional_start_delimiter="if ",
|
||||||
|
conditional_else_delimiter="else:",
|
||||||
|
conditional_end_delimiter=":",
|
||||||
|
block_start_delimiter="",
|
||||||
|
block_end_delimiter="", # TODO can this contain the pass?
|
||||||
|
strip_conditionals=True)
|
||||||
|
|
||||||
|
self.source = ''
|
||||||
|
|
||||||
|
def format_variable(self, mut, ty, name, declaration: bool = False):
|
||||||
|
if declaration:
|
||||||
|
return "{}: {}".format(name, ty)
|
||||||
|
else:
|
||||||
|
return "{}".format(name)
|
||||||
|
|
||||||
|
def translate_value(self, val):
|
||||||
|
return str(val)
|
||||||
|
|
||||||
|
def translate_op(self, param, ty=None):
|
||||||
|
return to_python_op(param, ty)
|
||||||
|
|
||||||
|
def translate_type(self, ty):
|
||||||
|
return to_python_type(ty)
|
||||||
|
|
||||||
|
def unparse_block(self, node):
|
||||||
|
raise TypeError("Cannot unparse blocks for this type of evaluation")
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,13 @@ from constants import GAZ_VAR_TAG, GAZ_ARG_TAG
|
||||||
|
|
||||||
|
|
||||||
class Variable:
|
class Variable:
|
||||||
def __init__(self, name: str, type: str, qualifier: str, value: any = None):
|
def __init__(self, name: str, type: str, qualifier: str, value: any = None): # decl_xml: ET.Element = None,
|
||||||
self.name = name
|
self.name = name
|
||||||
self.type = type
|
self.type = type
|
||||||
self.value = value
|
self.value = value
|
||||||
self.qualifier = qualifier
|
self.qualifier = qualifier
|
||||||
self.xml = self._build_xml()
|
self.xml = self._build_xml()
|
||||||
|
# self.decl_xml = decl_xml
|
||||||
|
|
||||||
def _build_xml(self):
|
def _build_xml(self):
|
||||||
args = [
|
args = [
|
||||||
|
|
|
@ -4,7 +4,7 @@ generation-options:
|
||||||
max-nesting-depth: 5 # maximum nesting depth for statements
|
max-nesting-depth: 5 # maximum nesting depth for statements
|
||||||
max-conditionals-loops: 5 # maximum number of loops/conditionals per routine
|
max-conditionals-loops: 5 # maximum number of loops/conditionals per routine
|
||||||
max-number-of-routines: 5 # maximum number of routines (main will always be generated)
|
max-number-of-routines: 5 # maximum number of routines (main will always be generated)
|
||||||
generate-dead-code: True # generate dead code
|
generate-dead-code: False # generate dead code
|
||||||
max-loop-iterations: 100 # maximum number of iterations in a loop
|
max-loop-iterations: 100 # maximum number of iterations in a loop
|
||||||
max-globals: 5 # maximum number of global variables
|
max-globals: 5 # maximum number of global variables
|
||||||
properties:
|
properties:
|
||||||
|
@ -90,9 +90,7 @@ misc-weights:
|
||||||
type-qualifier-weights:
|
type-qualifier-weights:
|
||||||
const: 10
|
const: 10
|
||||||
var: 60
|
var: 60
|
||||||
conditional-eval:
|
truthiness: 0.99 # Probability of conditionals being true
|
||||||
true: 50
|
|
||||||
false: 50
|
|
||||||
|
|
||||||
block-termination-probability: 0.2 # probability for a block to terminate
|
block-termination-probability: 0.2 # probability for a block to terminate
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,6 @@ class GazpreaFuzzer:
|
||||||
|
|
||||||
def fuzz(self):
|
def fuzz(self):
|
||||||
self.generator.generate_ast()
|
self.generator.generate_ast()
|
||||||
self.write_ast() # FIXME sometimes this is none
|
|
||||||
|
|
||||||
self.gaz_source_gen = GazUnparser(self.generator.ast, True)
|
self.gaz_source_gen = GazUnparser(self.generator.ast, True)
|
||||||
try:
|
try:
|
||||||
|
@ -56,6 +55,7 @@ class GazpreaFuzzer:
|
||||||
pass
|
pass
|
||||||
# exec(str(self.ground_truth))
|
# exec(str(self.ground_truth))
|
||||||
# exec(self.ground_truth, globals(), locals()) # FIXME the exec doesn't actually execute for some reason...
|
# exec(self.ground_truth, globals(), locals()) # FIXME the exec doesn't actually execute for some reason...
|
||||||
|
self.write_ast() # FIXME sometimes this is none
|
||||||
|
|
||||||
self.out = buf.getvalue()
|
self.out = buf.getvalue()
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
from constants import NoneTagException
|
from constants import NoneTagException
|
||||||
|
|
||||||
|
import signal as sig
|
||||||
|
|
||||||
|
|
||||||
def gprint(expr, end=''):
|
def gprint(expr, end=''):
|
||||||
if type(expr) is bool:
|
if type(expr) is bool:
|
||||||
|
@ -37,6 +39,9 @@ class Fuzzer():
|
||||||
self.fuzzer = fz.GazpreaFuzzer(config)
|
self.fuzzer = fz.GazpreaFuzzer(config)
|
||||||
|
|
||||||
def fuzz(self):
|
def fuzz(self):
|
||||||
|
sig.signal(sig.SIGALRM, handler)
|
||||||
|
sig.alarm(30)
|
||||||
|
|
||||||
base_dir = os.getcwd()
|
base_dir = os.getcwd()
|
||||||
fuzzer_root = base_dir + '/fuzzer'
|
fuzzer_root = base_dir + '/fuzzer'
|
||||||
|
|
||||||
|
@ -71,7 +76,10 @@ class Fuzzer():
|
||||||
"Look for a top-level <argument> tag or send it to Ayrton and I'll see what I can see"
|
"Look for a top-level <argument> tag or send it to Ayrton and I'll see what I can see"
|
||||||
"".format(r))
|
"".format(r))
|
||||||
with open(f"{fuzzer_asterr}/{r}.xml", 'w') as f:
|
with open(f"{fuzzer_asterr}/{r}.xml", 'w') as f:
|
||||||
f.write(xml.dom.minidom.parseString(ET.tostring(self.fuzzer.ast).decode('utf-8')).toprettyxml())
|
try:
|
||||||
|
f.write(xml.dom.minidom.parseString(ET.tostring(self.fuzzer.ast).decode('utf-8')).toprettyxml())
|
||||||
|
except AttributeError:
|
||||||
|
print("Failed to write to the file", file=sys.stderr)
|
||||||
if i - 1 >= min_i:
|
if i - 1 >= min_i:
|
||||||
i -= 1
|
i -= 1
|
||||||
else:
|
else:
|
||||||
|
@ -90,7 +98,7 @@ class Fuzzer():
|
||||||
exec(read, globals())
|
exec(read, globals())
|
||||||
except (OverflowError, ZeroDivisionError, ValueError, TypeError, SyntaxError):
|
except (OverflowError, ZeroDivisionError, ValueError, TypeError, SyntaxError):
|
||||||
os.system("rm -f {}/{}_{}.py".format(fuzzer_ground_truth, self.file_name, i))
|
os.system("rm -f {}/{}_{}.py".format(fuzzer_ground_truth, self.file_name, i))
|
||||||
os.system("rm -f {}/{}_{}.py".format(fuzzer_outputs, self.file_name, i))
|
os.system("rm -f {}/{}_{}.out".format(fuzzer_outputs, self.file_name, i))
|
||||||
warnings.warn("Runtime error encountered, retrying")
|
warnings.warn("Runtime error encountered, retrying")
|
||||||
if i - 1 >= min_i:
|
if i - 1 >= min_i:
|
||||||
i -= 1
|
i -= 1
|
||||||
|
@ -105,6 +113,32 @@ class Fuzzer():
|
||||||
f.write(xml.dom.minidom.parseString(
|
f.write(xml.dom.minidom.parseString(
|
||||||
ET.tostring(self.fuzzer.ast).decode('utf-8')).toprettyxml())
|
ET.tostring(self.fuzzer.ast).decode('utf-8')).toprettyxml())
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
except TimeoutError:
|
||||||
|
r = random.randint(0, 1000000)
|
||||||
|
warnings.warn("Execution timed out, result written to debug/ast/{}.xml\n"
|
||||||
|
"".format(r))
|
||||||
|
with open("{}/{}.xml".format(fuzzer_asterr, r), 'w') as f:
|
||||||
|
f.write(xml.dom.minidom.parseString(
|
||||||
|
ET.tostring(self.fuzzer.ast).decode('utf-8')).toprettyxml())
|
||||||
|
if i - 1 >= min_i:
|
||||||
|
i -= 1
|
||||||
|
else:
|
||||||
|
i = min_i
|
||||||
|
continue
|
||||||
|
|
||||||
|
with open("{}/{}_{}.out".format(fuzzer_outputs, self.file_name, i), 'r') as y:
|
||||||
|
out = y.read()
|
||||||
|
if out == "":
|
||||||
|
print("Empty output, skipping", file=sys.stderr)
|
||||||
|
os.system("rm -f {}/{}_{}.py".format(fuzzer_ground_truth, self.file_name, i))
|
||||||
|
os.system("rm -f {}/{}_{}.out".format(fuzzer_outputs, self.file_name, i))
|
||||||
|
if i - 1 >= min_i:
|
||||||
|
i -= 1
|
||||||
|
else:
|
||||||
|
i = min_i
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
with open("{}/{}_{}.in".format(fuzzer_input, self.file_name, i), 'w') as f:
|
with open("{}/{}_{}.in".format(fuzzer_input, self.file_name, i), 'w') as f:
|
||||||
f.write(self.fuzzer.source)
|
f.write(self.fuzzer.source)
|
||||||
with open("{}/{}_{}.xml".format(fuzzer_debug, self.file_name, i), 'w') as f:
|
with open("{}/{}_{}.xml".format(fuzzer_debug, self.file_name, i), 'w') as f:
|
||||||
|
@ -114,11 +148,19 @@ class Fuzzer():
|
||||||
# f.write(self.fuzzer.source)
|
# f.write(self.fuzzer.source)
|
||||||
# with open("fuzzer/outputs/{}.out".format(i), 'w') as f:
|
# with open("fuzzer/outputs/{}.out".format(i), 'w') as f:
|
||||||
# f.write(self.fuzzer.out)
|
# f.write(self.fuzzer.out)
|
||||||
|
print("test {}/{} generated".format(i, self.batch))
|
||||||
i += 1
|
i += 1
|
||||||
min_i = i
|
min_i = i
|
||||||
|
|
||||||
|
|
||||||
|
def handler(signum, frame):
|
||||||
|
print("Execution Timeout")
|
||||||
|
raise TimeoutError
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='Procedurally generate a test case for Gazprea'
|
description='Procedurally generate a test case for Gazprea'
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue