struct ast_node* token_id(char *name) { struct ast_node *node; struct symbol *sym; switch (current_token) { case TOKEN_LPARENTH : node = function_call(name); break; case TOKEN_LBRACKET: node = access_node(name); break; default: sym = symbol_table_lookup_all(name); if (sym == NULL) { sym = symbol_new(name, VALUE_TYPE_UNKNOWN); symbol_table_global_put_symbol(sym); } node = (struct ast_node *)ast_node_id(name); break; } return AST_NODE(node); }
// reset the color of node to G // return its PREVIOUS color COLOR ConstraintGraph::erase_color(const GNode & node){ COLOR pre; GNode & n = access_node(node); pre=n.color; n.color = G; return pre; }
// add an edge between u,v bool ConstraintGraph::do_add_edge(const GNode &u,const GNode &v,EType type){ GEdge &uv = access_edge(u,v); GEdge &vu = access_edge(v,u); GNode &unode = access_node(u); GNode &vnode = access_node(v); if( uv.type == NOEDGE || uv.type == type ){// safely add edge uv.type = type; uv.count++; unode.ecount++; vu.type = type; // symmetric vu.count++; vnode.ecount++; } else report_exit("Trying to add incompatible edge type"); return true; }
// remove (one) edge between node u,v // note that when the node becomes standalone, also rip its color bool ConstraintGraph::remove_edge(const GNode &u,const GNode &v){ GEdge &uv = access_edge(u,v); GEdge &vu = access_edge(v,u); GNode &unode = access_node(u); GNode &vnode = access_node(v); assert( uv.count == vu.count ); // edge not exist, if( uv.count == 0 ) return false; uv.count--; if( uv.count == 0 ) uv.type = NOEDGE; unode.ecount--; if( unode.ecount == 0 ) erase_color(u); vu.count--; // symmetric if( vu.count == 0 ) vu.type = NOEDGE; vnode.ecount--; if( vnode.ecount == 0 ) erase_color(v); return true; }
// try to add edge with color awareness // return EXIST if the edge exists already bool ConstraintGraph::add_edge_color(const GNode &u,const GNode &v, EType type) { // first check if edge exist int a=get_node_idx(u); int b=get_node_idx(v); //GEdge & uv = access_edge(u,v); GEdge & uv = edge[a][b]; if( uv.type != NOEDGE ){// already has an edge if( uv.type != type ) return false; // type incompatible else do_add_edge(u,v,type); // safely add dummy edge } // now we ensure u-v edge NOT exist(NOEDGE) // check if adding this edge will conflict // explore all 9 cases: {G,H,V} X {G,H,V} assert( u != v ); GNode & unode = access_node(u); GNode & vnode = access_node(v); COLOR ucolor = get_color(u); COLOR vcolor = get_color(v); // node u standalone, which means color = G if( ucolor == G ){ assert( unode.ecount == 0 ); do_add_edge(u,v,type); // safely add edge if( vcolor == G ){ // G,G: color them set_color(unode,HI); if( type == DIFF ) set_color(vnode,LO); else set_color(vnode,HI); } else if( vcolor == HI ){// G,H if( type == DIFF ) set_color(unode,LO); else set_color(unode,HI); } else{// G,L if( type == DIFF ) set_color(unode,HI); else set_color(unode,LO); } return SUCCESS; } // v standlone(symmetric to previous case) else if( vcolor == G ) { assert( vnode.ecount == 0 ); do_add_edge(v,u,type); // safely add edge if( ucolor == G ){ // G,G: color them set_color(unode,LO); if( type == DIFF ) set_color(vnode,HI); else set_color(vnode,LO); } else if( ucolor == HI ){// H,G if( type == DIFF ) set_color(vnode,LO); else set_color(vnode,HI); } else{// L,G if( type == DIFF ) set_color(vnode,HI); else set_color(vnode,LO); } return SUCCESS; } else{// u,v not standalone => u,v has colors, but not connected if( (ucolor != vcolor && type == DIFF) || // different color, DIFF edge (ucolor == vcolor && type == SAME)) // same color, SAME edge {// type compatible do_add_edge(u,v,type); // safely link them return SUCCESS; } // H-L, H-H or L-L // try to swap the color // of one connected component //ConstraintGraph bak(*this); // make backup reverse_color(v); // reverse the coloring of v component COLOR u_newcolor = get_color(u); if( ucolor != u_newcolor ){ // if u's color changed=>2-color failed //*this = bak; return FAIL; } else{ do_add_edge(u,v,type);// safely link them return SUCCESS; } } }