Phase 5 Hint


Symbol Table

Created by the parser, it is referenced by the node structure (int symval;).

typedef struct sym_entry {
    char *name;
    int val;
    enum token toktype;
    struct sym_entry *link;
} SYM_ENTRY;

Definition Table

Created by the scoping routine use a preorder (node-left-right) tree traversal. Entries are added for parameters or variables. The defiinition table is referenced by the node structure (int defval).

typedef struct def {
    enum type_t type;
    enum v_kind kind;
} DEFINITION;
enum v_kind {
    PARAMETER,
    VARIABLE
};
enum type_t {
    TYPE_ILLEGAL, /* initial value */
    TYPE_INT,
    TYPE_FLOAT,
    TYPE_ERROR,
    TYPE_NONE    /* for typeless nodes */
};
Type Checking

Performed after the scoping procedure. Performs a post order traversal (left-right-node) of the expression tree. Adds nodetype to each node and adds INT_TO_FLOAT and TRUNCATE as appropriate..

enum token

The token values as recorded in the symbol table.

enum token {
    TOK_PLUS,      TOK_MINUS,    TOK_MULT,      TOK_DIV,    TOK_PERCENT,  TOK_BANG,    TOK_QUES,     TOK_COLON,
    TOK_ASSIGN,    TOK_COMMA,    TOK_LT,        TOK_GT,     TOK_OPAR,     TOK_CLPAR,   TOK_OCURLY,   TOK_CLCURLY,
    TOK_OR,        TOK_AND,      TOK_EQUAL,     TOK_SEMI,   TOK_BREAK,    TOK_CONTIN,  TOK_ELSE,     TOK_FLOAT,
    TOK_IF,        TOK_INT,      TOK_RETURN,    TOK_WHILE,  TOK_IDENT,    TOK_INTNUM,  TOK_FLOATNUM, TOK_EOF,
    TOK_COMMENT,   TOK_SPACE,    TOK_ERR,	       TOK_UNKNOWN    };

enum node_ty

Node type added to each node by the type checking procedure.

enum node_ty {
    /* use this for initializing */
    ILLEGAL_NODE,

    /* this is the top node of the tree */
    SOURCE,
   
    /* these are the two types in C-- */
    INTTYPE,    FLOATTYPE,

    /* this is a declaration */
    DECL,

    /* these are leaves with values */
    INTNUM,    FLOATNUM,    IDENT,

    /* these are statements */
    COMPOUND,    CONDITIONAL,    ITERATION,    BREAK,    CONTINUE,    RETURN,    COMPUTATION,    EMPTY,

    /* these are expressions */
    ASSIGN,    CONDITION,    OR_OP,    AND_OP,    NOT_OP,    EQUAL_OP,    GT_OP,    LT_OP,
    ADD_OP,    SUB_OP,    MULT_OP,    DIV_OP,    MOD_OP,    NEG_OP,
    /* new nodes needed after overloading has been resolved */
    ADD_OP_INT,    ADD_OP_FLOAT,    SUB_OP_INT,    SUB_OP_FLOAT,    MULT_OP_INT,    MULT_OP_FLOAT,
    DIV_OP_INT,    DIV_OP_FLOAT,    NEG_OP_INT,    NEG_OP_FLOAT,    GT_OP_INT,    GT_OP_FLOAT,
    LT_OP_INT,    LT_OP_FLOAT,    EQUAL_OP_INT,    EQUAL_OP_FLOAT,    INT_TO_FLOAT,    TRUNCATE    };

node structure

typedef struct node {
    enum node_ty nodetype;
    struct node *child[3];  /* used for tree structure */
    struct node *link;      /* used for linked lists */
    union
        {
        int intval;
        int symval;
        float floatval;
        } val;
    int defval;             /* set by scoping routine */
    enum type_t valtype;    /* set by typing routine */
    int line, column;
} NODE;

Two fields are added to the existing NODE structure (from phase 4): an index into the definition table (defval, applicable only to IDENT nodes), and the value type (valtype) of the node as described above.


void showSymbolTable() {

    SYM_ENTRY * x;

	char * symbolTokStr[] =
    {
    "TOK_PLUS",     "TOK_MINUS",     "TOK_MULT",    "TOK_DIV",      "TOK_PERCENT",
    "TOK_BANG",     "TOK_QUES",      "TOK_COLON",   "TOK_ASSIGN",   "TOK_COMMA",
    "TOK_LT",	     "TOK_GT",        "TOK_OPAR",    "TOK_CLPAR",    "TOK_OCURLY",
    "TOK_CLCURLY",  "TOK_OR",        "TOK_AND",     "TOK_EQUAL",    "TOK_SEMI",
    "TOK_BREAK",    "TOK_CONTIN",    "TOK_ELSE",    "TOK_FLOAT",    "TOK_IF",
    "TOK_INT",      "TOK_RETURN",    "TOK_WHILE",   "TOK_IDENT",    "TOK_INTNUM",
    "TOK_FLOATNUM",    "TOK_EOF",    "TOK_COMMENT", "TOK_SPACE",    "TOK_ERR", 
	"TOK_UNKNOWN"    };

	printf("symbol table entries follows\n");

    for (x=sym_table; x!=NULL; x=x->link) {

		printf("# = %3d    ", x->val);
		printf("token # = %3d    ", x->toktype);
		printf("token type = %12s    ", symbolTokStr[x->toktype]);
		printf("name = %s\n",x->name);
	}
}


