def get_index(node):
"""
get the index followed after the given namenode if possible
"""
parent = node.parent
if isinstance(parent, ast.Subscript):
try:
ind_node = parent.slice.value
#if there's multiple dimensions in index
if isinstance(ind_node, ast.Tuple):
value = []
for i in range(len(ind_node.elts)):
ind_value = py_ast.dump_ast(ind_node.elts[i])
value.append(ind_value)
return value
else:
value = py_ast.dump_ast(ind_node)
return value
except:
try:
value = []
ind_node = parent.slice.dims
for i in range(len(ind_node)):
ind_value = py_ast.dump_ast(ind_node[i])
value.append(ind_value)
return value
except:
return []
else:
return []
python类Subscript()的实例源码
def update_variable_domains(variable_domains, node_list):
'''Updates variable_domains by inserting mappings from a variable name to the to the number of
elements in their data domain.
Program variables are created in assignments of the form
"{varName} = Var({size})" or "{varName} = Param({size})".
'''
for ch in node_list:
if isinstance(ch, ast.Assign) and len(ch.targets) == 1:
name = astunparse.unparse(ch.targets[0]).rstrip()
rhs = ch.value
if isinstance(rhs, ast.Call):
decl_name = rhs.func.id
args = rhs.args
elif isinstance(rhs, ast.Subscript) and isinstance(rhs.value, ast.Call):
decl_name = rhs.value.func.id
args = rhs.value.args
else:
continue
if decl_name not in ["Param", "Var", "Input", "Output"]:
continue
if len(args) > 1:
error.error('More than one size parameter in variable declaration of "%s".' % (name), ch)
size = args[0]
if isinstance(size, ast.Num):
if name in variable_domains and variable_domains[name] != size.n:
error.fatal_error("Trying to reset the domain of variable '%s' to '%i' (old value '%i')." % (name, size.n, variable_domains[name]), size)
variable_domains[name] = size.n
else:
error.fatal_error("Trying to declare variable '%s', but size parameters '%s' is not understood." % (name, astunparse.unparse(size).rstrip()), size)
def flatten_array_declarations(root):
class Transformer(ast.NodeTransformer):
def visit_FunctionDef(self, node):
return node
def visit_Assign(self, node):
if isinstance(node.value, ast.Subscript) and isinstance(node.value.value, ast.Call):
subscr = node.value
call = subscr.value
if len(node.targets) > 1:
error.error('Cannot use multiple assignment in array declaration.', node)
variable_name = node.targets[0].id
value_type = call.func.id
declaration_args = call.args
# Get the indices being accessed.
shape = slice_node_to_tuple_of_numbers(subscr.slice)
new_assigns = []
for indices in itertools.product(*[range(n) for n in shape]):
index_name = flattened_array_name(variable_name, indices)
new_index_name_node = ast.copy_location(ast.Name(index_name, ast.Store()), node)
new_value_type_node = ast.copy_location(ast.Name(value_type, ast.Load()), node)
new_declaration_args = [copy.deepcopy(arg) for arg in declaration_args]
new_call_node = ast.copy_location(ast.Call(new_value_type_node, new_declaration_args, [], None, None), node)
new_assign = ast.Assign([new_index_name_node], new_call_node)
new_assign = ast.copy_location(new_assign, node)
new_assigns.append(new_assign)
return new_assigns
else:
return node
return Transformer().visit(root)
def is_declaration_of_type(node, typ):
if isinstance(node, ast.Subscript):
return is_declaration_of_type(node.value, typ)
if not isinstance(node, ast.Call): return False
if not isinstance(node.func, ast.Name): return False
return node.func.id == typ
def is_declaration(node):
if isinstance(node, ast.Subscript):
return is_declaration(node.value)
if not isinstance(node, ast.Call): return False
if not isinstance(node.func, ast.Name): return False
return node.func.id in ["Input", "Output", "Var", "Hyper", "Param"]
def get_var_name(node):
if isinstance(node, ast.Name):
return node.id
elif isinstance(node, ast.Subscript):
return get_var_name(node.value)
elif isinstance(node, ast.Call):
return None # This is the Input()[10] case
else:
raise Exception("Can't extract var name from '%s'" % (unparse(node).rstrip()))
def generate_io_stmt(input_idx, var_name, value, func_name):
if value is None:
return []
elif isinstance(value, list):
return [ast.Expr(
ast.Call(
ast.Attribute(
ast.Subscript(
ast.Name(var_name, ast.Load()),
ast.Index(
ast.Tuple([ast.Num(input_idx),
ast.Num(val_idx)],
ast.Load())),
ast.Load()),
func_name,
ast.Load()),
[ast.Num(val)],
[], None, None))
for val_idx, val in enumerate(value)
if val is not None]
else:
return [ast.Expr(
ast.Call(
ast.Attribute(
ast.Subscript(
ast.Name(var_name, ast.Load()),
ast.Index(ast.Num(input_idx)),
ast.Load()),
func_name,
ast.Load()),
[ast.Num(value)],
[], None, None))]
def rhs_function(node):
if not isinstance(node, ast.Assign): return None
rhs = node.value
if isinstance(rhs, ast.Call):
return rhs
elif isinstance(rhs, ast.BinOp):
return rhs
elif isinstance(rhs, ast.UnaryOp):
return rhs
elif isinstance(rhs, ast.Subscript):
return rhs
def var_id(var_node):
if isinstance(var_node, ast.Name):
return var_node.id
elif isinstance(var_node, ast.Subscript):
return var_node.value.id
def top_level_name(node):
if type(node) is ast.Name:
return node.id
elif type(node) is ast.Subscript or type(node) is ast.Attribute:
return SchedulerRewriter.top_level_name(node.value)
return None
def is_valid_assignment(self, node):
if not (type(node) is ast.Assign and self.is_concurrent_call(node.value)):
return False
if len(node.targets) != 1:
raise ValueError("???????????")
if not type(node.targets[0]) is ast.Subscript:
raise ValueError("??????????")
return True
def __init__(self, operators=None, functions=None, names=None):
"""
Create the evaluator instance. Set up valid operators (+,-, etc)
functions (add, random, get_val, whatever) and names. """
if not operators:
operators = DEFAULT_OPERATORS
if not functions:
functions = DEFAULT_FUNCTIONS
if not names:
names = DEFAULT_NAMES
self.operators = operators
self.functions = functions
self.names = names
self.nodes = {
ast.Num: self._eval_num,
ast.Str: self._eval_str,
ast.Name: self._eval_name,
ast.UnaryOp: self._eval_unaryop,
ast.BinOp: self._eval_binop,
ast.BoolOp: self._eval_boolop,
ast.Compare: self._eval_compare,
ast.IfExp: self._eval_ifexp,
ast.Call: self._eval_call,
ast.keyword: self._eval_keyword,
ast.Subscript: self._eval_subscript,
ast.Attribute: self._eval_attribute,
ast.Index: self._eval_index,
ast.Slice: self._eval_slice,
}
# py3k stuff:
if hasattr(ast, 'NameConstant'):
self.nodes[ast.NameConstant] = self._eval_nameconstant
elif isinstance(self.names, dict) and "None" not in self.names:
self.names["None"] = None
def _infer_one_target(target, context, solver):
"""
Get the type of the left hand side of an assignment
:param target: The target on the left hand side
:param context: The current context level
:param solver: The SMT solver
:return: the type of the target
"""
if isinstance(target, ast.Name):
if target.id in context.types_map:
return context.get_type(target.id)
else:
target_type = solver.new_z3_const("assign")
context.set_type(target.id, target_type)
return target_type
elif isinstance(target, ast.Tuple):
args_types = []
for elt in target.elts:
args_types.append(_infer_one_target(elt, context, solver))
return solver.z3_types.tuples[len(args_types)](*args_types)
elif isinstance(target, ast.List):
list_type = solver.new_z3_const("assign")
for elt in target.elts:
solver.add(list_type == _infer_one_target(elt, context, solver),
fail_message="List assignment in line {}".format(target.lineno))
return solver.z3_types.list(list_type)
target_type = expr.infer(target, context, solver)
if isinstance(target, ast.Subscript):
solver.add(axioms.subscript_assignment(expr.infer(target.value, context, solver), solver.z3_types),
fail_message="Subscript assignment in line {}".format(target.lineno))
return target_type
def scan_opcodes_cli(self, co):
import ast
with open(co.co_filename, 'rU') as f:
nodes = ast.parse(f.read(), co.co_filename)
items = []
class ModuleFinderVisitor(ast.NodeVisitor):
def visit_Assign(self, node):
for x in node.targets:
if isinstance(x, ast.Subscript):
if isinstance(x.value, ast.Name):
items.append(("store", (x.value.id, )))
elif isinstance(x.value, ast.Attribute):
items.append(("store", (x.value.attr, )))
else:
print 'Unknown in store: %s' % type(x.value).__name__
elif isinstance(x, ast.Name):
items.append(("store", (x.id, )))
def visit_Import(self, node):
items.extend([("import", (None, x.name)) for x in node.names])
def visit_ImportFrom(self, node):
if node.level == 1:
items.append(("relative_import", (node.level, [x.name for x in node.names], node.module)))
else:
items.extend([("import", ([x.name for x in node.names], node.module))])
v = ModuleFinderVisitor()
v.visit(nodes)
for what, args in items:
yield what, args
def resolve_attr_id(node):
if isinstance(node, (ast.Attribute, ast.Subscript)):
value_id = None
if isinstance(node.value, (ast.Name, ast.Attribute, ast.Subscript)):
value_id = resolve_attr_id(node.value)
elif isinstance(node.value, ast.Call):
value_id = resolve_attr_id(node.value)
elif isinstance(node.value, ast.Str):
value_id = 'str'
elif isinstance(node.value, ast.Bytes):
value_id = 'bytes'
elif isinstance(node.value, (ast.List, ast.ListComp)):
value_id = 'list'
elif isinstance(node.value, ast.Tuple):
value_id = 'tuple'
elif isinstance(node.value, (ast.Set, ast.SetComp)):
value_id = 'set'
elif isinstance(node.value, (ast.Dict, ast.DictComp)):
value_id = 'dict'
else:
raise SyntaxError(
'unsupport type: {}'.format(ast.dump(node.value))
)
if isinstance(node, ast.Attribute):
return '{}.{}'.format(value_id, node.attr)
elif isinstance(node, ast.Subscript):
slice = None
if isinstance(node.slice.value, ast.Str):
slice = node.slice.value.s
elif isinstance(node.slice.value, ast.Num):
slice = node.slice.value.n
elif isinstance(node.slice.value, ast.Name):
slice = resolve_attr_id(node.slice.value)
return '{}[{}]'.format(value_id, slice)
elif isinstance(node, ast.Call):
return '{}()'.format(resolve_attr_id(node.func))
return node.id
def _build_subscript(value1, value2):
return Subscript(
value=value1,
slice=Index(value=value2),
ctx=Load())
def _assertTrueorder(self, ast_node, parent_pos, reverse_check = False):
def should_reverse_check(parent, child):
# In some situations, the children of nodes occur before
# their parents, for example in a.b.c, a occurs before b
# but a is a child of b.
if isinstance(parent, ast.Call):
if parent.func == child:
return True
if isinstance(parent, (ast.Attribute, ast.Subscript)):
return True
return False
if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
return
if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
node_pos = (ast_node.lineno, ast_node.col_offset)
if reverse_check:
self.assertTrue(node_pos <= parent_pos)
else:
self.assertTrue(node_pos >= parent_pos)
parent_pos = (ast_node.lineno, ast_node.col_offset)
for name in ast_node._fields:
value = getattr(ast_node, name)
if isinstance(value, list):
for child in value:
self._assertTrueorder(child, parent_pos,
should_reverse_check(ast_node, child))
elif value is not None:
self._assertTrueorder(value, parent_pos,
should_reverse_check(ast_node, value))
def translate_Attribute(self, ctx, e):
n = _util.odict_idx_of(self.idx, e.attr)
return ast.copy_location(ast.Subscript(
value=ctx.translate(e.value),
slice=ast.Num(n=n),
ctx=ast.Load()
), e)
def translate_Subscript(self, ctx, e):
value = e.value
label = e.slice.value.label
n = _util.odict_idx_of(self.idx, label)
return ast.copy_location(ast.Subscript(
value=ctx.translate(value),
slice=ast.Num(n=n),
ctx=ast.Load()
), e)
def _labeled_translation(idx_mapping, arg_translation):
lambda_translation = ast.Lambda(
args=ast.arguments(
args=[ast.Name(id='x', ctx=ast.Param())],
vararg=None,
kwarg=None,
defaults=[]),
body=ast.Tuple(
elts=list(
ast.Subscript(
value=ast.Name(
id='x',
ctx=ast.Load()),
slice=ast.Index(
value=ast.Num(n=n)),
ctx=ast.Load())
for n in idx_mapping
),
ctx=ast.Load()
)
)
return ast.Call(
func=lambda_translation,
args=[arg_translation],
keywords=[],
starargs=[],
kwargs=None
)