def process_parsed_package(parsed_package): ''' Process the 'use' clauses in a parsed file to get a list of the package dependencies. ''' p_constants = parsed_package.packages[0].constants p_types = get_types(parsed_package.packages[0]) constants = {} for c in p_constants: if c.text == '': # This typically happens when a parameters file has been generated # incorrectly. raise Exception('Constant {} has no value to parse'.format( c.identifier)) constants[c.identifier] = symbolic_math.parse_and_simplify(c.text) processed_types = [(t.identifier, typ_parser.process_parsed_type(t)) for t in p_types] # Filter out the types that could not be processed. types = dict([(k, v) for k, v in processed_types if v is not None]) failed_type_keys = [k for k, v in processed_types if v is None] if failed_type_keys: logger.warning('Failed to parse types {}'.format(failed_type_keys)) uses = get_parsed_package_dependencies(parsed_package) p = UnresolvedPackage( identifier=parsed_package.packages[0].identifier, types=types, constants=constants, uses=uses, ) return p
def test_substitute(): string = 'fish + 3 * bear * shark / house' simplified = sm.parse_and_simplify(string) substituted = sm.make_substitute_function({ 'fish': 2, 'bear': 4, 'shark': 3, 'house': 2, })(simplified) final = sm.simplify(substituted) assert final == 2 + 3 * 4 * 3 / 2
def get_range_bounds(type_range): _type_range_re = re.compile( r""" \s*range \s*(?P<range_left>.+?) \s+(?P<direction>to|downto)\s+ (?P<range_right>.+?)\s* """, re.MULTILINE | re.IGNORECASE | re.VERBOSE | re.DOTALL) match = _type_range_re.match(type_range) if match: gd = match.groupdict() if gd['direction'] == 'to': high = gd['range_right'] low = gd['range_left'] elif gd['direction'] == 'downto': high = gd['range_left'] low = gd['range_right'] high_expr = symbolic_math.parse_and_simplify(high) low_expr = symbolic_math.parse_and_simplify(low) else: raise Exception('Failed to parse constraint.') return low_expr, high_expr
def get_bounds(type_range): if type_range is None: upper = None lower = None else: if type_range.direction == 'to': upper = type_range.right lower = type_range.left elif type_range.direction == 'downto': upper = type_range.left lower = type_range.right else: assert (type_range.left is None) assert (type_range.right is None) upper = None lower = None if (upper is None) and (lower is None): upper_expression = None lower_expression = None else: upper_expression = symbolic_math.parse_and_simplify(upper) lower_expression = symbolic_math.parse_and_simplify(lower) return lower_expression, upper_expression
def get_constraint_bounds(constraint): _constrained_range_re = re.compile( r""" \s*\( \s*(?P<range_left>.+?) \s+(?P<direction>to|downto)\s+ (?P<range_right>.+?)\s* \)\s*""", re.MULTILINE | re.IGNORECASE | re.VERBOSE | re.DOTALL) match = _constrained_range_re.match(constraint) if match: gd = match.groupdict() if gd['direction'] == 'to': high = gd['range_right'] low = gd['range_left'] elif gd['direction'] == 'downto': high = gd['range_left'] low = gd['range_right'] high_expr = symbolic_math.parse_and_simplify(high) low_expr = symbolic_math.parse_and_simplify(low) size_as_string = '{} + 1 - {}'.format(high, low) size = symbolic_math.parse_and_simplify(size_as_string) else: raise Exception('Failed to parse constraint.') return high_expr, low_expr
def test_simplifications(): ins_and_outs = ( ('fish + 8*bear + 2 * (fish - bear)', ('(3*fish+6*bear)', '(6*bear+3*fish)')), ('4 + (4 - 4) * 2 - 3', ('1', )), ('7 * 7', ('49', )), ('2 * (3 + 5)', ('16', )), ('logceil(5+3)-2', ('1', )), ('1 + 1', ('2', )), ('(logceil(5*4)-1)+1-0', ('5', )), ('3 * 2 / fish / (3 / 4)', ('8/fish', '8*1/fish')), ('fish + 1 - 1', ('fish', )), ('(fish + 1) - 1', ('fish', )), ('fish + 2 * fish', ('3*fish', )), ) for in_string, expected_strings in ins_and_outs: simplified = sm.parse_and_simplify(in_string) out_string = sm.str_expression(simplified) assert out_string in expected_strings
def test_empty_constant_list(): string = '3 * 12' simplified = sm.parse_and_simplify(string) constants = sm.get_constant_list(simplified) assert constants == set()
def test_constant_list(): string = '3 * (fish + 6) - 2 * bear - fish' simplified = sm.parse_and_simplify(string) constants = sm.get_constant_list(simplified) assert constants == set(['fish', 'bear'])
def get_constraint_size(constraint): high, low = get_constraint_bounds(constraint) size = symbolic_math.parse_and_simplify('{} + 1 - {}'.format( symbolic_math.str_expression(high), symbolic_math.str_expression(low))) return size