void exNode ( nodeType *p, int c, int l, /* start column and line of node */ int *ce, int *cm /* resulting end column and mid of node */ ) { int w, h; /* node width and height */ char *s; /* node text */ int cbar; /* "real" start column of node (centred above subnodes) */ int k; /* child number */ int che, chm; /* end column and mid of children */ int cs; /* start column of children */ char word[20]; /* extended node text */ if (!p) return; strcpy (word, "???"); /* should never appear */ s = word; switch(p->type) { case typeCon: sprintf (word, "c(%d)", p->con.value); break; case typeId: sprintf (word, "id(%c)", p->id.i + 'A'); break; case typeOpr: switch(p->opr.oper){ case WHILE: s = "while"; break; case IF: s = "if"; break; case PRINT: s = "print"; break; case ';': s = "[;]"; break; case '=': s = "[=]"; break; case UMINUS: s = "[_]"; break; case '+': s = "[+]"; break; case '-': s = "[-]"; break; case '*': s = "[*]"; break; case '/': s = "[/]"; break; case '<': s = "[<]"; break; case '>': s = "[>]"; break; case GE: s = "[>=]"; break; case LE: s = "[<=]"; break; case NE: s = "[!=]"; break; case EQ: s = "[==]"; break; } break; } /* construct node text box */ graphBox (s, &w, &h); cbar = c; *ce = c + w; *cm = c + w / 2; /* node is leaf */ if (p->type == typeCon || p->type == typeId || p->opr.nops == 0) { graphDrawBox (s, cbar, l); return; } /* node has children */ cs = c; for (k = 0; k < p->opr.nops; k++) { exNode (p->opr.op[k], cs, l+h+eps, &che, &chm); cs = che; } /* total node width */ if (w < che - c) { cbar += (che - c - w) / 2; *ce = che; *cm = (c + che) / 2; } /* draw node */ graphDrawBox (s, cbar, l); /* draw arrows (not optimal: children are drawn a second time) */ cs = c; for (k = 0; k < p->opr.nops; k++) { exNode (p->opr.op[k], cs, l+h+eps, &che, &chm); graphDrawArrow (*cm, l+h, chm, l+h+eps-1); cs = che; } }
void exNode ( nodeType *p, int c, int l, /* start column and line of node */ int *ce, int *cm /* resulting end column and mid of node */ ) { int w, h; /* node width and height */ char *s; /* node text */ int cbar; /* "real" start column of node (centred above subnodes) */ uint32_t k; /* child number */ int che, chm; /* end column and mid of children */ int cs; /* start column of children */ char word[20]; /* extended node text */ if(!p) return; strcpy (word, "???"); /* should never appear */ s = word; std::string temp; switch(p->type()) { case node::NodeIdentIFace::INT: sprintf(word, "%ld", dynamic_cast<const node::TermNodeIFace<node::NodeIdentIFace::INT>*>(p)->value()); break; case node::NodeIdentIFace::FLOAT: sprintf(word, "%f", dynamic_cast<const node::TermNodeIFace<node::NodeIdentIFace::FLOAT>*>(p)->value()); break; case node::NodeIdentIFace::STRING: sprintf(word, "\"%s\"", dynamic_cast<const node::TermNodeIFace<node::NodeIdentIFace::STRING>*>(p)->value()->c_str()); break; case typeId: sprintf(word, "%s", dynamic_cast<const node::TermNodeIFace<node::NodeIdentIFace::IDENT>*>(p)->value()->c_str()); break; case typeOpr: temp = p->name(); s = const_cast<char*>(temp.c_str()); break; default: break; } /* construct node text box */ graphBox (s, &w, &h); cbar = c; *ce = c + w; *cm = c + w / 2; /* node is term */ if(p->type() != typeOpr || dynamic_cast<const node::SymbolNodeIFace*>(p)->size() == 0) { graphDrawBox (s, cbar, l); return; } /* node has children */ cs = c; for(k = 0; k < dynamic_cast<const node::SymbolNodeIFace*>(p)->size(); k++) { exNode (dynamic_cast<const node::SymbolNodeIFace*>(p)->operator[](k), cs, l+h+eps, &che, &chm); cs = che; } /* total node width */ if(w < che - c) { cbar += (che - c - w) / 2; *ce = che; *cm = (c + che) / 2; } /* draw node */ graphDrawBox (s, cbar, l); /* draw arrows (not optimal: children are drawn a second time) */ cs = c; for(k = 0; k < dynamic_cast<const node::SymbolNodeIFace*>(p)->size(); k++) { exNode (dynamic_cast<const node::SymbolNodeIFace*>(p)->operator[](k), cs, l+h+eps, &che, &chm); graphDrawArrow (*cm, l+h, chm, l+h+eps-1); cs = che; } }
/* 递归算法 -------- 如果当前节点是叶子节点: 绘制当前节点,返回; 如果有子节点: 绘制所有子节点; 绘制自己; 绘制箭头; */ void exNode ( nodeType *p, int c, int l, /* start column and line of node */ int *ce, int *cm /* resulting end column and mid of node: 输出行结尾列坐标+1,输出行中间坐标 */ ) { int w, h; /* node width and height */ char *s; /* node text */ int cbar; /* "real" start column of node (centred above subnodes) */ int k; /* child number */ int che, chm; /* end column and mid of children */ int cs; /* start column of children */ char word[20]; /* extended node text */ //JYD //if (!p) return; strcpy (word, "???"); /* should never appear */ s = word; if (!p) { s = "(null)"; goto draw; } switch(p->type) { case typeCon: sprintf (word, "c(%d)", p->con.value); break; case typeId: sprintf (word, "id(%c)", p->id.i + 'A'); break; case typeOpr: switch(p->opr.oper){ case WHILE: s = "while"; break; case IF: s = "if"; break; case PRINT: s = "print"; break; case ';': s = "[;]"; break; case '=': s = "[=]"; break; case UMINUS: s = "[_]"; break; case '+': s = "[+]"; break; case '-': s = "[-]"; break; case '*': s = "[*]"; break; case '/': s = "[/]"; break; case '<': s = "[<]"; break; case '>': s = "[>]"; break; case GE: s = "[>=]"; break; case LE: s = "[<=]"; break; case NE: s = "[!=]"; break; case EQ: s = "[==]"; break; } break; } draw: /* construct node text box */ graphBox (s, &w, &h); cbar = c; *ce = c + w; //随后的第一个空列: _ab [<-cm] c[ce] *cm = c + w / 2; //中间列 /* node is leaf */ if (!p || p->type == typeCon || p->type == typeId || p->opr.nops == 0) { graphDrawBox (s, cbar, l); return; } /* node has children */ cs = c; //起始列 for (k = 0; k < p->opr.nops; k++) { //绘制各子节点 exNode (p->opr.op[k], cs, l+h+eps, &che, &chm); //行加上用于分隔的eps(=3)行 cs = che; // 新列 } /* total node width */ if (w < che - c) { //子节点总宽度大于 当前节点的宽度,需要调整当前的节点的起始输出列 cbar += (che - c - w) / 2; *ce = che; *cm = (c + che) / 2; } /* draw node */ graphDrawBox (s, cbar, l); //输出当前节点 /* draw arrows (not optimal: children are drawn a second time) */ cs = c; for (k = 0; k < p->opr.nops; k++) { exNode (p->opr.op[k], cs, l+h+eps, &che, &chm);//为了得到che和chm graphDrawArrow (*cm, l+h, chm, l+h+eps-1); cs = che; } }
/* Draw the syntax tree using this function recursively. */ void exNode(nodeType *p, int c, int l, int *ce, int *cm){ int w, h; char *s; int cbar; int k; int che, chm; int cs; char word[64]; if(!p) return; strcpy(word,"???"); s = word; /* Set the corresponding displaying strings. */ switch(p->type){ case typeCon: sprintf(word, "c(%d)", p->con.value); break; case typeId: sprintf(word, "id(%s)", p->id.i); break; case typeOpr: switch(p->opr.oper){ case IF: s = "if"; break; case FOR: s = "for"; break; case RETURN: s = "return"; break; case ELSE: s = "else"; break; case CONT: s = "continue"; break; case BREAK: s = "break"; break; case STRUCT: s = "struct"; break; case TYPE: s = "int"; break; case SEMI: s = "semi"; break; case COMMA: s = "comma"; break; case DOT: s = "dot"; break; case LP: s = "lp"; break; case RP: s = "rp"; break; case LB: s = "lb"; break; case RB: s = "rb"; break; case LC: s = "lc"; break; case RC: s = "rc"; break; case 199: s = "program"; break; case 200: s = "extdefs"; break; case 201: s = "extdef"; break; case 202: s = "extvars"; break; case 203: s = "spec"; break; case 204: s = "stspec"; break; case 205: s = "opttag"; break; case 206: s = "var"; break; case 207: s = "func"; break; case 208: s = "paras"; break; case 209: s = "para"; break; case 210: s = "stmtblock"; break; case 211: s = "stmts"; break; case 212: s = "stmt"; break; case 213: s = "estmt"; break; case 214: s = "defs"; break; case 215: s = "def"; break; case 216: s = "decs"; break; case 217: s = "dec"; break; case 218: s = "init"; break; case 219: s = "arrs"; break; case 220: s = "args"; break; case 221: s = "exp"; break; case 222: s = "exp/null"; break; case 'e': s = "VOID"; break; case 300: s = "[&&]"; break; case 301: s= "[||]"; break; case 302: s = "[+=]"; break; case 303: s = "[-=]"; break; case 304: s = "[*=]"; break; case 305: s = "[/=]"; break; case 306: s = "[&=]"; break; case 307: s = "[^=]"; break; case 308: s = "[|=]"; break; case 309: s = "[<<=]"; break; case 310: s = "[>>=]"; break; case 311: s = "[<<]"; break; case 312: s = "[>>]"; break; case 313: s = "[>=]"; break; case 314: s = "[<=]"; break; case 315: s = "[==]"; break; case 316: s = "[!=]"; break; case 317: s = "[++]"; break; case 318: s = "[--]"; break; case '+': s = "[+]"; break; case '-': s = "[-]"; break; case '*': s = "[*]"; break; case '/': s = "[/]"; break; case '^': s = "[^]"; break; case '%': s = "[%]"; break; case '!': s = "[!]"; break; case '~': s = "[~]"; break; case '=': s = "[=]"; break; case '<': s = "[<]"; break; case '>': s = "[>]"; break; } break; } graphBox(s, &w, &h); cbar = c; *ce = c+w; *cm = c+w/2; if(p->type == typeCon || p->type == typeId || p->opr.nops == 0){ graphDrawBox(s, cbar, l); return; } cs = c; for(k = 0;k<p->opr.nops;k++){ exNode(p->opr.op[k], cs, l+h+eps, &che, &chm); cs = che; } if(w<che-c){ cbar+=(che-c-w)/2; *ce = che; *cm = (c+che)/2; } graphDrawBox(s, cbar, l); cs = c; for(k = 0;k<p->opr.nops;k++){ exNode(p->opr.op[k], cs, l+h+eps, &che, &chm); graphDrawArrow(*cm, l+h, chm, l+h+eps-1); cs = che; } }