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

📄 analyze.c

📁 1.小型编译器 2。支持整数
💻 C
字号:
/****************************************************/
/* File: analyze.c                                  */
/* Semantic analyzer implementation                 */
/* for the TINY compiler                            */
/* Compiler Construction: Principles and Practice   */
/* Kenneth C. Louden                                */
/****************************************************/

#include "Globals.h"
#include "SymTab.h"
#include "Analyze.h"

/* counter for variable memory locations */
static int location = 0;

/* Procedure traverse is a generic recursive 
 * syntax tree traversal routine:
 * it applies preProc in preorder and postProc 
 * in postorder to tree pointed to by t
 */
static void traverse( TreeNode * t,
               void (* preProc) (TreeNode *),
               void (* postProc) (TreeNode *) )
{
	if (t != NULL)
  	{ 
  		preProc(t);
    	{
			int i;
      		for (i=0; i < MAXCHILDREN; i++)
        		traverse(t->child[i],preProc,postProc);
    	}
    	postProc(t);
    	traverse(t->sibling,preProc,postProc);
  	}
}

/* nullProc is a do-nothing procedure to 
 * generate preorder-only or postorder-only
 * traversals from traverse
 */
static void nullProc(TreeNode * t)
{ 
	if (t==NULL) 
		return;
  	else 
		return;
}

/* Procedure insertNode inserts 
 * identifiers stored in t into 
 * the symbol table 
 */
static void insertNode( TreeNode * t)
{
	switch (t->nodekind)
  	{ 
  		case StmtK:
	      	switch (t->kind.stmt)
	      	{ 
	      		case AssignK:
	        	case ReadK:
	          		if (st_lookup(t->attr.name) == -1)
	          			/* not yet in table, so treat as new definition */
	            		st_insert(t->attr.name,t->lineno,location++);
	          		else
	          			/* already in table, so ignore location, 
	             		add line number of use only */ 
	            		st_insert(t->attr.name,t->lineno,0);
	          			break;
	        	default:
	          		break;
	      	}
	      	break;
    	case ExpK:
      		switch (t->kind.exp)
      		{
      			case IdK:
          			if (st_lookup(t->attr.name) == -1)
          				/* not yet in table, so treat as new definition */
           				st_insert(t->attr.name,t->lineno,location++);
          			else
          				/* already in table, so ignore location, 
             			add line number of use only */ 
            			st_insert(t->attr.name,t->lineno,0);
          			break;
        		default:
          			break;
     		}
      		break;
    	default:
      		break;
  	}
}

/* Function buildSymtab constructs the symbol 
 * table by preorder traversal of the syntax tree
 */
void buildSymtab(TreeNode * syntaxTree)
{
	traverse(syntaxTree,insertNode,nullProc);
  	if (TraceAnalyze)
  	{ 
  		fprintf(listing,"\nSymbol table:\n\n");
    	printSymTab(listing);
  	}
}

static void typeError(TreeNode * t, const char * message)
{ 
	fprintf(listing,"Type error at line %d: %s\n",t->lineno,message);
  	Error = TRUE;
}

/* Procedure checkNode performs
 * type checking at a single tree node
 */
static void checkNode(TreeNode * t)
{
	switch (t->nodekind)
  	{ 
  		case ExpK:
      		switch (t->kind.exp)
      		{
      			case OpK:
          			if ((t->child[0]->type != Integer) ||
              			(t->child[1]->type != Integer))
            			typeError(t,"Op applied to non-integer");
          			if ((t->attr.op == EQ) || (t->attr.op == LT))
            			t->type = Boolean;
         			else
            			t->type = Integer;
          			break;
        		case ConstK:
        		case IdK:
          			t->type = Integer;
          			break;
        		default:
          			break;
      		}
      		break;
    	case StmtK:
      		switch (t->kind.stmt)
      		{ 
      			case IfK:
          			if (t->child[0]->type == Integer)
            			typeError(t->child[0],"if test is not Boolean");
          			break;
        		case AssignK:
          			if (t->child[0]->type != Integer)
            			typeError(t->child[0],"assignment of non-integer value");
          			break;
        		case WriteK:
          			if (t->child[0]->type != Integer)
            			typeError(t->child[0],"write of non-integer value");
          			break;
        		case RepeatK:
          			if (t->child[1]->type == Integer)
            			typeError(t->child[1],"repeat test is not Boolean");
         			break;
        		default:
          			break;
      		}
      		break;
    	default:
      		break;

  	}
}

/* Procedure typeCheck performs type checking 
 * by a postorder syntax tree traversal
 */
void typeCheck(TreeNode * syntaxTree)
{ 
	traverse(syntaxTree,nullProc,checkNode);
}

⌨️ 快捷键说明

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