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

📄 util.cpp

📁 一个c语言的编译器的源代码
💻 CPP
字号:
// This file defines some useful functions,
// just as tools :)
//
// Written by bood, boodweb@163.com, http://boodweb.126.com
// 2004-08-06

// Parameters are as a part of function local variables now
// so no more parameter printing in 'PrintOneTable' now
// by bood, 2005-01-22

// Add function 'ReportPos', report the error pos(filename&lineno)
// Other error handling functions are also modified to adopt this
// change
// bood, 2005-03-13

#pragma warning(disable:4786)

#include <iostream>
#include <string>
#include <map>
#include "global.h"
#include "symtable.h"
#include "pp_scan.h"
#include "util.h"

using namespace std;
int indent=0;
map<TokenType,string> TokenMap;

// Initialize the keyword maping
void init()
{
	TokenMap[IF]="if";
	TokenMap[ELSE]="else";
	TokenMap[WHILE]="while";
	TokenMap[RETURN]="return";
	TokenMap[VOID]="void";
	TokenMap[INT]="int";
	TokenMap[PLUS]="+";
	TokenMap[MINUS]="-";
	TokenMap[MUL]="*";
	TokenMap[DIV]="/";
	TokenMap[LT]="<";
	TokenMap[LTEQ]="<=";
	TokenMap[GT]=">";
	TokenMap[GTEQ]=">=";
	TokenMap[EQ]="=";
	TokenMap[NEQ]="!=";
	TokenMap[ASSIGN]="==";
	TokenMap[SEMI]=";";
	TokenMap[COMMA]=",";
	TokenMap[LPAREN]="(";
	TokenMap[RPAREN]=")";
	TokenMap[LSQUAR]="[";
	TokenMap[RSQUAR]="]";
	TokenMap[LBRACE]="{";
	TokenMap[RBRACE]="}";
	TokenMap[LCOMMENT]="/*";
	TokenMap[RCOMMENT]="*/";
	TokenMap[ID]="identifier";
	TokenMap[NUMBER]="number";
}

// Create a new node in the syntax tree
// and return the pointer to it
//
// Note!This function DO NOT join the new
// node into the tree, that job is done by
// the caller
TreeNode *NewNode(Kind kind)
{
	TreeNode *p;
	p=new TreeNode;
	p->kind=kind;
	p->pNext=NULL;
	p->arraynum=-1;
	p->lineno=lineno;
	for(int i=0;i<MAXCHILDREN;i++)
		p->pChild[i]=NULL;
	return p;
}

// Just print number of `indent`'s spaces
void PrintIndent(ostream &os)
{
	for(int i=0;i<indent;i++)
		os<<" ";
}
/*
void PrintDeclar(TreeNode *p,ostream &os)
{
}
void PrintExp(TreeNode *p,ostream &os)
{
}
void PrintParam(TreeNode *p,ostream &os)
{
}
void PrintArgs(TreeNode *p,ostream &os)
{
}
*/
// Print the syntax tree, the parameters
// are obvious :)
void PrintSyntaxTree(TreeNode *p,ostream &os)
{
	if(p==NULL) return;
	indent+=2;
	while(p!=NULL)
	{
        PrintIndent(os); //for good looking
		switch(p->kind)
		{
		case DECLAR:
			switch(p->childkind.declarK)
			{
			case VAR_DECLAR:
				os<<"Variable Declaration: "<<p->name<<endl;
				break;
			case FUNC_DEFINE:
				os<<"Function Definition: "<<p->name
					<<", Parameters: "<<endl;
				break;
			}
			break;
		case OP:
		case RELOP:
			os<<p->name<<endl;
			break;
		case STMT:
			switch(p->childkind.stmtK)
			{
			case IF_STMT:
				os<<"if_then_else"<<endl;
				break;
			case WHILE_STMT:
				os<<"while_do"<<endl;
				break;
			case RETURN_STMT:
				os<<"return"<<endl;
				break;
			}
			break;
		case REFER:
			os<<"ID: "<<p->name<<endl;
			break;
		case CALL:
			os<<"CALL: "<<p->name<<", Arguments: "<<endl;
			break;
		case PARAM:
			os<<p->name<<endl;
			break;
		case CSTMT:
			os<<"Compound Statement: "<<endl;
			break;
		case EXP:
			switch(p->childkind.expK)
			{
			case ASSIGN_EXP:
				os<<"Assignment: "<<p->name<<endl;
				break;
			case SIMPLE_EXP:
				os<<"Simple Expression"<<endl;
				break;
			}
			break;
		case NUM:
			os<<"Literal: "<<p->name<<endl;
			break;
		}
        // Recurse for child nodes
		for(int i=0;i<MAXCHILDREN;i++)
			PrintSyntaxTree(p->pChild[i],os);
		p=p->pNext;
	}
	indent-=2;
}
// Print one table, i.e. with in a compound statment
// BucketList is used for symbol saving(hash table used)
void PrintOneTable(BucketList *p,ostream &os)
{
	BucketList *t=p;
	for(int i=0;i<BUCKET_SIZE;i++)
	{
		if(t->pRecord[i]==NULL) continue;
		else{
			SymbolRecord * p=t->pRecord[i];
			do{
				os<<p->name<<"\t\t"<<p->location
					<<"\t\t"<<p->lineno<<"\t\t"<<
					p->nestlevel<<endl;
				p=p->pNext;
			}while(p!=NULL);
		}
	}
}
// Print the symbol table
//
void PrintSymbolTable(TreeNode *p,ostream &os)
{
	if(p==NULL) return;
	while(p!=NULL)
	{
		if(p->kind==CSTMT){
			PrintOneTable(p->pBucketList,os);
		}
		for(int i=0;i<MAXCHILDREN;i++)
			PrintSymbolTable(p->pChild[i],os);
		p=p->pNext;
	}
}

