www.pudn.com > subpas.rar > util.c


/****************************************************/ 
/* File: util.c                                     */ 
/* Utility function interface                       */ 
/* for the SubPas compiler                          */ 
/****************************************************/ 
 
#include "globals.h" 
#include "util.h" 
#include "parse.h" 
 
/* 返回树节点的数据类型 
 * @param tree 指向该节点的指针 
 * @return 类型的字符表达式,如"integer","boolean","real"等 
 */ 
char * getType(TreeNode *tree) 
{  
	static char * datatype[] = {"integer","real","boolean","array","void","unkown type"}; 
	if (!tree || tree->type < Integer || tree->type > Void) 
		return datatype[5]; 
	return datatype[tree->type]; 
} 
 
/* 在listing文件中打印出一个token的识别 
 * @param token 该token的类别 
 * @param tokenString 该token在源文件中的字符串表示 
*/ 
void printToken(TokenType token, const char* tokenString ) 
{ switch (token) 
  { 
    case ARRAY: 
    case BOOLEAN: 
    case DO: 
    case ELSE: 
    case END: 
    case MYFALSE: 
    case FUNCTION: 
    case IF: 
    case INTEGER: 
    case MYBEGIN: 
	case OF: 
    case PROCEDURE: 
    case PROGRAM: 
    case REAL: 
    case THEN: 
    case MYTRUE: 
    case VAR: 
    case WHILE: 
      fprintf(listing,"reserved word: %s\n",tokenString); 
      break; 
    case PLUS: fprintf(listing,"+\n"); break; 
    case MINUS: fprintf(listing,"-\n"); break; 
    case TIMES: fprintf(listing,"*\n"); break; 
    case DIV: fprintf(listing,"DIV\n"); break; 
    case MOD: fprintf(listing,"MOD\n");break; 
    case LT: fprintf(listing,"<\n"); break; 
    case LE: fprintf(listing,"<=\n"); break; 
    case GT: fprintf(listing,">\n"); break; 
    case GE: fprintf(listing,">=\n"); break; 
    case EQ: fprintf(listing,"=\n"); break; 
    case NE: fprintf(listing,"<>\n"); break; 
    case AND: fprintf(listing,"and\n"); break; 
    case OR: fprintf(listing,"or\n"); break; 
    case NOT: fprintf(listing,"not\n"); break; 
    case ASSIGNOP: fprintf(listing,":=\n"); break; 
    case LP: fprintf(listing,"(\n"); break; 
    case RP: fprintf(listing,")\n"); break; 
	case LSP: fprintf(listing,"[\n"); break; 
	case RSP: fprintf(listing,"]\n"); break; 
	case SEMI: fprintf(listing,";\n"); break; 
	case COMMA: fprintf(listing,",\n"); break; 
	case COLON: fprintf(listing,":\n"); break; 
	case DOT: fprintf(listing,".\n"); break; 
    case NUM: fprintf(listing,"NUM, val= %s\n",tokenString); break; 
	case REALNUM:fprintf(listing,"REALNUM,val=%s\n",tokenString);break; 
    case ID: fprintf(listing,"ID, name= %s\n",tokenString); break; 
    case ERROR:fprintf(listing,"ERROR: %s\n",tokenString); break; 
	case 0: fprintf(listing,"End of file.\n");break; 
    default: /* should never happen */ 
      fprintf(listing,"Unknown token: %d\n",token); 
  } 
} 
 
/* 建立一个过程的节点 
 * @param kind 过程的小类别:MainP或SubP 
 * @return 指向该节点的指针 
 */ 