void printDefinitionTable() {
	char * type_t_string[] = {
		"TYPE_ILLEGAL",       /* initial value */
		"TYPE_INT    ",
		"TYPE_FLOAT  ",
		"TYPE_ERROR  ",
		"TYPE_NONE   "           /* for typeless nodes */
    };

	char * v_kind_string[] = {
		"PARAMETER",
		"VARIABLE "
		};

	printf("DEFINITION def_table[%d]\n", def_cnt);
	for(int i = 0; i < def_cnt; i++) {
		printf("entry = %2d ",i);
		printf("kind = %12s ", v_kind_string[def_table[i].kind]);
		printf("type = %12s\n",	type_t_string[def_table[i].type]);
	}
}


void printNode(NODE * n) {
        char * node_ty_string[] =
    {   "ILLEGAL_NODE",    "SOURCE",        "INTTYPE",      "FLOATTYPE",    "DECL",
        "INTNUM",          "FLOATNUM",      "IDENT",        "COMPOUND",     "CONDITIONAL",
        "ITERATION",       "BREAK",         "CONTINUE",     "RETURN",       "COMPUTATION",
        "EMPTY",           "ASSIGN",        "CONDITION",    "OR_OP",        "AND_OP",       
        "NOT_OP",          "EQUAL_OP",      "GT_OP",        "LT_OP",        "ADD_OP",
        "SUB_OP",          "MULT_OP",       "DIV_OP",       "MOD_OP",       "NEG_OP",
        "ADD_OP_INT",      "ADD_OP_FLOAT",  "SUB_OP_INT",   "SUB_OP_FLOAT", "MULT_OP_INT",
        "MULT_OP_FLOAT",   "DIV_OP_INT",    "DIV_OP_FLOAT", "NEG_OP_INT",   "NEG_OP_FLOAT",
        "GT_OP_INT",       "GT_OP_FLOAT",   "LT_OP_INT",    "LT_OP_FLOAT",  "EQUAL_OP_INT",
        "EQUAL_OP_FLOAT",  "INT_TO_FLOAT",  "TRUNCATE"
    };

    char * type_t_string[] =  {"TYPE_ILLEGAL","TYPE_INT","TYPE_FLOAT",
                               "TYPE_ERROR","TYPE_NONE"};

        char * loc_string[] =  {"NO_LOC", "M_LOC", "I_REG", "F_REG" };
        
        int node_ty_string_entries = sizeof(node_ty_string) / sizeof(char *);
        int type_t_string_entries = sizeof(type_t_string) / sizeof(char *);
        int loc_string_entries = sizeof(loc_string) / sizeof(char *);

        if(n == NULL) {
                printf("node pointer is NULL in printnode\n");
                return;
        }

        printf("node type = %s\n",node_ty_string[n->nodetype]);

        if(n->child[0] == NULL) printf("child[0] = NULL\n");
        else 
                if(n->child[0]->nodetype < 0 || n->child[0]->nodetype >= node_ty_string_entries)
                        printf("child[0] = %s\n", "***ILLEGAL***");
                        else
                                printf("child[0] = %s\n",node_ty_string[n->child[0]->nodetype]);
        
        if(n->child[1] == NULL) printf("child[1] = NULL\n");
        else 
                if(n->child[1]->nodetype < 0 || n->child[1]->nodetype >= node_ty_string_entries)
                        printf("child[0] = %s\n", "***ILLEGAL***");
                        else
                                printf("child[1] = %s\n",node_ty_string[n->child[1]->nodetype]);
        
        if(n->child[2] == NULL) printf("child[2] = NULL\n");
        else 
                if(n->child[2]->nodetype < 0 || n->child[2]->nodetype >= node_ty_string_entries)
                        printf("child[0] = %s\n", "***ILLEGAL***");
                        else
                                printf("child[2] = %s\n",node_ty_string[n->child[2]->nodetype]);

        if(n->link == NULL) printf("link = NULL\n");
        else 
                if(n->link->nodetype < 0 || n->link->nodetype >= node_ty_string_entries)
                        printf("link = %s\n", "***ILLEGAL***");
                        else
                                printf("link = %s\n",node_ty_string[n->link->nodetype]);
                        
        printf("intval = %d   symval = %d   floatval = %f\n",
                n->val.intval, n->val.symval, n->val.floatval);
        printf("defval = %d\n",n->defval);
        
        if(n->valtype < 0 || n->valtype >= type_t_string_entries)
                printf("valtype = %s\n", "***ILLEGAL***");
                else
                        printf("valtype = %s\n",type_t_string[n->valtype]);
        
        printf("\n");
}


C-- Operators