Fixed anti-parsing errors in python
Took 1 hour 2 minutes
This commit is contained in:
parent
4ee1770092
commit
04675a01d6
|
@ -240,6 +240,7 @@ class GeneralUnparser:
|
||||||
else:
|
else:
|
||||||
self.source += (self.conditional_delimiters[1] + " ")
|
self.source += (self.conditional_delimiters[1] + " ")
|
||||||
elif node.tag == GAZ_BLOCK_TAG:
|
elif node.tag == GAZ_BLOCK_TAG:
|
||||||
|
self.source += self.indentation * self.indentation_character
|
||||||
if node.get(GAZ_TY_KEY) == GAZ_TRUE_BLOCK_TAG:
|
if node.get(GAZ_TY_KEY) == GAZ_TRUE_BLOCK_TAG:
|
||||||
self.unparse_node(node)
|
self.unparse_node(node)
|
||||||
elif node.get(GAZ_TY_KEY) == GAZ_FALSE_BLOCK_TAG:
|
elif node.get(GAZ_TY_KEY) == GAZ_FALSE_BLOCK_TAG:
|
||||||
|
@ -267,7 +268,7 @@ class GeneralUnparser:
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
def unparse_unary(self, element_in: ET.Element):
|
def unparse_unary(self, element_in: ET.Element):
|
||||||
self.source += " {}".format(self.translate_op(element_in.get("op")))
|
self.source += "{}".format(self.translate_op(element_in.get("op")))
|
||||||
self.unparse_xhs(element_in.find(GAZ_RHS_TAG))
|
self.unparse_xhs(element_in.find(GAZ_RHS_TAG))
|
||||||
|
|
||||||
def unparse_single_arg(self, param):
|
def unparse_single_arg(self, param):
|
||||||
|
|
|
@ -92,3 +92,16 @@ class PythonUnparser(GeneralUnparser):
|
||||||
|
|
||||||
def format_single_arg(self, ty, name):
|
def format_single_arg(self, ty, name):
|
||||||
return "{}: {}".format(name, ty)
|
return "{}: {}".format(name, ty)
|
||||||
|
|
||||||
|
def unparse_block(self, node):
|
||||||
|
super().unparse_block(node)
|
||||||
|
self.source += f"{self.block_delimiters[0]}\n"
|
||||||
|
self.indentation += 4
|
||||||
|
for child in node:
|
||||||
|
self.unparse_node(child)
|
||||||
|
self.source += self.indentation_character * self.indentation + "pass\n"
|
||||||
|
self.indentation -= 4
|
||||||
|
if node.get(GAZ_TY_KEY) is None:
|
||||||
|
self.source += f"{self.block_delimiters[1]}\n\n"
|
||||||
|
elif node.get(GAZ_TY_KEY) in [GAZ_TRUE_BLOCK_TAG, GAZ_FALSE_BLOCK_TAG]:
|
||||||
|
self.source += f"{self.block_delimiters[1]}"
|
||||||
|
|
0
fuzzer/ground_truth/ee
Normal file
0
fuzzer/ground_truth/ee
Normal file
94
test/config.yaml
Normal file
94
test/config.yaml
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
# The default configuration for the Gazprea Fuzzer
|
||||||
|
---
|
||||||
|
generation-options:
|
||||||
|
max-nesting-depth: 5 # maximum nesting depth for statements
|
||||||
|
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)
|
||||||
|
generate-dead-code: True # generate dead code
|
||||||
|
properties:
|
||||||
|
max-range-length: 5 # maximum length of ranges, vectors and tuples, (AxA matrices can exist)
|
||||||
|
use-english-words: True # use english words instead of random names (this may limit the maximum number of names)
|
||||||
|
id-length: # length of identifiers
|
||||||
|
min: 1
|
||||||
|
max: 10
|
||||||
|
function-name-length: # length of function names
|
||||||
|
min: 1
|
||||||
|
max: 10
|
||||||
|
number-of-arguments: # number of arguments to a routine
|
||||||
|
min: 1
|
||||||
|
max: 10
|
||||||
|
generate-max-int: True # if False, generate integers between [-1000, 1000] else
|
||||||
|
expression-weights: # weights for expressions
|
||||||
|
# the higher a weight, the more likely (0, 10000), 0 to exclude, 10000 for only that
|
||||||
|
brackets: 10
|
||||||
|
|
||||||
|
arithmetic:
|
||||||
|
addition: 80
|
||||||
|
subtraction: 80
|
||||||
|
multiplication: 30
|
||||||
|
division: 10
|
||||||
|
modulo: 10
|
||||||
|
power: 5
|
||||||
|
|
||||||
|
comparison:
|
||||||
|
equality: 50
|
||||||
|
inequality: 50
|
||||||
|
less-than: 30
|
||||||
|
greater-than: 30
|
||||||
|
less-than-or-equal: 10
|
||||||
|
greater-than-or-equal: 10
|
||||||
|
|
||||||
|
logical:
|
||||||
|
and: 50
|
||||||
|
or: 50
|
||||||
|
xor: 10
|
||||||
|
|
||||||
|
vector-or-string:
|
||||||
|
generator: 20
|
||||||
|
range: 30
|
||||||
|
filter: 10
|
||||||
|
reverse: 10
|
||||||
|
concatenation: 50
|
||||||
|
|
||||||
|
unary:
|
||||||
|
noop: 10
|
||||||
|
negation: 20
|
||||||
|
not: 10
|
||||||
|
|
||||||
|
|
||||||
|
statement-weights: # set to 0 for any statements you wish to exclude
|
||||||
|
variable-declaration: 50
|
||||||
|
routine-call: 20
|
||||||
|
conditional: 30
|
||||||
|
loop: 20
|
||||||
|
assignment: 40
|
||||||
|
out-stream: 20
|
||||||
|
in-stream: 5
|
||||||
|
|
||||||
|
type-weights:
|
||||||
|
value-types:
|
||||||
|
integer: 50
|
||||||
|
real: 50
|
||||||
|
boolean: 50
|
||||||
|
character: 50
|
||||||
|
void: 10
|
||||||
|
composite-types:
|
||||||
|
vector: 20
|
||||||
|
tuple: 5
|
||||||
|
matrix: 10
|
||||||
|
string: 10
|
||||||
|
composite: 0 #TODO add support for composite types
|
||||||
|
atomic: 40
|
||||||
|
|
||||||
|
routine-weights:
|
||||||
|
procedure: 20
|
||||||
|
function: 50
|
||||||
|
|
||||||
|
misc-weights:
|
||||||
|
type-qualifier-weights:
|
||||||
|
const: 10
|
||||||
|
var: 60
|
||||||
|
|
||||||
|
block-termination-probability: 0.2 # probability for a block to terminate
|
||||||
|
|
||||||
|
|
134
test/test_correctness.py
Normal file
134
test/test_correctness.py
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
from contextlib import redirect_stdout
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import signal
|
||||||
|
|
||||||
|
from ast_generator.ast_generator import AstGenerator
|
||||||
|
from ast_parser.python_unparser import PythonUnparser
|
||||||
|
|
||||||
|
|
||||||
|
class MyTestCase(unittest.TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
with open("config.yaml", 'r') as stream:
|
||||||
|
cls.props = yaml.safe_load(stream)
|
||||||
|
|
||||||
|
def setUp(cls):
|
||||||
|
cls.ast_gen = AstGenerator(cls.props)
|
||||||
|
cls.python_unparser = PythonUnparser(cls.ast_gen.ast, True)
|
||||||
|
def test_assignment(self):
|
||||||
|
self.ast_gen.ast = ET.Element("block")
|
||||||
|
self.ast_gen.current_ast_element = self.ast_gen.ast
|
||||||
|
self.ast_gen.generate_declaration()
|
||||||
|
self.ast_gen.generate_assignment()
|
||||||
|
|
||||||
|
self.python_unparser.xml = self.ast_gen.ast
|
||||||
|
self.python_unparser.unparse()
|
||||||
|
|
||||||
|
try:
|
||||||
|
exec(self.python_unparser.source)
|
||||||
|
except Exception as e:
|
||||||
|
self.fail(e)
|
||||||
|
|
||||||
|
def test_binary_operator(self):
|
||||||
|
self.ast_gen.ast = ET.Element("block")
|
||||||
|
self.ast_gen.current_ast_element = self.ast_gen.ast
|
||||||
|
self.ast_gen.generate_declaration()
|
||||||
|
self.ast_gen.generate_binary('addition', 'int')
|
||||||
|
|
||||||
|
self.python_unparser.xml = self.ast_gen.ast
|
||||||
|
self.python_unparser.unparse()
|
||||||
|
|
||||||
|
try:
|
||||||
|
exec(self.python_unparser.source)
|
||||||
|
except Exception as e:
|
||||||
|
self.fail(e)
|
||||||
|
|
||||||
|
def test_unary_operator(self):
|
||||||
|
self.ast_gen.ast = ET.Element("block")
|
||||||
|
self.ast_gen.current_ast_element = self.ast_gen.ast
|
||||||
|
self.ast_gen.generate_declaration()
|
||||||
|
self.ast_gen.generate_unary('negation', 'int')
|
||||||
|
|
||||||
|
self.python_unparser.xml = self.ast_gen.ast
|
||||||
|
self.python_unparser.unparse()
|
||||||
|
|
||||||
|
try:
|
||||||
|
exec(self.python_unparser.source)
|
||||||
|
except Exception as e:
|
||||||
|
print(self.python_unparser.source)
|
||||||
|
self.fail(e)
|
||||||
|
|
||||||
|
def test_output(self):
|
||||||
|
self.ast_gen.ast = ET.Element("block")
|
||||||
|
self.ast_gen.current_ast_element = self.ast_gen.ast
|
||||||
|
self.ast_gen.generate_out_stream()
|
||||||
|
|
||||||
|
output = StringIO()
|
||||||
|
|
||||||
|
self.python_unparser.xml = self.ast_gen.ast
|
||||||
|
self.python_unparser.unparse()
|
||||||
|
|
||||||
|
with redirect_stdout(output):
|
||||||
|
exec(self.python_unparser.source)
|
||||||
|
|
||||||
|
try:
|
||||||
|
exec(output.getvalue())
|
||||||
|
except Exception as e:
|
||||||
|
self.fail(e)
|
||||||
|
|
||||||
|
outstring = output.getvalue()
|
||||||
|
self.assertNotEqual("", outstring, self.python_unparser.source)
|
||||||
|
|
||||||
|
def test_input(self): #FIXME this doesn't actually accept user input, I think I need to create a global dict
|
||||||
|
# to store the input and then access it from the python in some way...
|
||||||
|
self.ast_gen.ast = ET.Element("block")
|
||||||
|
self.ast_gen.current_ast_element = self.ast_gen.ast
|
||||||
|
self.ast_gen.generate_in_stream()
|
||||||
|
|
||||||
|
self.python_unparser.xml = self.ast_gen.ast
|
||||||
|
self.python_unparser.unparse()
|
||||||
|
|
||||||
|
try:
|
||||||
|
exec(self.python_unparser.source)
|
||||||
|
except Exception as e:
|
||||||
|
self.fail(e)
|
||||||
|
|
||||||
|
def test_conditional(self):
|
||||||
|
self.ast_gen.ast = ET.Element("block")
|
||||||
|
self.ast_gen.current_ast_element = self.ast_gen.ast
|
||||||
|
self.ast_gen.generate_conditional()
|
||||||
|
|
||||||
|
self.python_unparser.xml = self.ast_gen.ast
|
||||||
|
self.python_unparser.unparse()
|
||||||
|
|
||||||
|
try:
|
||||||
|
exec(self.python_unparser.source)
|
||||||
|
except Exception as e:
|
||||||
|
print(self.python_unparser.source)
|
||||||
|
self.fail(e)
|
||||||
|
|
||||||
|
def test_loop(self):
|
||||||
|
self.ast_gen.ast = ET.Element("block")
|
||||||
|
self.ast_gen.current_ast_element = self.ast_gen.ast
|
||||||
|
self.ast_gen.generate_loop()
|
||||||
|
|
||||||
|
self.python_unparser.xml = self.ast_gen.ast
|
||||||
|
self.python_unparser.unparse()
|
||||||
|
|
||||||
|
try:
|
||||||
|
exec(self.python_unparser.source)
|
||||||
|
except Exception as e:
|
||||||
|
print(self.python_unparser.source)
|
||||||
|
self.fail(e)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
Reference in a new issue