def __parse_if_else_expression__(self, symbol_node: jcmuta.SymbolNode, code: int): condition = self.__parse__(symbol_node.get_child(0), code) loperand = self.__parse__(symbol_node.get_child(1), code) roperand = self.__parse__(symbol_node.get_child(2), code) condition = self.__cast_to_bool__(condition) return z3.If(condition, loperand, roperand)
def __parse_call_expression__(self, symbol_node: jcmuta.SymbolNode): function = symbol_node.get_child(0) if function.get_class_name() == "Identifier": func_name = function.get_content().get_token_value() else: func_name = self.__new_default_name__(function) arguments = symbol_node.get_child(1).get_children() for k in range(0, len(arguments)): arg = self.__parse__(arguments[k]) self.__save__("{}#{}".format(func_name, k), arg) return self.__parse_by_name__( "{}_{}".format(func_name, symbol_node.get_class_id()), symbol_node.get_data_type())
def __parse_unary_expression__(self, symbol_node: jcmuta.SymbolNode, code: int): """ :param symbol_node: negative, bit_not, logic_not, address_of, dereference :param code: :return: """ operator = symbol_node.get_content().get_token_value() operand = symbol_node.get_child(1) if operator == "negative": u_operand = self.__parse__(operand, code) return -self.__cast_to_numb__(u_operand) elif operator == "bit_not": u_operand = self.__parse__(operand, self.__s_code__) return ~self.__cast_to_bits__(u_operand) elif operator == "logic_not": u_operand = self.__parse__(operand, code) return z3.Not(self.__cast_to_bool__(u_operand)) elif operator == "address_of": return z3.Const(self.__unique_name__(symbol_node), z3.IntSort()) else: name = self.__unique_name__(symbol_node) name = self.__normal_name__(name, symbol_node.get_data_type()) return self.__new_reference__(name, symbol_node.get_data_type(), code)
def __parse_bitws_expression__(self, symbol_node: jcmuta.SymbolNode): operator = str(symbol_node.get_content().get_token_value()).strip() self.bitSwitch = True loperand = self.__parse__(symbol_node.get_child(1)) self.bitSwitch = True roperand = self.__parse__(symbol_node.get_child(2)) self.bitSwitch = False if operator == "bit_and": return loperand & roperand elif operator == "bit_or": return loperand | roperand elif operator == "bit_xor": return loperand ^ roperand elif operator == "left_shift": return loperand << roperand else: return loperand >> roperand
def __parse_call_expression__(self, symbol_node: jcmuta.SymbolNode, code: int): """ :param symbol_node: :param code: :return: """ function = symbol_node.get_child(0) if function.get_class_name() == "Identifier": func_name = function.get_content().get_token_value() else: func_name = self.__unique_name__(function) arguments = symbol_node.get_child(1).get_children() for k in range(0, len(arguments)): arg = self.__parse__(arguments[k], 0) self.__save_state__("{}#{}".format(func_name, k), arg) return self.__new_reference__(func_name, symbol_node.get_data_type(), code)
def __parse_logic_expression__(self, symbol_node: jcmuta.SymbolNode, code: int): """ :param symbol_node: :param code: :return: """ operator = symbol_node.get_content().get_token_value() loperand = self.__cast_to_bool__( self.__parse__(symbol_node.get_child(1), code)) roperand = self.__cast_to_bool__( self.__parse__(symbol_node.get_child(2), code)) if operator == "logic_and": return z3.And(loperand, roperand) elif operator == "logic_or": return z3.Or(loperand, roperand) else: return z3.Implies(loperand, roperand)
def __parse_assign_expression__(self, symbol_node: jcmuta.SymbolNode): operator = str(symbol_node.get_content().get_token_value()).strip() loperand = self.__parse__(symbol_node.get_child(1)) roperand = self.__parse__(symbol_node.get_child(2)) self.__save__(loperand.sexpr(), roperand) if operator == "assign": return roperand else: return loperand
def __parse_logic_expression__(self, symbol_node: jcmuta.SymbolNode): operator = str(symbol_node.get_content().get_token_value()).strip() loperand = self.__parse__(symbol_node.get_child(1)) roperand = self.__parse__(symbol_node.get_child(2)) loperand = self.__cast_to_bool__(loperand) roperand = self.__cast_to_bool__(roperand) if operator == "logic_and": return z3.And(loperand, roperand) else: return z3.Or(loperand, roperand)
def __parse_bitws_expression__(self, symbol_node: jcmuta.SymbolNode): """ :param symbol_node: :return: """ operator = symbol_node.get_content().get_token_value() loperand = self.__cast_to_bits__( self.__parse__(symbol_node.get_child(1), self.__s_code__)) roperand = self.__cast_to_bits__( self.__parse__(symbol_node.get_child(2), self.__s_code__)) if operator == "bit_and": return loperand & roperand elif operator == "bit_or": return loperand | roperand elif operator == "bit_xor": return loperand ^ roperand elif operator == "left_shift": return loperand << roperand else: return loperand >> roperand
def __parse_arith_expression__(self, symbol_node: jcmuta.SymbolNode, code: int): """ :param symbol_node: +, -, *, /, % :param code: :return: """ operator = symbol_node.get_content().get_token_value() loperand = self.__cast_to_numb__( self.__parse__(symbol_node.get_child(1), code)) roperand = self.__cast_to_numb__( self.__parse__(symbol_node.get_child(2), code)) if operator == "arith_add": return loperand + roperand elif operator == "arith_sub": return loperand - roperand elif operator == "arith_mul": return loperand * roperand elif operator == "arith_div": return loperand / roperand else: return loperand % roperand
def __parse_relation_expression__(self, symbol_node: jcmuta.SymbolNode, code: int): """ :param symbol_node: :param code: :return: """ operator = symbol_node.get_content().get_token_value() loperand = self.__cast_to_numb__( self.__parse__(symbol_node.get_child(1), code)) roperand = self.__cast_to_numb__( self.__parse__(symbol_node.get_child(2), code)) if operator == "greater_tn": return loperand > roperand elif operator == "greater_eq": return loperand >= roperand elif operator == "smaller_tn": return loperand < roperand elif operator == "smaller_eq": return loperand <= roperand elif operator == "equal_with": return loperand == roperand else: return loperand != roperand
def __parse_relation_expression__(self, symbol_node: jcmuta.SymbolNode): operator = str(symbol_node.get_content().get_token_value()).strip() loperand = self.__parse__(symbol_node.get_child(1)) roperand = self.__parse__(symbol_node.get_child(2)) if operator == "greater_tn": return loperand > roperand elif operator == "greater_eq": return loperand >= roperand elif operator == "smaller_tn": return loperand < roperand elif operator == "smaller_eq": return loperand <= roperand elif operator == "equal_with": return loperand == roperand else: return loperand != roperand
def __parse_arith_expression__(self, symbol_node: jcmuta.SymbolNode): """ :param symbol_node: :return: """ operator = str(symbol_node.get_content().get_token_value()).strip() loperand = self.__parse__(symbol_node.get_child(1)) roperand = self.__parse__(symbol_node.get_child(2)) if operator == "arith_add": return loperand + roperand elif operator == "arith_sub": return loperand - roperand elif operator == "arith_mul": return loperand * roperand elif operator == "arith_div": return loperand / roperand else: return loperand % roperand
def __parse_unary_expression__(self, symbol_node: jcmuta.SymbolNode): """ :param symbol_node: :return: neg, rsv, not, adr, der """ operator = symbol_node.get_content().get_token_value() u_operand = self.__parse__(symbol_node.get_child(1)) if operator == "negative": return -u_operand elif operator == "bit_not": if isinstance(u_operand, z3.IntNumRef) or isinstance( u_operand, z3.ArithRef): return -u_operand - 1 else: return ~u_operand elif operator == "logic_not": return z3.Not(self.__cast_to_bool__(u_operand)) elif operator == "address_of": return z3.Const(self.__new_default_name__(symbol_node), z3.IntSort()) else: return self.__parse_by_name__( self.__new_default_name__(symbol_node), symbol_node.get_data_type())
def __parse_casted_expression__(self, symbol_node: jcmuta.SymbolNode, code: int): return self.__parse__(symbol_node.get_child(1), code)
def __parse_if_else_expression__(self, symbol_node: jcmuta.SymbolNode): condition = self.__parse__(symbol_node.get_child(0)) loperand = self.__parse__(symbol_node.get_child(1)) roperand = self.__parse__(symbol_node.get_child(2)) return z3.If(condition, loperand, roperand)