TreeNode * newProNode(ProKind kind) 
{  
  TreeNode * t = (TreeNode *) malloc(sizeof(TreeNode)); 
  int i; 
  if (t==NULL) 
    fprintf(listing,"Out of memory error at line %d\n",lineno); 
  else { 
    for (i=0;ichild[i] = NULL; 
    t->sibling = NULL; 
    t->nodekind = Pro; 
    t->lineno = lineno; 
    t->kind.pro = kind; 
	t->offset = 0; 
    t->name = NULL; 
  } 
  return t; 
} 
 
/* 建立一个语句的节点 
 * @param kind 语句的小类别,IfK,WhileK,AssignK等 
 * @return 指向该节点的指针 
 */ 
TreeNode * newStmtNode(StmtKind kind) 
{ TreeNode * t = (TreeNode *) malloc(sizeof(TreeNode)); 
  int i; 
  if (t==NULL) 
    fprintf(listing,"Out of memory error at line %d\n",lineno); 
  else { 
    for (i=0;ichild[i] = NULL; 
    t->sibling = NULL; 
    t->nodekind = Stmt; 
    t->lineno = lineno; 
    t->kind.stmt = kind; 
	t->offset = 0; 
    t->name = NULL; 
    t->ltrue = NULL; 
    t->lfalse = NULL; 
  } 
  return t; 
} 
 
/* 建立一个表达式的节点 
 * @param kind 表达式的小类别:OpK,IdK,NumK等 
 * @return 指向该节点的指针 
 */ 
TreeNode * newExpNode(ExpKind kind) 
{ TreeNode * t = (TreeNode *) malloc(sizeof(TreeNode)); 
  int i; 
  if (t==NULL) 
    fprintf(listing,"Out of memory error at line %d\n",lineno); 
  else { 
    for (i=0;ichild[i] = NULL; 
    t->sibling = NULL; 
    t->nodekind = Exp; 
    t->lineno = lineno; 
    t->kind.exp = kind; 
	t->offset = 0; 
    t->name = NULL; 
    t->ltrue = NULL; 
    t->lfalse = NULL; 
  } 
  return t; 
} 
 
 
/* 分配相应空间,将一个字符串复制到该空间中,再返回 
 * 复制后的字符串指针 
 * @param s 要复制的字符串 
 * @return  指向新空间的字符串指针 
 */ 
char * copyString(char * s) 
{ size_t n; 
  char * t; 
  if (s==NULL) return NULL; 
  n = strlen(s)+1; 
  t = malloc(n); 
  if (t==NULL) 
    fprintf(listing,"Out of memory error at line %d\n",lineno); 
  else strcpy(t,s); 
  return t; 
} 
/* 用一个链表来模拟堆栈*/ 
typedef struct savedFunName{ 
	char * name; 
	struct savedFunName * next; 
} SavedFunName; 
 
/* savedfunname是一个链表,用于保存函数的名字*/ 
static SavedFunName * savedfunname = NULL; 
 
/* 将一个字符串指针压入栈 
 * @param name 要入栈的字符串指针 
*/ 
void pushName(char * name) 
{ 
	SavedFunName * temp = (SavedFunName *)malloc(sizeof(SavedFunName)); 
	temp->name = name; 
	temp->next = savedfunname; 
	savedfunname = temp; 
} 
/* 将栈顶的字符串指针出栈 
 * @return 指向出栈后的字符串指针 
*/ 
char * popName(void) 
{ 
	char * name; 
	SavedFunName * temp = savedfunname; 
	savedfunname = savedfunname->next; 
	name = temp->name; 
	free(temp); 
	return name; 
} 
/* 变量indentno用来格式化打印语法树(主要是tab缩进表示) 
 */ 
static int indentno = 0; 
 
/* macros to increase/decrease indentation */ 
#define INDENT indentno++ 
#define UNDENT indentno-- 
 
/* 打印indentno个tab */ 
static void printTab(void) 
{ int i; 
  for (i=0;inodekind) { 
   case Pro: 
     switch(tree ->kind.pro){ 
     case MainP: 
          if (tree->child[1]){ 
			fprintf(listing,"\n\nPROGRAM NAME:%s\n",tree->name); 
            fprintf(listing,"*****************Print Tree Start:********************\n"); 
            fprintf(listing,"Global Declarations:\n"); 
            t = tree->child[1]; 
            while(t){ 
              fprintf(listing,"\tname:%s\ttype:%s \n",t->name,getType(t)); 
              t=t->sibling; 
            } 
          }  
          printTree(tree->sibling); 
          INDENT;printTree(tree->child[2]);UNDENT; 
          fprintf(listing,"*****************Print Tree Ends.*********************\n\n"); 
          break; 
     case SubP: 
          fprintf(listing,"==================================\n"); 
          if(tree->type==Void) 
            fprintf(listing,"Procedure name: %s\n ",tree->name); 
          else fprintf(listing,"Function name:%s\n",tree->name); 
          fprintf(listing,"\tParameters:\n"); 
          t = tree->child[0]; 
		  if(t==NULL) fprintf(listing,"\t\tNone.\n"); 
          else  while(t){ 
            fprintf(listing,"\t\tname:%s\ttype:%s\n",t->name,getType(t)); 
            t=t->sibling; 
          } 
		  if(tree->type	!=Void)  
			fprintf(listing,"\treturn type:%s\n",getType(tree)); 
 
          fprintf(listing,"\tLocal Declarations:\n"); 
          t = tree->child[1]; 
		  if(t==NULL) fprintf(listing,"\t\tNone.\n"); 
          else while(t){ 
            fprintf(listing,"\t\tname:%s\ttype:%s\n",t->name,getType(t)); 
            t=t->sibling; 
          }    
          INDENT;printTree(tree->child[2]); UNDENT; 
          fprintf(listing,"=================================\n"); 
          printTree(tree->sibling); 
          break; 
     } 
     break; 
   case Stmt: 
     switch(tree ->kind.stmt){ 
         case IfK: 
			printTab();fprintf(listing,"If-statement:\n"); 
			printTab();fprintf(listing,"\tcondition:\n"); 
			INDENT;printTree(tree->child[0]);UNDENT; 
			printTab();fprintf(listing,"\n\t\ttrue:\n"); 
			INDENT;printTree(tree->child[1]);UNDENT; 
			printTab();fprintf(listing,"\n\t\tfalse:\n"); 
			INDENT;printTree(tree->child[2]);UNDENT; 
			printTab();fprintf(listing,"If-statement ends.\n"); 
			break; 
         case WhileK: 
			printTab();fprintf(listing,"While-statement:\n"); 
			printTab();fprintf(listing,"\tcondition:\n"); 
			INDENT;printTree(tree->child[0]);UNDENT; 
			printTab();fprintf(listing,"\tloop:\n"); 
			INDENT;printTree(tree->child[1]);UNDENT; 
			printTab();fprintf(listing,"While-statement ends.\n"); 
			break; 
         case AssignK: 
			printTab();fprintf(listing,"Assign-statement:\n"); 
			printTab();fprintf(listing,"\t%s assigned to\n",tree->child[0]->name); 
			INDENT;printTree(tree->child[1]);UNDENT; 
			printTab();fprintf(listing,"Assign-statement ends.\n"); 
			break; 
         case CallK: 
			printTab();fprintf(listing,"Call-statement:\n"); 
			printTab();fprintf(listing,"\tCalls:%s\n",tree ->name); 
			printTab();fprintf(listing,"\tparams:\n"); 
			t = tree->child[0]; 
			if(t==NULL){printTab();fprintf(listing,"\t\tNone.\n");} 
			else {INDENT;printTree(t);UNDENT;} 
			printTab();fprintf(listing,"Call-statement ends.\n"); 
			break; 
        } 
     printTree(tree->sibling); 
     break; 
   case Exp: 
     switch(tree->kind.exp){ 
     case NumK: 
        printTab();fprintf(listing,"Num_Const: %d\n",tree->attr.intval); 
        break; 
     case RealNumK: 
        printTab();fprintf(listing,"Real_Const: %f\n",tree->attr.realval); 
        break; 
	 case BoolK: 
		printTab(); 
		if(tree->attr.intval==0) fprintf(listing,"BoolValue:false\n"); 
		else fprintf(listing,"BoolValue:true\n"); 
		break; 
     case IdK: 
		printTab();fprintf(listing,"Variable: %s\n",tree->name); 
        break; 
     case SignK: 
        printTab(); 
        if(tree->attr.op==MINUS) 
          fprintf(listing,"-(inverse):\n");  
        INDENT;printTree(tree->child[0]);UNDENT; 
		break; 
     default: 
        printTab();fprintf(listing,"Op: "); 
        printToken(tree->attr.op,"\0"); 
        INDENT;printTree(tree->child[0]);UNDENT; 
        INDENT;printTree(tree->child[1]);UNDENT; 
        break; 
     } 
     printTree(tree->sibling); 
     break; 
   default: 
      printTab();fprintf(listing,"Unknown treenode kind!\n"); 
      break; 
      } 
  } 
}