📄 analyze.h
字号:
#ifndef ANALYZE_H_
#define ANALYZE_H_
#include "global.h"
#include "symtable.h"
using namespace std;
int InsertSymbolList(TreeNode *p)
{
int location_old=location;
if(p==NULL || p->kind!=DECLAR)
return 0;
while(p!=NULL)
{
st_insert(p->name,GetType(p),GetSymbolType(p),location,p->lineno);
if(p->childkind.declarK!=FUNC_DECLAR)
{
if(p->arraynum>0)
location+=p->arraynum;
else location+=1;
}
p=p->pNext;
}
return location-location_old;
}
void SymbolTraverse(TreeNode *t)
{
static SymbolRecord * sFunc;
if (t != NULL)
{
if(t->kind==DECLAR && t->childkind.declarK==FUNC_DECLAR)
{
location=-3; //skip ret&ofp
SymbolRecord *s;
s=sFunc=st_lookup(t->name);
TreeNode *tempt=t->pChild[0];
if(tempt!=NULL){
s=s->pParam=new SymbolRecord;
while(tempt!=NULL){
s->name=tempt->name;
s->type=GetType(tempt);
if(tempt->childkind.declarK==ARRAY_DECLAR)
s->symboltype=
(tempt->arraynum==0?
ARRAYADDR_SYMBOL:ARRAY_SYMBOL);
else s->symboltype=VAR_SYMBOL;
s->lineno=tempt->lineno;
s->location=location;
s->nestlevel=1;
s->pNext=NULL;
location--;
tempt=tempt->pNext;
if(tempt!=NULL){
SymbolRecord *stemp=s;
s=s->pNext=new SymbolRecord;
}
}
}
else s->pParam=NULL;
sFunc->paramAlloc=-location-3;
location=0;
}
else if(t->kind==CSTMT)
{
pCurrentST=t->pBucketList=st_new();
nestlevel++;
sFunc->localAlloc+=InsertSymbolList(t->pChild[0]);
}
for (int i=0; i < MAXCHILDREN; i++){
SymbolTraverse(t->pChild[i]);
}
if(t->kind==CSTMT) nestlevel--;
SymbolTraverse(t->pNext);
}
}
void BuildSymbolTable(TreeNode *t)
{
globalAlloc=InsertSymbolList(t);
SymbolTraverse(t);
}
void CheckNode(TreeNode *t)
{
SymbolRecord *s=st_lookup(t->name);
switch(t->kind)
{
case DECLAR:
break;
case OP:
if(t->pChild[0]->type!=INTEGER_TYPE ||
t->pChild[1]->type!=INTEGER_TYPE) {
SyntaxError(string("Operands of '")+t->name+"' not consist",
t->lineno);
}
t->type=INTEGER_TYPE;
break;
case RELOP:
if(t->pChild[0]->type!=INTEGER_TYPE ||
t->pChild[1]->type!=INTEGER_TYPE) {
SyntaxError(string("Operands of '")+t->name+"' not consist",
t->lineno);
}
t->type=BOOLEAN_TYPE;
break;
case STMT:
switch(t->childkind.stmtK)
{
case IF_STMT:
if(t->pChild[0]->type!=BOOLEAN_TYPE){
SyntaxError("The expression of 'if' statement is not type of boolean",
t->lineno);
}
break;
case WHILE_STMT:
if(t->pChild[0]->type!=BOOLEAN_TYPE){
SyntaxError("The expression of 'while' statement is not type of boolean",
t->lineno);
}
break;
case RETURN_STMT:
s=st_lookup(FuncName);
if(s->type==VOID_TYPE){
if(t->pChild[0]!=NULL){
SyntaxError(string("Function '")+FuncName+"' do not return a value",
t->lineno);
}
}
else if(t->pChild[0]==NULL){
SyntaxError(string("Function '")+FuncName+"' must return a value",
t->lineno);
}
else if(s->symboltype!=FUNC_SYMBOL ||
t->pChild[0]->type!=s->type) {
SyntaxError(string("Function '")+FuncName+"' must return a value of type int",
t->lineno);
}
break;
}
break;
case REFER:
if(s==NULL){
SyntaxError(string("ID '")+t->name+"' not defined",
t->lineno);
t->type=ERROR_TYPE;
break;
}
if(t->pChild[0]!=NULL)
if(s->symboltype!=ARRAY_SYMBOL &&
s->symboltype!=ARRAYADDR_SYMBOL){
SyntaxError(string("ID '")+t->name+"' must be an array",
t->lineno);
}
t->type=s->type;
break;
case CALL:
if(s==NULL){
SyntaxError(string("ID '")+t->name+"' must be an array",
t->lineno);
t->type=ERROR_TYPE;
break;
}
t->type=s->type;
if(s->symboltype!=FUNC_SYMBOL){
SyntaxError(string("'")+t->name+"' is not a function",
t->lineno);
}
else{
TreeNode *ttemp=t->pChild[0];
s=s->pParam;
while(s!=NULL && ttemp!=NULL){
if(ttemp->type!=s->type) break;
s=s->pNext;
ttemp=ttemp->pNext;
}
if(ttemp!=NULL || s!=NULL){
SyntaxError(string("Function call '")+t->name+"' has an error in its arguments",
t->lineno);
}
}
break;
case PARAM:
break;
case CSTMT:
break;
case EXP:
switch(t->childkind.expK)
{
case ASSIGN_EXP:
if(s->type!=t->pChild[1]->type){
SyntaxError(string("Oprands of '=' not consist"),
t->lineno);
}
if(t->pChild[0]!=NULL)
if(s->symboltype!=ARRAY_SYMBOL &&
s->symboltype!=ARRAYADDR_SYMBOL){
SyntaxError(string("ID '")+t->name+"' must be an array",
t->lineno);
}
t->type=s->type;
break;
}
break;
case NUM:
t->type=INTEGER_TYPE;
break;
}
}
void CheckTraverse( TreeNode * t)
{
if (t != NULL)
{
if(t->kind==DECLAR && t->childkind.declarK==FUNC_DECLAR){
FuncName=t->name;
location=0;
}
else if(t->kind==CSTMT) st_addon(t->pBucketList);
for (int i=0; i<MAXCHILDREN; i++)
CheckTraverse(t->pChild[i]);
if(t->kind==DECLAR && t->childkind.declarK==FUNC_DECLAR){
FuncName="";
}
else if(t->kind==CSTMT) st_takeoff();
CheckNode(t);
CheckTraverse(t->pNext);
}
}
void TypeCheck(TreeNode *t)
{
CheckTraverse(t);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -