/* * Definitions of the parse tree functions. */ #include #include "STreeNode.h" static const char *TypeToDescription(NodeType t) { static const char *typenames[] = { "ID", "CLASS DEC", "FIELD DEC", "CONSTRUCTOR DEC", "METHOD DEC", "PARAMETER DEC", "VARIABLE DEC", "EMPTY STMT", "RETURN STMT", "IF STMT", "WHILE STMT", "ASSIGNMENT STMT", "COMPOUND EXP", "OPERATOR", "INT CONST", "DOUBLE CONST", "STRING CONST", "BOOL CONST", "FIELD REF", "METHOD CALL", "CONSTRUCTOR CALL", "CAST", "NULL", "THIS" }; return typenames[t]; } /* output the required number of spaces to the stream */ static void pad(FILE *os, const unsigned int indent) { int j; static const int indentfactor = 2; for (j=0; j < indent*indentfactor; ++j) { fprintf(os," "); } } STreePtr Create(const NodeType t, const STreePtr c0, const STreePtr c1, const STreePtr c2, const STreePtr c3) { unsigned int j; STreePtr n = (STreePtr)malloc(sizeof(struct STreeNode)); n->type=t; for (j=0; jchildren[j]=0; } n->sibling=0; n->children[0]=c0; n->children[1]=c1; n->children[2]=c2; n->children[3]=c3; n->extrainfo=0; return n; } STreePtr CreateString(const NodeType t, const char *s) { unsigned int j; STreePtr n=(STreePtr)malloc(sizeof(struct STreeNode)); n->type=t; for (j=0; jchildren[j]=0; } n->sibling=0; n->extrainfo=0; SetExtraInfo(n,s); return n; } /* Destructor */ void Destroy(STreePtr n) { unsigned int j; for (j=0; jchildren[j] != 0) { Destroy(n->children[j]); n->children[j]=0; } } if (n->sibling!=0) /* note not a loop */ { /* the rest destroyed recursively */ Destroy(n->sibling); n->sibling=0; } if (n->extrainfo!=0) { free(n->extrainfo); } free(n); } bool HasChild(const STreePtr n) { unsigned int j; for (j=0; jchildren[j]!=0) { return TRUE; } } return FALSE; } STreePtr GetChild(STreePtr n, unsigned int i) { return (ichildren[i] : 0; } void SetChild(STreePtr n, const unsigned int i, const STreePtr c) { if (ichildren[i]!=0) { Destroy(n->children[i]); } n->children[i]=c; } } void SetLastSibling(STreePtr n, const STreePtr c) { STreePtr target=n; while (target->sibling != 0) { target=target->sibling; } SetSibling(target, c); } void SetSibling(STreePtr n, const STreePtr c) { if (n->sibling!=0) { Destroy(n->sibling); } n->sibling=c; } void SetExtraInfo(STreePtr n, const char *s) { if (n->extrainfo!=0) { free(n->extrainfo); n->extrainfo=0; /* in case someone tries to overwrite with null */ } if (s!=0) { n->extrainfo = (char *)malloc(strlen(s)*sizeof(char)+1); strcpy(n->extrainfo, s); } } void Print(const STreePtr n, FILE *os, unsigned int indent) { unsigned int i, j; unsigned int lastchild = 0; STreePtr s = n->sibling; pad(os, indent); fprintf(os, "%s", TypeToDescription(n->type)); if (n->extrainfo != 0) fprintf(os, " %s", n->extrainfo); fprintf(os, "\n"); if (HasChild(n)) { indent++; for (j=0; jchildren[j]!=0) { lastchild=j; } } for (i=0; i<=lastchild; ++i) { if (n->children[i]==0) { pad(os, indent); fprintf(os, "null\n"); } else { Print(n->children[i], os, indent); } } indent--; } if (s!=0) { Print(s, os, indent); } }