// TreeNode => Type
// Return the type of the variable
// ONLY node of function parameter
// or declaration accepted
Type GetType(TreeNode *t)
{
	Type type=ERROR_TYPE;
	if(t->kind==PARAM){
		if(t->tokenT==INT) type=INTEGER_TYPE;
	}
	else if(t->kind==DECLAR){
		type=t->tokenT==INT?INTEGER_TYPE:VOID_TYPE;
	}
	return type;
}
//
// TreeNode=>SymbolType (FUNCTION or VAR or ARRAY)
SymbolType GetSymbolType(TreeNode *t)
{
	SymbolType symboltype=ERROR_SYMBOL;
	if(t->childkind.declarK==FUNC_DECLAR)
        symboltype=FUNC_DECLAR_SYMBOL;
	else if(t->childkind.declarK==FUNC_DEFINE)
		symboltype=FUNC_DEFINE_SYMBOL;
	else if(t->childkind.declarK==VAR_DECLAR)
		symboltype=VAR_SYMBOL;
	else if(t->arraynum<=0)
        symboltype=ARRAYADDR_SYMBOL;
    else
        symboltype=ARRAY_SYMBOL;
	return symboltype;
}

// Token-type => Token-string
string GetTokenString(TokenType token)
{
	return TokenMap[token];
}

//
// Error reporting below
//
void ReportPos(int lineno, ostream &os)
{
    /* for debug
    while(include_it!=include_list.end()) {
        os<<include_it->lineno<<' '<<
            include_it->file_lineno<<' '<<
            include_it->filename<<endl;
        include_it++;
    }
    */
    while(lineno>=include_it->lineno&&
        include_it!=include_list.end())
        include_it++;
    include_it--;

    // when comes here, inlcude_it is the last
    // satisfying lineno>=include_it->lineno
    lineno = lineno - include_it->lineno +
        include_it->file_lineno;
    os<<include_it->filename<<'('<<lineno<<"): ";
}
void SemanticError(string errinfo,int lineno,int ref_lineno,
                   ostream &os)
{
    ReportPos(lineno, cout);
	os<<"semantic error: "<<errinfo;

    // if has reference line number, locate it
    // generate a "see line XXX in YYY"
    if(ref_lineno>0) {
        list<INCLUDE_NODE>::iterator include_it =
            include_list.begin();
        while(ref_lineno>=include_it->lineno&&
            include_it!=include_list.end())
            include_it++;
        include_it--;
        if(ref_lineno<include_it->lineno) include_it--;
        ref_lineno = ref_lineno - include_it->lineno +
            include_it->file_lineno;
        os<<", see line "<< ref_lineno <<" in "<<
            include_it->filename;
    }
    os<<endl;
	bSemanticError=1;
}
void ParseError(string errinfo,int lineno, ostream &os)
{
    ReportPos(lineno, cout);
	os<<"syntax error: "<<errinfo<<endl;
	os<<"Compiling interrupped"<<endl;
    bParseError=1;
    exit(lineno);
}
void GenError(string errinfo, ostream &os)
{
	os<<"Cann't generate code: "<<errinfo<<endl;
	os<<"Compiling interrupped"<<endl;
	exit(-1);
}

⌨️ 快捷键说明

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