def compile_divide(p): if len(p) == 2: return ast.BinOp(ast.Num(1), ast.Div(), build_ast(p[1])) elif len(p) == 3: return ast.BinOp(build_ast(p[1]), ast.Div(), build_ast(p[2])) else: return ast.BinOp(compile_divide(p[:-1]), ast.Div(), build_ast(p[-1]))
def operator(mod): op = ast.Add() if mod == 'or': op = ast.Or() if mod == '|': op = ast.Or() if mod == '||': op = ast.Or() if mod == 'and': op = ast.And() if mod == '&': op = ast.And() if mod == '&&': op = ast.And() if mod == 'plus': op = ast.Add() if mod == '+': op = ast.Add() if mod == '-': op = ast.Sub() if mod == 'minus': op = ast.Sub() if mod == 'times': op = ast.Mult() if mod == '*': op = ast.Mult() if mod == '**': op = ast.Pow() if mod == 'divide': op = ast.Div() if mod == 'divided': op = ast.Div() if mod == 'divided by': op = ast.Div() if mod == '/': op = ast.Div() if mod == '//': op = ast.FloorDiv() if mod == 'floor div': op = ast.FloorDiv() if mod == '%': op = ast.Mod() if mod == 'mod': op = ast.Mod() if mod == 'modulus': op = ast.Mod() if mod == 'modulo': op = ast.Mod() if mod == '^': op = ast.BitXor() if mod == 'xor': op = ast.BitXor() if mod == '<<': op = ast.LShift() if mod == '>>': op = ast.RShift() return op
def visit_BinOp(self, node): # operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv print(" in MyTransformer.visit_BinOp()") print(" curr op =", node.op) bin_negate = node.op # use pseudorandomness to determine whether to negate or just mix up rand_num = random.randint(1, 10) # negate if rand_num >= 4: print(" negating...") if isinstance(node.op, ast.Add): bin_negate = ast.Sub() elif isinstance(node.op, ast.Sub): bin_negate = ast.Add() elif isinstance(node.op, ast.Mult): bin_negate = ast.Div() elif isinstance(node.op, ast.Div): bin_negate = ast.FloorDiv() elif isinstance(node.op, ast.FloorDiv): bin_negate = ast.Div() elif isinstance(node.op, ast.LShift): bin_negate = ast.RShift() elif isinstance(node.op, ast.RShift): bin_negate = ast.LShift() elif isinstance(node.op, ast.BitOr): bin_negate = ast.BitAnd() elif isinstance(node.op, ast.BitAnd): bin_negate = ast.BitXor() elif isinstance(node.op, ast.BitXor): bin_negate = ast.BitOr() elif isinstance(node.op, ast.Pow): bin_negate = ast.Mult() elif isinstance(node.op, ast.Mod): bin_negate = ast.Div() elif isinstance(node.op, ast.MatMult): bin_negate = ast.Mult() else: print(" did not find negation for", node.op) # mix up else: print(" mixing up...") if isinstance(node.op, ast.Add): bin_negate = ast.Mult() elif isinstance(node.op, ast.Sub): bin_negate = ast.Div() elif isinstance(node.op, ast.Mult): bin_negate = ast.Pow() elif isinstance(node.op, ast.Div): bin_negate = ast.FloorDiv() elif isinstance(node.op, ast.FloorDiv): bin_negate = ast.Div() elif isinstance(node.op, ast.BitOr): bin_negate = ast.BitXor() elif isinstance(node.op, ast.BitAnd): bin_negate = ast.BitOr() elif isinstance(node.op, ast.BitXor): bin_negate = ast.BitOr() elif isinstance(node.op, ast.Pow): bin_negate = ast.Mult() elif isinstance(node.op, ast.Mod): bin_negate = ast.FloorDiv() else: print(" did not find negation for", node.op) print(" bin_negate =", bin_negate) # create negated node | BinOp(expr left, operator op, expr right) new_node = node new_node.op = bin_negate ast.copy_location(new_node, node) ast.fix_missing_locations(new_node) return new_node
def ln(a, base=None): if base == None: return ast.BinOp( left=ast.Num(n=1), right=a, op=ast.Div(), ) else: return ast.BinOp( left=ast.Num(n=1), right=a, op=ast.Div(), )
def mutation_visit(self, node): replacement = { type(ast.Add()): ast.Sub(), type(ast.Sub()): ast.Add(), type(ast.Mult()): ast.Div(), type(ast.Div()): ast.Mult() } try: node.op = replacement[type(node.op)] except KeyError: pass # All other binary operators (and, mod, etc.) return node
def test_all_divisions(self): pat = ast.BinOp(op=ast.Div()) it = ASTPatternFinder(pat).scan_file(StringIO(division_sample)) assert_ast_like(next(it), ast.BinOp(left=ast.Num(n=1))) assert_ast_like(next(it), ast.BinOp(right=ast.Name(id='c'))) assert_ast_like(next(it), ast.BinOp(left=ast.Name(id='x'))) self.assert_no_more(it)
def visit_Operator(self, node: Operator, *args, **kwargs) -> C.operator: if node == Operator.Add: return C.Add() elif node == Operator.Sub: return C.Sub() elif node == Operator.Mult: return C.Mult() elif node == Operator.MatMult: return C.MatMult() elif node == Operator.Div: return C.Div() elif node == Operator.Mod: return C.Mod() elif node == Operator.Pow: return C.Pow() elif node == Operator.LShift: return C.LShift() elif node == Operator.RShift: return C.RShift() elif node == Operator.BitOr: return C.BitOr() elif node == Operator.BitXor: return C.BitXor() elif node == Operator.BitAnd: return C.BitAnd() elif node == Operator.FloorDiv: return C.FloorDiv() else: raise Exception(f'unknown Operator {node!r}')
def visit_Call(self, node): if node.func.id == 'Z' or node.func.id == 'SCALE': for kw in node.keywords: if kw.arg == 'group_by': kws = [kw] break else: if len(node.args) > 1: kws = [ast.keyword(arg='group_by', value=node.args[1])] else: kws = [] return ast.BinOp(left=ast.BinOp(left=node.args[0], op=ast.Sub(), right=ast.Call(func=ast.Name( id='VMEAN', ctx=ast.Load()), args=[node.args[0]], keywords=kws)), op=ast.Div(), right=ast.Call(func=ast.Name(id='VSTDEV', ctx=ast.Load()), args=[node.args[0]], keywords=kws)) else: return self.generic_visit(node)
def __init__(self, base_node): BaseMutator.__init__(self, base_node) self.original_bin_op = base_node.op if type(base_node.op) in [ ast.Add, ast.Sub, ast.Mult, ast.Div, ast.Mod, ast.Pow ]: if type(base_node.op) is ast.Add: # Don't perform the mutation for string concatenation (e.g. 'string' + 'concat') if (type(base_node.left) is not ast.Str) and (type( base_node.right) is not ast.Str): self.mutations.append({"op": ast.Sub()}) if type(base_node.op) is ast.Sub: self.mutations.append({"op": ast.Add()}) if type(base_node.op) is ast.Mult: # Don't perform the mutation for string repetition (e.g. 'string' * 50) if (type(base_node.left) is not ast.Str) and (type( base_node.right) is not ast.Str): self.mutations.append({"op": ast.Div()}) if type(base_node.op) is ast.Div: self.mutations.append({"op": ast.Mult()}) if type(base_node.op) is ast.Mod: # Don't perform the mutation for string format (e.g. 'strings are %s' % 'cool') if (type(base_node.left) is not ast.Str) and (type( base_node.right) is not ast.Str): self.mutations.append({"op": ast.Pow()}) if type(base_node.op) is ast.Pow: self.mutations.append({"op": ast.Mod()})
def binop_action(s, loc, tokens): node = tokens[0] for op_char, right in tokens[1:]: if op_char == '+': op = ast.Add() elif op_char == '-': op = ast.Sub() elif op_char == '*': op = ast.Mult() elif op_char == '/': op = ast.Div() elif op_char == '%': op = ast.Mod() elif op_char == '<<': op = ast.LShift() elif op_char == '>>': op = ast.RShift() elif op_char == '&': op = ast.BitAnd() elif op_char == '^': op = ast.BitXor() else: # op_char == '|': op = ast.BitOr() node = ast.BinOp(left=node, op=op, right=right, lineno=1, col_offset=0) return node
def visit_BinOp(self, node): # TODO: handle floor devision node.left = self.visit(node.left) node.right = self.visit(node.right) if isinstance(node.op, ast.Pow): node = self.pow(node.left, node.right) return self.visit(node) v1, v2 = node.left.variable, node.right.variable promotion_type = self.promote(v1, v2) if not (v1.type.is_array and v2.type.is_array): # Don't coerce arrays to lesser or higher dimensionality # Broadcasting transforms should take care of this node.left, node.right = nodes.CoercionNode.coerce( [node.left, node.right], promotion_type) node.variable = Variable(promotion_type) if isinstance(node.op, ast.FloorDiv): dst_type = self.promote(node.left.variable, node.right.variable) if dst_type.is_float or dst_type.is_int: node.op = ast.Div() node = nodes.CoercionNode(node, long_) node = nodes.CoercionNode(node, dst_type) return node
def get_bin_op(self, s): """Get the BinOp class for s.""" op = None if s == '+': op = ast.Add() elif s == '-': op = ast.Sub() elif s == '*': op = ast.Mult() elif s == '/': op = ast.Div() elif s == '%': op = ast.Mod() elif s == '<<': op = ast.LShift() elif s == '>>': op = ast.RShift() elif s == '&': op = ast.BitAnd() elif s == '^': op = ast.BitXor() elif s == '|': op = ast.BitOr() return op
def _seconds_to_mu(ref_period, node): divided = ast.copy_location( ast.BinOp(left=node, op=ast.Div(), right=value_to_ast(ref_period)), node) return ast.copy_location( ast.Call(func=ast.Name("round64", ast.Load()), args=[divided], keywords=[]), divided)
def divide(a, b): db = derive(b) leftmul = ast.BinOp(left=a, right=db, op=ast.Mult()) rightmul = ast.BinOp(left=b, right=derive(a), op=ast.Mult()) topsub = ast.BinOp(left=leftmul, right=rightmul, op=ast.Sub()) bottompow = ast.BinOp(left=db, right=ast.Num(n=2), op=ast.Pow()) return ast.BinOp(left=topsub, right=bottompow, op=ast.Div()) return f"(({a} * {db} - {b} * {derive(a)}) / ({db} ** 2))"
def swap_Op(self, node): if (isinstance(node.op, ast.Add)): #BinOp node.op = ast.Sub() elif (isinstance(node.op, ast.Sub)): #BinOp node.op = ast.Add() elif (isinstance(node.op, ast.Mult)): #BinOp node.op = ast.Div() elif (isinstance(node.op, ast.Div)): #BinOp node.op = ast.Mult() elif (isinstance(node.op, ast.FloorDiv)): #BinOp node.op = ast.Div() # elif(isinstance(node.op, ast.And)): #BoolOp # node.op = ast.Or() # elif(isinstance(node.op, ast.Or)): #BoolOp # node.op = ast.And() # elif(isinstance(node.op, ast.UAdd)): #UnaryOp # node.op = ast.USub() # elif(isinstance(node.op, ast.USub)): #UnaryOp node.op = ast.UAdd()
def visit_BinOp(self, node): if node.op.__class__ != ast.FloorDiv: return node dummy_op = ast.BinOp(left=node.left, op=ast.Div(), right=node.right) dummy_int = ast.Name(id="int", ctx=ast.Load()) return ast.Call(func=dummy_int, args=[dummy_op], keywords=[], starargs=None, kwargs=None)
def visit_AugAssign(self, node): if node.op.__class__ != ast.FloorDiv: return node dummy_op = ast.BinOp(left=node.target, op=ast.Div(), right=node.value) dummy_int = ast.Name(id="int", ctx=ast.Load()) dummy_call = ast.Call(func=dummy_int, args=[dummy_op], keywords=[], starargs=None, kwargs=None) return ast.Assign(targets=[node.target], value=dummy_call)
def operator(value): if value == "+": return ast.Add() elif value == "-": return ast.Sub() elif value == "*": return ast.Mult() elif value == "/": return ast.Div() raise Exception("operator not supported: {0}".format(value))
def mutate(cls, node): """ mutate augmented assignment operators: +=, -=, *=, /=, //= """ if node not in config.visited_nodes: if node.__class__ is ast.AugAssign: if node.op.__class__ is ast.Add: if node.value.__class__ is ast.Str and node.value.__class__ is ast.Call and hasattr( node.value.func, 'id') and node.value.func.id == 'str': return node if node.op.__class__ in config.arithmetic_operators: config.arithmetic_operators.remove(node.op.__class__) while len(config.arithmetic_operators) > 0: original_node = deepcopy(node) parent = config.parent_dict[node] del config.parent_dict[node] op_node = None op_type = config.arithmetic_operators.pop() if op_type is ast.Add: op_node = ast.Add() elif op_type is ast.Sub: op_node = ast.Sub() elif op_type is ast.Mult: op_node = ast.Mult() elif op_type is ast.Div: op_node = ast.Div() elif op_type is ast.FloorDiv: op_node = ast.FloorDiv() else: print "TypeError in ASR" if op_node: node.op = op_node config.parent_dict[node] = parent config.node_pairs[node] = original_node config.current_mutated_node = node config.mutated = True return node if len(config.arithmetic_operators) == 0: config.arithmetic_operators = [ ast.Add, ast.Sub, ast.Mult, ast.Div, ast.FloorDiv ] config.visited_nodes.add(node) return node
def test_scalar_bin_op_init(self): ScalarBinOp(self.constant, ast.Add(), self.constant) ScalarBinOp(self.output_element, ast.Add(), self.neighbor) ScalarBinOp(self.output_element, ast.Sub(), self.neighbor) ScalarBinOp(self.output_element, ast.Mult(), self.neighbor) ScalarBinOp(self.output_element, ast.Div(), self.neighbor) ScalarBinOp(self.output_element, ast.FloorDiv(), self.neighbor) ScalarBinOp(self.output_element, ast.Mod(), self.neighbor) for op in [ ast.Mod, ast.Pow, ast.LShift, ast.RShift, ast.BitOr, ast.BitXor, ast.BitAnd ]: with self.assertRaises(AssertionError): ScalarBinOp(self.output_element, op, self.neighbor)
def visit_Assign(self, node): if isinstance(node.value, ast.Call) \ and isinstance(node.value.func, ast.Name) \ and node.value.func.id in _noise_functions: node.value.func.id = 'havoc' change_v_epsilon = ast.AugAssign(target=ast.Name(id='__V_epsilon', ctx=ast.Store()), op=ast.Add(), value=ast.BinOp( left=ast.Num(1.0), op=ast.Div(), right=node.value.args[0])) return change_v_epsilon, node else: return node
def visit_Call(self, node): if node.func.id == 'Z' or node.func.id == 'SCALE': return ast.BinOp(left=ast.BinOp( left=copy.deepcopy(node.args[0]), op=ast.Sub(), right=ast.Call(func=ast.Name(id='VMEAN', ctx=ast.Load()), args=[copy.deepcopy(node.args[0])], keywords=[])), op=ast.Div(), right=ast.Call(func=ast.Name(id='VSTDEV', ctx=ast.Load()), args=[copy.deepcopy(node.args[0])], keywords=[])) else: return self.generic_visit(node)
def term(self): """term: factor ((MUL | DIV) factor)*""" print("BEGIN term") node = self.factor() while self.current_token.token_type in (TokenType.MUL, TokenType.DIV): token = self.current_token op = None if token.token_type == TokenType.MUL: op = ast.Mult() self.eat(TokenType.MUL) elif token.token_type == TokenType.DIV: op = ast.Div() self.eat(TokenType.DIV) node = ast.BinOp(node, op, self.factor()) print("END term") return node
def operator_equals(mod): op = ast.Add() if mod == '|=': op = ast.Or() if mod == '||=': op = ast.Or() if mod == '&=': op = ast.And() if mod == '&&=': op = ast.And() if mod == '+=': op = ast.Add() if mod == '-=': op = ast.Sub() if mod == '*=': op = ast.Mult() if mod == '**=': op = ast.Pow() if mod == '/=': op = ast.Div() if mod == '//=': op = ast.FloorDiv() if mod == '%=': op = ast.Mod() if mod == '^=': op = ast.BitXor() if mod == '<<': op = ast.LShift() if mod == '>>': op = ast.RShift() return op
def create_term_node(self, term): last_factor_index = len(term.factors) node = self.to_node(term.factors[0]) if last_factor_index == 0: return node for i in range(1, last_factor_index): if term.operators[i - 1] in ["*", "times"]: node = ast.BinOp(node, ast.Mult(), self.to_node(term.factors[i])) elif term.operators[i - 1] in ["/", "divided by"]: node = ast.BinOp(node, ast.Div(), self.to_node(term.factors[i])) elif term.operators[i - 1] in ["%", "modulo"]: node = ast.BinOp(node, ast.Mod(), self.to_node(term.factors[i])) else: raise return node
def to_node(self): node = self.left.to_node() if len(self.operator) == 0: return node else: for i in range(len(self.right)): if self.operator[i] in ['*', 'times']: node = ast.BinOp(node, ast.Mult(), self.right[i].to_node()) elif self.operator[i] in ['/', 'divided by']: node = ast.BinOp(node, ast.Div(), self.right[i].to_node()) elif self.operator[i] in ['%', 'modulo']: node = ast.BinOp(node, ast.Mod(), self.right[i].to_node()) elif self.operator[i] == '@': node = ast.BinOp(node, ast.MatMult(), self.right[i].to_node()) elif self.operator[i] == '//': node = ast.BinOp(node, ast.FloorDiv(), self.right[i].to_node()) return node
def _build_node(node): """Convert an AST node to an expression node.""" node_ref = { type(ast.Add()): '+', type(ast.Sub()): '-', type(ast.Mult()): '*', type(ast.Div()): '/' } if isinstance(node, ast.BinOp) and type(node.op) in node_ref: built_node = Node(type=Node.NODE_TYPE_OPERATOR, ch=node_ref[type(node.op)], left=_build_node(node.left), right=_build_node(node.right)) elif isinstance(node, ast.Num) and type(node.n) is int and node.n in list( range(0, 14)): built_node = Node(type=Node.NODE_TYPE_NUMBER, ch=node.n) else: raise SyntaxError('Unallowed operator or operands.') return built_node
def resolve_value(value, scope): if isinstance(value, EId): node = ast.Name(id=value.v, ctx=ast.Load()) elif isinstance(value, EInt): node = ast.Num(n=value.v) elif isinstance(value, EList): lst = [resolve_value(a, scope) for a in value.v] node = ast.List(elts=lst, ctx=ast.Load()) elif isinstance(value, EOp): lft, rgt = value.v lft = resolve_value(lft, scope) rgt = resolve_value(rgt, scope) operators = { '+': ast.Add(), '-': ast.Sub(), '*': ast.Mult(), '/': ast.Div(), '%': ast.Mod(), } node = ast.BinOp(left=lft, right=rgt, op=operators[value.t]) elif isinstance(value, ECompare): lft, rgt = value.v lft = resolve_value(lft, scope) rgt = resolve_value(rgt, scope) operators = { '<': ast.Lt(), '>': ast.Gt(), '<=': ast.LtE(), '>=': ast.GtE(), '==': ast.Eq(), } node = ast.Compare(left=lft, ops=[operators[value.t]], comparators=[rgt]) return ast.fix_missing_locations(node)
def setUp(self): # Translated from https://github.com/gvanrossum/pegen/blob/ec2b354f64f6dbfcb46133757fe4c0e07880f526/test/test_pegen.py#L232 ident = Alpha + Alnum.repeat() atom = (ident.value(lambda v: ast.Name(id=v, ctx=ast.Load())) | Digit.repeat(1).value( lambda v: ast.Constant(value=ast.literal_eval(v)))) expr = Forward() factor = (Terminal('(').then(expr).skip(')') | atom) term = Forward() term.is_( term.skip('*').then( factor, lambda l, r: ast.BinOp(l, ast.Mult(), r)) ^ term.skip( '/').then(factor, lambda l, r: ast.BinOp(l, ast.Div(), r)) ^ factor) expr.is_( expr.skip('+').then(term, lambda l, r: ast.BinOp(l, ast.Add(), r)) ^ expr.skip('-').then( term, lambda l, r: ast.BinOp(l, ast.Sub(), r)) ^ term) start = expr.skip(Terminal('\n').repeat(0, 1)).filter( lambda r: not r.remain).value(lambda v: ast.fix_missing_locations( ast.Expression(v, lineno=1, col_offset=0))) self.parser = start
def AugAssign(draw): op = draw( sampled_from([ ast.Add(), ast.Sub(), ast.Mult(), ast.Div(), ast.FloorDiv(), ast.Mod(), ast.Pow(), ast.LShift(), ast.RShift(), ast.BitOr(), ast.BitXor(), ast.BitOr(), ast.BitAnd(), ast.MatMult() ])) return ast.AugAssign(target=draw(Name(ast.Store)), op=op, value=draw(expression()))