📄 util.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 + -