⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 node.c

📁 深入理解计算机系统 的lab
💻 C
字号:
/* Functions to generate C or Verilog code from HCL *//* This file maintains a parse tree representation of expressions */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "node.h"#define MAXBUF 1024void yyerror(const char *str);void yyserror(const char *str, char *other);/* For error reporting */static char* show_expr(node_ptr expr);/* The symbol table */#define SYM_LIM 100static node_ptr sym_tab[2][SYM_LIM];static int sym_count = 0;/* Optional simulator name */char simname[MAXBUF] = "";extern FILE *outfile;/* * usage - print helpful diagnostic information */static void usage(char *name){#ifdef VLOG    fprintf(stderr, "Usage: %s [-h] <HCL file  >verilog file\n", name);    fprintf(stderr, "Input HCL file on stdin, output verilog code on stdout.\n");#else    fprintf(stderr, "Usage: %s [-h] <HCL file  >C file\n", name);    fprintf(stderr, "Input HCL file on stdin, output C file on stdout.\n");#endif    fprintf(stderr, "   -h     Print this message\n");    exit(0);}/* Initialization */void init_node(int argc, char **argv){    int c;    /* Parse the command line arguments */    while ((c = getopt(argc, argv, "hn")) != -1) {	switch(c) {	case 'h':	    usage(argv[0]);	    break;	case 'n': /* Optional simulator name */	    strcpy(simname, argv[optind]);	    break;	default:	    printf("Invalid option '%c'\n", c);	    usage(argv[0]);	    break;	}    }#ifndef VLOG    /* Define and initialize the simulator name */    if (!strcmp(simname, "")) 	printf("char simname[] = \"Y86 Processor\";\n");    else	printf("char simname[] = \"Y86 Processor: %s\";\n", simname);#endif}static void add_symbol(node_ptr name, node_ptr val){    if (sym_count >= SYM_LIM) {	yyerror("Symbol table limit exceeded");	return;    }    sym_tab[0][sym_count] = name;    sym_tab[1][sym_count] = val;    sym_count++;}static char *node_names[] =  {"quote", "var", "num", "and", "or", "not", "comp", "ele", "case"};static void show_node(node_ptr node){    printf("Node type: %s, Boolean ? %c, String value: %s\n",	   node_names[node->type], node->isbool ? 'Y':'N', node->sval);}void finish_node(int check_ref){    if (check_ref) {	int i;	for (i = 0; i < sym_count; i++)	    if (!sym_tab[0][i]->ref) {		fprintf(stderr, "Warning, argument '%s' not referenced\n",			sym_tab[0][i]->sval);	    }    }}static node_ptr find_symbol(char *name){    int i;    for (i = 0; i < sym_count; i++) {	if (strcmp(name, sym_tab[0][i]->sval) == 0) {	    node_ptr result = sym_tab[1][i];	    sym_tab[0][i]->ref++;	    return result;	}    }    yyserror("Symbol %s not found", name);    return NULL;}static node_ptr new_node(node_type_t t, int isbool,			 char *s, node_ptr a1, node_ptr a2){    node_ptr result = malloc(sizeof(node_rec));    result->type = t;    result->isbool = isbool;    result->sval = s;    result->arg1 = a1;    result->arg2 = a2;    result->ref = 0;    result->next = NULL;    return result;}/* Concatenate two lists */node_ptr concat(node_ptr n1, node_ptr n2){    node_ptr tail = n1;    if (!n1)	return n2;    while (tail->next)	tail = tail->next;    tail->next = n2;    return n1;}static void free_node(node_ptr n){    free(n->sval);    free(n);}node_ptr make_quote(char *qstring){    /* Quoted string still has quotes around it */    int len = strlen(qstring)-2;    char *sname = malloc(len+1);    strncpy(sname, qstring+1, len);    sname[len] = '\0';    return new_node(N_QUOTE, 0, sname, NULL, NULL);}node_ptr make_var(char *name){    char *sname = malloc(strlen(name)+1);    strcpy(sname, name);    /* Initially assume var is not Boolean */    return new_node(N_VAR, 0, sname, NULL, NULL);}node_ptr make_num(char *name){    char *sname = malloc(strlen(name)+1);    strcpy(sname, name);    return new_node(N_NUM, 0, sname, NULL, NULL);}void set_bool(node_ptr varnode){    if (!varnode)	yyerror("Null node encountered");    varnode->isbool = 1;}/* Make sure argument is OK */static int check_arg(node_ptr arg, int wantbool){    if (!arg) {	yyerror("Null node encountered");	return 0;    }    if (arg->type == N_VAR) {	node_ptr qval = find_symbol(arg->sval);	if (!qval) {	    yyserror("Variable '%s' not found", arg->sval);	    return 0;	}	if (wantbool != qval->isbool) {	    if (wantbool)		yyserror("Variable '%s' not Boolean", arg->sval);	    else		yyserror("Variable '%s' not integer", arg->sval);	    return 0;	}	return 1;    }    if (arg->type == N_NUM) {        if (wantbool && strcmp(arg->sval,"0") != 0 &&	    strcmp(arg->sval,"1") != 0) {	    yyserror("Value '%s' not Boolean", arg->sval);	    return 0;        }	return 1;    }    if (wantbool && !arg->isbool)	yyserror("Non Boolean argument '%s'", show_expr(arg));    if (!wantbool && arg->isbool)	yyserror("Non integer argument '%s'", show_expr(arg));    return (wantbool == arg->isbool);}node_ptr make_not(node_ptr arg){    check_arg(arg, 1);    return new_node(N_NOT, 1, "!", arg, NULL);}node_ptr make_and(node_ptr arg1, node_ptr arg2){    check_arg(arg1, 1);    check_arg(arg2, 1);    return new_node(N_AND, 1, "&", arg1, arg2);}node_ptr make_or(node_ptr arg1, node_ptr arg2){    check_arg(arg1, 1);    check_arg(arg2, 1);    return new_node(N_OR, 1, "|", arg1, arg2);}node_ptr make_comp(node_ptr op, node_ptr arg1, node_ptr arg2){    check_arg(arg1, 0);    check_arg(arg2, 0);    return new_node(N_COMP, 1, op->sval, arg1, arg2);}node_ptr make_ele(node_ptr arg1, node_ptr arg2){    node_ptr ele;    check_arg(arg1, 0);    for (ele = arg1; ele; ele = ele->next)	check_arg(ele, 0);    return new_node(N_ELE, 1, "in", arg1, arg2);}node_ptr make_case(node_ptr arg1, node_ptr arg2){    check_arg(arg1, 1);    check_arg(arg2, 0);    return new_node(N_CASE, 0, ":", arg1, arg2);}void insert_code(node_ptr qstring){    if (!qstring)	yyerror("Null node");    else {#ifndef VLOG	fputs(qstring->sval, outfile);	fputs("\n", outfile);#endif    }}void add_arg(node_ptr var, node_ptr qstring, int isbool){    if (!var || !qstring) {	yyerror("Null node");	return;    }    add_symbol(var, qstring);    if (isbool) {	set_bool(var);	set_bool(qstring);    }}static char expr_buf[1024];static int errlen = 0;#define MAXERRLEN 80/* Recursively display expression for error reporting */static void show_expr_helper(node_ptr expr){    switch(expr->type) {	int len;	node_ptr ele;    case N_QUOTE:	len = strlen(expr->sval) + 2;	if (len + errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, "'%s'", expr->sval);	    errlen += len;	}	break;    case N_VAR:	len = strlen(expr->sval);	if (len + errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, expr->sval);	    errlen += len;	}	break;    case N_NUM:	len = strlen(expr->sval);	if (len + errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, expr->sval);	    errlen += len;	}	break;    case N_AND:	if (errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, "(");	    errlen+=1;	    show_expr_helper(expr->arg1);	    sprintf(expr_buf+errlen, " & ");	    errlen+=3;	}	if (errlen < MAXERRLEN) {	    show_expr_helper(expr->arg2);	    sprintf(expr_buf+errlen, ")");	    errlen+=1;	}	break;    case N_OR:	if (errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, "(");	    errlen+=1;	    show_expr_helper(expr->arg1);	    sprintf(expr_buf+errlen, " | ");	    errlen+=3;	}	if (errlen < MAXERRLEN) {	    show_expr_helper(expr->arg2);	    sprintf(expr_buf+errlen, ")");	    errlen+=1;	}	break;    case N_NOT:	if (errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, "!");	    errlen+=1;	    show_expr_helper(expr->arg1);	}	break;    case N_COMP:	if (errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, "(");	    errlen+=1;	    show_expr_helper(expr->arg1);	    sprintf(expr_buf+errlen, " %s ", expr->sval);	    errlen+=4;	}	if (errlen < MAXERRLEN) {	    show_expr_helper(expr->arg2);	    sprintf(expr_buf+errlen, ")");	    errlen+=1;	}	break;    case N_ELE:	if (errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, "(");	    errlen+=1;	    show_expr_helper(expr->arg1);	    sprintf(expr_buf+errlen, " in {");	    errlen+=5;	}	for (ele = expr->arg2; ele; ele=ele->next) {	    if (errlen < MAXERRLEN) {		show_expr_helper(ele);		if (ele->next) {		    sprintf(expr_buf+errlen, ", ");		    errlen+=2;		}	    }	}	if (errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, "})");	    errlen+=2;	}	break;    case N_CASE:	if (errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, "[ ");	    errlen+=2;	}	for (ele = expr; errlen < MAXERRLEN && ele; ele=ele->next) {	    show_expr_helper(ele->arg1);	    sprintf(expr_buf+errlen, " : ");	    errlen += 3;	    show_expr_helper(ele->arg2);	}	if (errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, " ]");	    errlen+=2;	}	break;    default:	if (errlen < MAXERRLEN) {	    sprintf(expr_buf+errlen, "??");	    errlen+=2;	}	break;    }}static char *show_expr(node_ptr expr){    errlen = 0;    show_expr_helper(expr);    if (errlen >= MAXERRLEN)	sprintf(expr_buf+errlen, "...");    return expr_buf;}/* Recursively generate code for function */static void gen_expr(node_ptr expr){    node_ptr ele;    switch(expr->type) {    case N_QUOTE:	yyserror("Unexpected quoted string", expr->sval);	break;    case N_VAR:	{	    node_ptr qstring = find_symbol(expr->sval);	    if (qstring)#ifdef VLOG		fprintf(outfile, "(%s)", expr->sval);#else		fprintf(outfile, "(%s)", qstring->sval);#endif	    else		yyserror("Invalid variable '%s'", expr->sval);	}	break;    case N_NUM: 	fputs(expr->sval, outfile);	break;    case N_AND:	fprintf(outfile, "(");	gen_expr(expr->arg1);	fprintf(outfile, " & ");	gen_expr(expr->arg2);	fprintf(outfile, ")");	break;    case N_OR:	fprintf(outfile, "(");	gen_expr(expr->arg1);	fprintf(outfile, " | ");	gen_expr(expr->arg2);	fprintf(outfile, ")");	break;    case N_NOT:#ifdef VLOG	fprintf(outfile, "~");#else	fprintf(outfile, "!");#endif	gen_expr(expr->arg1);	break;    case N_COMP:	fprintf(outfile, "(");	gen_expr(expr->arg1);	fprintf(outfile, " %s ", expr->sval);	gen_expr(expr->arg2);	fprintf(outfile, ")");	break;    case N_ELE:	fprintf(outfile, "(");	for (ele = expr->arg2; ele; ele=ele->next) {	    gen_expr(expr->arg1);	    fprintf(outfile, " == ");	    gen_expr(ele);	    if (ele->next)#ifdef VLOG		fprintf(outfile, "|");#else		fprintf(outfile, "||");#endif	}	fprintf(outfile, ")");	break;    case N_CASE:	fprintf(outfile, "(");	for (ele = expr; ele; ele=ele->next) {	    gen_expr(ele->arg1);	    fprintf(outfile, " ? ");	    gen_expr(ele->arg2);	    fprintf(outfile, " : ");	}	fprintf(outfile, "0)");	break;    default:	yyerror("Unknown node type");	break;    }}/* Generate code defining function for var */void gen_funct(node_ptr var, node_ptr expr, int isbool){    if (!var || !expr) {	yyerror("Null node");	return;    }    check_arg(expr, isbool);#ifdef VLOG    fprintf(outfile, "assign %s = \n    ", var->sval);    gen_expr(expr);    fprintf(outfile, ";\n");    #else    /* Print function header */    fprintf(outfile, "int gen_%s()\n{\n    return ", var->sval);    gen_expr(expr);    fprintf(outfile, ";\n}\n\n");#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -