def p_func_stmt(p): """func_stmt : FUNCTION ident lambda_args SEMI | FUNCTION ret EQ ident lambda_args SEMI """ # stmt_list of func_stmt is set below # marked with XYZZY global ret_expr, use_nargin, use_varargin ret_expr = node.expr_list() use_varargin = use_nargin = 0 if len(p) == 5: assert isinstance(p[3], node.expr_list) p[0] = node.func_stmt( ident=p[2], ret=node.expr_list(), args=p[3], stmt_list=node.stmt_list()) ret_expr = node.expr_list() elif len(p) == 7: assert isinstance(p[2], node.expr_list) assert isinstance(p[5], node.expr_list) p[0] = node.func_stmt( ident=p[4], ret=p[2], args=p[5], stmt_list=node.stmt_list()) ret_expr = p[2] else: assert 0
def p_args_opt(p): """ args_opt : | LPAREN RPAREN | LPAREN expr_list RPAREN """ flag = False if len(p) == 1: p[0] = node.expr_list() elif len(p) == 3: p[0] = node.expr_list() elif len(p) == 4: assert isinstance(p[2], node.expr_list) p[0] = p[2] flag = True else: assert 0 if flag: t = p[2][-1] if isinstance(t, node.ident) and t.name == "varargin": t.name = "*varargin" for t in p[2]: if isinstance(t, node.ident) and t.name != '*varargin': t.init = node.ident("None")
def p_funcall_expr(p): """expr : expr LPAREN expr_list RPAREN | expr LPAREN RPAREN """ if (len(p) == 5 and len(p[3]) == 1 and p[3][0].__class__ is node.expr and p[3][0].op == ":" and not p[3][0].args): # foo(:) => ravel(foo) p[0] = node.funcall(func_expr=node.ident("ravel"), args=node.expr_list([p[1]])) else: args = node.expr_list() if len(p) == 4 else p[3] assert isinstance(args, node.expr_list) p[0] = node.funcall(func_expr=p[1], args=args)
def p_funcall_expr(p): """expr : expr LPAREN expr_list RPAREN | expr LPAREN RPAREN """ if (len(p) == 5 and len(p[3]) == 1 and p[3][0].__class__ is node.expr and p[3][0].op == ":" and not p[3][0].args): # foo(:) => ravel(foo) p[0] = node.funcall( func_expr=node.ident("ravel"), args=node.expr_list([p[1]])) else: args = node.expr_list() if len(p) == 4 else p[3] assert isinstance(args, node.expr_list) p[0] = node.funcall(func_expr=p[1], args=args)
def p_args_opt(p): """ args_opt : | LPAREN RPAREN | LPAREN expr_list RPAREN """ if len(p) == 1: p[0] = node.expr_list() elif len(p) == 3: p[0] = node.expr_list() elif len(p) == 4: assert isinstance(p[2],node.expr_list) p[0] = p[2] else: assert 0
def p_ret(p): """ ret : ident | LBRACKET RBRACKET | LBRACKET expr_list RBRACKET """ if len(p) == 2: p[0] = node.expr_list([p[1]]) elif len(p) == 3: p[0] = node.expr_list([]) elif len(p) == 4: assert isinstance(p[2],node.expr_list) p[0] = p[2] else: assert 0
def p_expr1(p): """expr1 : MINUS expr %prec UMINUS | PLUS expr %prec UMINUS | NEG expr | HANDLE ident """ p[0] = node.expr(op=p[1],args=node.expr_list([p[2]]))
def p_expr2(p): """expr2 : expr AND expr | expr ANDAND expr | expr BACKSLASH expr | expr COLON expr | expr DIV expr | expr DOT expr | expr DOTDIV expr | expr DOTEXP expr | expr DOTMUL expr | expr EQ expr | expr EXP expr | expr GE expr | expr GT expr | expr LE expr | expr LT expr | expr MINUS expr | expr MUL expr | expr NE expr | expr OR expr | expr OROR expr | expr PLUS expr """ if p[2] == "." and isinstance(p[3],node.expr) and p[3].op=="parens": p[0] = node.getfield(p[1],p[3].args[0]) elif p[2] == ":" and isinstance(p[1],node.expr) and p[1].op==":": # Colon expression means different things depending on the # context. As an array subscript, it is a slice; otherwise, # it is a call to the "range" function, and the parser can't # tell which is which. So understanding of colon expressions # is put off until after "resolve". p[0] = p[1] p[0].args.insert(1,p[3]) else: p[0] = node.expr(op=p[2],args=node.expr_list([p[1],p[3]]))
def p_cellarrayref(p): """expr : expr LBRACE expr_list RBRACE | expr LBRACE RBRACE """ args = node.expr_list() if len(p) == 4 else p[3] assert isinstance(args, node.expr_list) p[0] = node.cellarrayref(func_expr=p[1], args=args)
def p_unwind(p): """ unwind : UNWIND_PROTECT stmt_list UNWIND_PROTECT_CLEANUP stmt_list END_UNWIND_PROTECT """ p[0] = node.try_catch(try_stmt=p[2], catch_stmt=node.expr_list(), finally_stmt=p[4])
def p_cellarrayref(p): """expr : expr LBRACE expr_list RBRACE | expr LBRACE RBRACE """ args = node.expr_list() if len(p) == 4 else p[3] assert isinstance(args,node.expr_list) p[0] = node.cellarrayref(func_expr=p[1],args=args)
def p_foo_stmt(p): "foo_stmt : expr OROR expr SEMI" expr1 = p[1][1][0] expr2 = p[3][1][0] ident = expr1.ret args1 = expr1.args args2 = expr2.args p[0] = node.let(ret=ident, args=node.expr("or", node.expr_list([args1, args2])))
def p_field_expr(p): """ expr : expr FIELD """ p[0] = node.expr(op=".", args=node.expr_list([p[1], node.ident(name=p[2], lineno=p.lineno(2), lexpos=p.lexpos(2))]))
def p_foo_stmt(p): "foo_stmt : expr OROR expr SEMI" expr1 = p[1][1][0] expr2 = p[3][1][0] ident = expr1.ret args1 = expr1.args args2 = expr2.args p[0] = node.let(ret=ident, args=node.expr("or",node.expr_list([args1,args2])))
def p_cellarray(p): """ cellarray : LBRACE RBRACE | LBRACE expr_list RBRACE """ if len(p) == 3: p[0] = node.cellarray(op="{}",args=node.expr_list()) else: p[0] = node.cellarray(op="{}",args=p[2])
def p_args(p): """ args : arg1 | args arg1 """ if len(p) == 2: p[0] = node.expr_list([p[1]]) else: p[0] = p[1] p[0].append(p[2])
def let_statement(u): """ If LHS is a plain variable, and RHS is a matrix enclosed in square brackets, replace the matrix expr with a funcall. """ if u.__class__ is node.let: if (u.ret.__class__ is node.ident and u.args.__class__ is node.matrix): u.args = node.funcall(func_expr=node.ident("matlabarray"), args=node.expr_list([u.args]))
def p_func_decl(p): """func_decl : FUNCTION ident args_opt SEMI | FUNCTION ret EQ ident args_opt SEMI """ global ret_expr,use_nargin use_nargin = 0 if len(p) == 5: assert isinstance(p[3],node.expr_list) p[0] = node.func_decl(ident=p[2], ret=node.expr_list(), args=p[3]) ret_expr = node.expr_list() elif len(p) == 7: assert isinstance(p[2],node.expr_list) assert isinstance(p[5],node.expr_list) p[0] = node.func_decl(ident=p[4], ret=p[2], args=p[5]) ret_expr = p[2] else: assert 0
def p_exprs(p): """ exprs : expr | exprs COMMA expr """ if len(p) == 2: p[0] = node.expr_list([p[1]]) elif len(p) == 4: p[0] = p[1] p[0].append(p[3]) else: assert (0) assert isinstance(p[0], node.expr_list)
def p_func_stmt(p): """func_stmt : FUNCTION ident args_opt SEMI | FUNCTION ret EQ ident args_opt SEMI """ global ret_expr,use_nargin,use_varargin use_varargin = use_nargin = 0 if len(p) == 5: assert isinstance(p[3],node.expr_list) p[0] = node.func_stmt(ident=p[2], ret=node.expr_list(), args=p[3]) ret_expr = node.expr_list() elif len(p) == 7: assert isinstance(p[2],node.expr_list) assert isinstance(p[5],node.expr_list) p[0] = node.func_stmt(ident=p[4], ret=p[2], args=p[5]) ret_expr = p[2] else: assert 0
def p_arg_list(p): """ arg_list : ident_init_opt | arg_list COMMA ident_init_opt """ if len(p) == 2: p[0] = node.expr_list([p[1]]) elif len(p) == 4: p[0] = p[1] p[0].append(p[3]) else: assert 0 assert isinstance(p[0], node.expr_list)
def p_exprs(p): """ exprs : expr | exprs COMMA expr """ if len(p) == 2: p[0] = node.expr_list([p[1]]) elif len(p) == 4: p[0] = p[1] p[0].append(p[3]) else: assert(0) assert isinstance(p[0],node.expr_list)
def p_arg_list(p): """ arg_list : ident | arg_list COMMA ident """ if len(p) == 2: p[1].__class__ = node.param p[0] = node.expr_list([p[1]]) elif len(p) == 4: p[0] = p[1] p[3].__class__ = node.param p[0].append(p[3]) else: assert 0 assert isinstance(p[0],node.expr_list)
def p_case_list(p): """ case_list : | CASE expr sep stmt_list_opt case_list | OTHERWISE stmt_list """ if len(p) == 1: p[0] = node.stmt_list() elif len(p) == 3: assert isinstance(p[2],node.stmt_list) p[0] = p[2] elif len(p) == 6: p[0] = node.if_stmt(cond_expr=node.expr(op="==", args=node.expr_list([p[2]])), then_stmt=p[4], else_stmt=p[5]) p[0].cond_expr.args.append(None) # None will be replaced using backpatch() else: assert 0
def p_expr_end(p): "end : END_EXPR" p[0] = node.expr(op="end", args=node.expr_list([node.number(0), node.number(0)]))
def p_expr_end(p): "end : END_EXPR" p[0] = node.expr(op="end",args=node.expr_list())
def resolve(t, symtab=None, fp=None, func_name=None): if symtab is None: symtab = {} do_resolve(t, symtab) G = as_networkx(t) # import pdb;pdb.set_trace() for n in G.nodes(): u = G.node[n]["ident"] if u.props: pass elif G.out_edges(n) and G.in_edges(n): u.props = "U" # upd # print u.name, u.lineno, u.column elif G.in_edges(n): u.props = "D" # def elif G.out_edges(n): u.props = "R" # ref else: u.props = "F" # ??? G.node[n]["label"] = "%s\\n%s" % (n, u.props) for u in node.postorder(t): # if u.__class__ is node.func_decl: # u.ident.name += "_" if u.__class__ is node.funcall: try: if u.func_expr.props in "UR": # upd,ref u.__class__ = node.arrayref # else: # u.func_expr.name += "_" except: pass for u in node.postorder(t): if u.__class__ in (node.arrayref, node.cellarrayref): for i, v in enumerate(u.args): if v.__class__ is node.expr and v.op == ":": v.op = "::" # for w in node.postorder(v): # if w.__class__ is node.expr and w.op == "end": # w.args[0] = u.func_expr # w.args[1] = node.number(i) for u in node.postorder(t): if u.__class__ is node.let: if u.ret.__class__ is node.ident and u.args.__class__ is node.matrix: u.args = node.funcall(func_expr=node.ident("matlabarray"), args=node.expr_list([u.args])) H = nx.connected_components(G.to_undirected()) for i, component in enumerate(H): for nodename in component: if G.node[nodename]["ident"].props == "R": has_update = 1 break else: has_update = 0 if has_update: for nodename in component: G.node[nodename]["ident"].props += "S" # sparse # S = G.subgraph(nbunch) # print S.edges() return G
def p_lambda_args(p): """lambda_args : LPAREN RPAREN | LPAREN arg_list RPAREN """ p[0] = p[2] if len(p) == 4 else node.expr_list()
def p_expr_end(p): "end : END_EXPR" p[0] = node.expr(op="end",args=node.expr_list([node.number(0), node.number(0)]))
def p_expr_colon(p): "colon : COLON" p[0] = node.expr(op=":",args=node.expr_list())
def p_expr2(p): """expr2 : expr AND expr | expr ANDAND expr | expr BACKSLASH expr | expr COLON expr | expr DIV expr | expr DOT expr | expr DOTDIV expr | expr DOTDIVEQ expr | expr DOTEXP expr | expr DOTMUL expr | expr DOTMULEQ expr | expr EQEQ expr | expr EXP expr | expr EXPEQ expr | expr GE expr | expr GT expr | expr LE expr | expr LT expr | expr MINUS expr | expr MUL expr | expr NE expr | expr OR expr | expr OROR expr | expr PLUS expr | expr EQ expr | expr MULEQ expr | expr DIVEQ expr | expr MINUSEQ expr | expr PLUSEQ expr | expr OREQ expr | expr ANDEQ expr """ if p[2] == "=": if p[1].__class__ is node.let: raise NotImplementedError("assignment " "as expression") # The algorithm, which decides if an # expression F(X) # is arrayref or funcall, is implemented in # resolve.py, except the following lines up # to XXX. These lines handle the case where # an undefined array is updated: # >>> clear a # >>> a[1:10]=123 # Though legal in matlab, these lines # confuse the algorithm, which thinks that # the undefined variable is a function name. # To prevent the confusion, we mark these # nodes arrayref as early as during the parse # phase. if p[1].__class__ is node.funcall: # A(B) = C p[1].__class__ = node.arrayref elif p[1].__class__ is node.matrix: # [A1(B1) A2(B2) ...] = C for e in p[1].args: if e.__class__ is node.funcall: e.__class__ = node.arrayref # XXX if isinstance(p[1],node.getfield): #import pdb;pdb.set_trace() # A.B=C setfield(A,B,C) p[0] = node.setfield(p[1].args[0], p[1].args[1], p[3]) else: #assert len(p[1].args) > 0 ret = p[1].args if isinstance(p[1],node.matrix) else p[1] p[0] = node.let(ret=ret, args=p[3], lineno=p.lineno(2), lexpos=p.lexpos(2)) if isinstance(p[1],node.matrix): # TBD: mark idents as "P" - persistent if p[3].__class__ not in (node.ident,node.funcall): #, p[3].__class__ raise NotImplementedError("multi-assignment %d" % p[0].lineno) if p[3].__class__ is node.ident: # [A1(B1) A2(B2) ...] = F implied F() # import pdb; pdb.set_trace() p[3] = node.funcall(func_expr=p[3], args=node.expr_list()) # [A1(B1) A2(B2) ...] = F(X) p[3].nargout = len(p[1].args[0]) elif p[2] == ".*": p[0] = node.dot(p[1],p[3]) # elif p[2] == "." and isinstance(p[3],node.expr) and p[3].op=="parens": # p[0] = node.getfield(p[1],p[3].args[0]) # raise NotImplementedError(p[3],p.lineno(3),p.lexpos(3)) elif p[2] == ":" and isinstance(p[1],node.expr) and p[1].op==":": # Colon expression means different things depending on the # context. As an array subscript, it is a slice; otherwise, # it is a call to the "range" function, and the parser can't # tell which is which. So understanding of colon expressions # is put off until after "resolve". p[0] = p[1] p[0].args.insert(1,p[3]) else: p[0] = node.expr(op=p[2],args=node.expr_list([p[1],p[3]]))
def do_resolve(t, symtab): """ Array references ---------------- a(x) --> a[x-1] if rank(a) == 1 --> a.flat[x-1] otherwise a(:) --> a if rank(a) == 1 --> a.flat[-1,1] otherwise a(x,y,z) --> a[x-1,y-1,z-1] a(x:y) --> a[x-1:y] a(x:y:z) --> a[x-1,z,y] a(...end...) --> a[... a.shape[i]...] a(x==y) --> ??? Function calls -------------- start:stop --> np.arange(start,stop+1) start:step:stop --> np.arange(start,stop+1,step) """ t._resolve(symtab) #pprint.pprint(symtab) for u in node.postorder(t): if (u.__class__ is node.funcall and u.func_expr.__class__ is node.expr and u.func_expr.op == "."): u.__class__ = node.arrayref elif (u.__class__ is node.funcall and u.func_expr.__class__ is node.ident): if u.func_expr.defs: # Both node.arrayref and node.builtins are subclasses # of node.funcall, so we are allowed to assign to its # __class__ field. Convert funcall nodes to array # references. u.__class__ = node.arrayref elif u.func_expr.defs == set(): # Function used, but there is no definition. It's # either a builtin function, or a call to user-def # function, which is defined later. cls = getattr(node, u.func_expr.name, None) # """ # if not cls: # # This is the first time we met u.func_expr.name # cls = type(u.func_expr.name, # (node.funcall,), # { 'code' : None }) # setattr(node,u.func_expr.name,cls) # assert cls # if issubclass(cls,node.builtins) and u.__class__ != cls: # u.func_expr = None # same in builtins ctor if cls: u.__class__ = cls else: # Only if we have A(B) where A.defs is None assert 0 if u.__class__ in (node.arrayref, node.cellarrayref): # if (len(u.args) == 1 # and isinstance(u.args[0],node.expr) # and u.args[0].op == ":"): # # FOO(:) becomes ravel(FOO) # u.become(node.ravel(u.func_expr)) # else: for i in range(len(u.args)): cls = u.args[i].__class__ if cls is node.number: u.args[i].value -= 1 elif cls is node.expr and u.args[i].op in ("==", "!=", "~=", "<", "=<", ">", ">="): pass elif cls is node.expr and u.args[i].op == ":": # Colon expression as a subscript becomes a # slice. Everywhere else it becomes a call to # the "range" function (done in a separate pass, # see below). u.args[i].op = "::" # slice marked with op=:: if u.args[i].args: if type(u.args[i].args[0]) is node.number: u.args[i].args[0].value -= 1 else: u.args[i].args[0] = node.sub( u.args[i].args[0], node.number(1)) for s in node.postorder(u.args[i]): if s.__class__ == node.expr and s.op == "end" and not s.args: s.args = node.expr_list( [u.func_expr, node.number(i)]) elif cls is node.expr and u.args[i].op == "end": u.args[i] = node.number(-1) else: u.args[i] = node.sub(u.args[i], node.number(1)) for u in node.postorder(t): if u.__class__ == node.ident and u.defs == set(): cls = getattr(node, u.name, None) if cls and issubclass(cls, node.builtins): u.become(cls()) elif u.__class__ == node.expr and u.op == ":" and u.args: if len(u.args) == 2: u.become( node.range(u.args[0], node.add(u.args[1], node.number(1)))) else: u.become( node.range(u.args[0], node.add(u.args[1], node.number(1)), u.args[2]))
def do_resolve(t,symtab): """ Array references ---------------- a(x) --> a[x-1] if rank(a) == 1 --> a.flat[x-1] otherwise a(:) --> a if rank(a) == 1 --> a.flat[-1,1] otherwise a(x,y,z) --> a[x-1,y-1,z-1] a(x:y) --> a[x-1:y] a(x:y:z) --> a[x-1,z,y] a(...end...) --> a[... a.shape[i]...] a(x==y) --> ??? Function calls -------------- start:stop --> np.arange(start,stop+1) start:step:stop --> np.arange(start,stop+1,step) """ t._resolve(symtab) #pprint.pprint(symtab) for u in node.postorder(t): if (u.__class__ is node.funcall and u.func_expr.__class__ is node.ident): if u.func_expr.defs: # Both node.arrayref and node.builtins are subclasses # of node.funcall, so we are allowed to assign to its # __class__ field. Convert funcall nodes to array # references. u.__class__ = node.arrayref elif u.func_expr.defs == set(): # Function used, but there is no definition. It's # either a builtin function, or a call to user-def # function, which is defined later. cls = getattr(node,u.func_expr.name,None) # """ # if not cls: # # This is the first time we met u.func_expr.name # cls = type(u.func_expr.name, # (node.funcall,), # { 'code' : None }) # setattr(node,u.func_expr.name,cls) # assert cls # if issubclass(cls,node.builtins) and u.__class__ != cls: # u.func_expr = None # same in builtins ctor if cls: u.__class__ = cls else: # Only if we have A(B) where A.defs is None assert 0 if u.__class__ in (node.arrayref,node.cellarrayref): # if (len(u.args) == 1 # and isinstance(u.args[0],node.expr) # and u.args[0].op == ":"): # # FOO(:) becomes ravel(FOO) # u.become(node.ravel(u.func_expr)) # else: for i in range(len(u.args)): cls = u.args[i].__class__ if cls is node.number: u.args[i].value -= 1 elif cls is node.expr and u.args[i].op in ("==","!=","~=","<","=<",">",">="): pass elif cls is node.expr and u.args[i].op == ":": # Colon expression as a subscript becomes a # slice. Everywhere else it becomes a call to # the "range" function (done in a separate pass, # see below). u.args[i].op = "::" # slice marked with op=:: if u.args[i].args: if type(u.args[i].args[0]) is node.number: u.args[i].args[0].value -= 1 else: u.args[i].args[0] = node.sub(u.args[i].args[0], node.number(1)) for s in node.postorder(u.args[i]): if s.__class__==node.expr and s.op=="end" and not s.args: s.args = node.expr_list([u.func_expr,node.number(i)]) elif cls is node.expr and u.args[i].op == "end": u.args[i] = node.number(-1) else: u.args[i] = node.sub(u.args[i],node.number(1)) for u in node.postorder(t): if u.__class__ == node.ident and u.defs == set(): cls = getattr(node,u.name,None) if cls and issubclass(cls,node.builtins): u.become(cls()) elif u.__class__ == node.expr and u.op == ":" and u.args: if len(u.args) == 2: u.become(node.range(u.args[0], node.add(u.args[1],node.number(1)))) else: u.become(node.range(u.args[0], node.add(u.args[1],node.number(1)), u.args[2]))
def p_parens_expr(p): """ expr : LPAREN expr RPAREN """ p[0] = node.expr(op="parens", args=node.expr_list([p[2]]))
def p_paren_expr(p): """ expr : LPAREN expr RPAREN """ p[0] = node.expr(op="parens",args=node.expr_list([p[2]]))
def p_expr2(p): """expr2 : expr AND expr | expr ANDAND expr | expr BACKSLASH expr | expr COLON expr | expr DIV expr | expr DOT expr | expr DOTDIV expr | expr DOTDIVEQ expr | expr DOTEXP expr | expr DOTMUL expr | expr DOTMULEQ expr | expr EQEQ expr | expr POW expr | expr EXP expr | expr EXPEQ expr | expr GE expr | expr GT expr | expr LE expr | expr LT expr | expr MINUS expr | expr MUL expr | expr NE expr | expr OR expr | expr OROR expr | expr PLUS expr | expr EQ expr | expr MULEQ expr | expr DIVEQ expr | expr MINUSEQ expr | expr PLUSEQ expr | expr OREQ expr | expr ANDEQ expr """ if p[2] == "=": if p[1].__class__ is node.let: raise_exception(SyntaxError, "Not implemented assignment as expression", new_lexer) # The algorithm, which decides if an # expression F(X) # is arrayref or funcall, is implemented in # resolve.py, except the following lines up # to XXX. These lines handle the case where # an undefined array is updated: # >>> clear a # >>> a[1:10]=123 # Though legal in matlab, these lines # confuse the algorithm, which thinks that # the undefined variable is a function name. # To prevent the confusion, we mark these # nodes arrayref as early as during the parse # phase. if p[1].__class__ is node.funcall: # A(B) = C p[1].__class__ = node.arrayref elif p[1].__class__ is node.matrix: # [A1(B1) A2(B2) ...] = C for e in p[1].args: if e.__class__ is node.funcall: e.__class__ = node.arrayref # XXX if isinstance(p[1], node.getfield): # import pdb;pdb.set_trace() # A.B=C setfield(A,B,C) p[0] = node.setfield(p[1].args[0], p[1].args[1], p[3]) else: # assert len(p[1].args) > 0 ret = p[1].args if isinstance(p[1], node.matrix) else p[1] p[0] = node.let(ret=ret, args=p[3], lineno=p.lineno(2), lexpos=p.lexpos(2)) if isinstance(p[1], node.matrix): # TBD: mark idents as "P" - persistent if p[3].__class__ not in (node.ident, node.funcall): #, p[3].__class__ raise_exception(SyntaxError, "multi-assignment", new_lexer) if p[3].__class__ is node.ident: # [A1(B1) A2(B2) ...] = F implied F() # import pdb; pdb.set_trace() p[3] = node.funcall(func_expr=p[3], args=node.expr_list()) # [A1(B1) A2(B2) ...] = F(X) p[3].nargout = len(p[1].args[0]) elif p[2] == "*": p[0] = node.funcall(func_expr=node.ident("dot"), args=node.expr_list([p[1], p[3]])) elif p[2] == ".*": p[0] = node.funcall(func_expr=node.ident("multiply"), args=node.expr_list([p[1], p[3]])) # elif p[2] == "." and isinstance(p[3],node.expr) and p[3].op=="parens": # p[0] = node.getfield(p[1],p[3].args[0]) # raise SyntaxError(p[3],p.lineno(3),p.lexpos(3)) elif p[2] == ":" and isinstance(p[1], node.expr) and p[1].op == ":": # Colon expression means different things depending on the # context. As an array subscript, it is a slice; otherwise, # it is a call to the "range" function, and the parser can't # tell which is which. So understanding of colon expressions # is put off until after "resolve". p[0] = p[1] p[0].args.insert(1, p[3]) else: p[0] = node.expr(op=p[2], args=node.expr_list([p[1], p[3]]))
def resolve(t, symtab=None, fp=None, func_name=None): if symtab is None: symtab = {} do_resolve(t, symtab) G = as_networkx(t) #import pdb;pdb.set_trace() for n in G.nodes(): u = G.node[n]["ident"] if u.props: pass elif G.out_edges(n) and G.in_edges(n): u.props = "U" # upd #print u.name, u.lineno, u.column elif G.in_edges(n): u.props = "D" # def elif G.out_edges(n): u.props = "R" # ref else: u.props = "F" # ??? G.node[n]["label"] = "%s\\n%s" % (n, u.props) for u in node.postorder(t): #if u.__class__ is node.func_decl: # u.ident.name += "_" if u.__class__ is node.funcall: try: if u.func_expr.props in "UR": # upd,ref u.__class__ = node.arrayref #else: # u.func_expr.name += "_" except: pass for u in node.postorder(t): if u.__class__ in (node.arrayref, node.cellarrayref): for i, v in enumerate(u.args): if v.__class__ is node.expr and v.op == ":": v.op = "::" # for w in node.postorder(v): # if w.__class__ is node.expr and w.op == "end": # w.args[0] = u.func_expr # w.args[1] = node.number(i) for u in node.postorder(t): if u.__class__ is node.let: if (u.ret.__class__ is node.ident and u.args.__class__ is node.matrix): u.args = node.funcall(func_expr=node.ident("matlabarray"), args=node.expr_list([u.args])) H = nx.connected_components(G.to_undirected()) for i, component in enumerate(H): for nodename in component: if G.node[nodename]["ident"].props == "R": has_update = 1 break else: has_update = 0 if has_update: for nodename in component: G.node[nodename]["ident"].props += "S" # sparse #S = G.subgraph(nbunch) #print S.edges() return G
def p_expr_colon(p): "colon : COLON" p[0] = node.expr(op=":", args=node.expr_list())