📄 语义分析.txt
字号:
return NULL;
Eptr1 = Expr(t->child[0],NULL);//intPtr;
if(Eptr1==NULL)
return NULL;
present = Compat(Eptr0,Eptr1);
if(present!=TRUE)
{
ErrorPrompt(t->lineno,"","type is not matched with the array member error !\n");
Eptr = NULL;
}
else
Eptr = entry->attrIR.idtype->More.ArrayAttr.elemTy;
}
}
else/*标识符无声明*/
ErrorPrompt(t->lineno,t->name[0],"is not declarations!\n");
return Eptr;
}
/************************************************************/
/* 函数名 recordVar */
/* 功 能 该函数处理记录变量中域的分析 */
/* 说 明 检查var:=var0.id中的var0是不是记录类型变量,id是 */
/* 不是该记录类型中的域成员。 */
/************************************************************/
Cglobal::TypeIR * Canalyze::recordVar(TreeNode * t)
{
int present = FALSE;
int result = TRUE;
SymbTable * entry = NULL;
TypeIR * Eptr0 = NULL;
TypeIR * Eptr1 = NULL;
TypeIR * Eptr = NULL;
fieldchain * currentP = NULL;
/*在符号表中查找此标识符*/
present = FindEntry(t->name[0],&entry);
t->table[0] = entry;
/*找到*/
if(present!=FALSE)
{
/*Var0不是变量*/
if (FindAttr(entry).kind!=varKind)
{
ErrorPrompt(t->lineno,t->name[0],"is not variable error!\n");
Eptr = NULL;
}
else/*Var0不是记录类型变量*/
if(FindAttr(entry).idtype->kind!=recordTy)
{
ErrorPrompt(t->lineno,t->name[0],"is not record variable error !\n");
Eptr = NULL;
}
else/*检查id是否是合法域名*/
{
Eptr0 = entry->attrIR.idtype;
currentP = Eptr0->More.body;
while((currentP!=NULL)&&(result!=FALSE))
{
result = strcmp(t->child[0]->name[0],currentP->id);
/*如果相等*/
if(result==FALSE)
Eptr = currentP->UnitType;
else
currentP = currentP->Next;
}
if(currentP==NULL)
if(result!=FALSE)
{
ErrorPrompt(t->child[0]->lineno,t->child[0]->name[0],
"is not field type!\n");
Eptr = NULL;
}
else/*如果id是数组变量*/
if(t->child[0]->child[0]!=NULL)
Eptr = arrayVar(t->child[0]);
}
}
else/*标识符无声明*/
ErrorPrompt(t->lineno,t->name[0],"is not declarations!\n");
return Eptr;
}
/************************************************************/
/* 函数名 assignstatement */
/* 功 能 该函数处理赋值语句分析 */
/* 说 明 赋值语句的语义分析的重点是检查赋值号两端分量的类 */
/* 型相容性。 */
/************************************************************/
void Canalyze::assignstatement(TreeNode * t)
{
SymbTable * entry = NULL;
int present = FALSE;
TypeIR * ptr = NULL;
TypeIR * Eptr = NULL;
TreeNode * child1 = NULL;
TreeNode * child2 = NULL;
child1 = t->child[0];
child2 = t->child[1];
if(child1->child[0]==NULL)
{
/*在符号表中查找此标识符*/
present = FindEntry(child1->name[0],&entry);
if(present!=FALSE)
{ /*id不是变量*/
if (FindAttr(entry).kind!=varKind)
{
ErrorPrompt(child1->lineno,child1->name[0],"is not variable error!\n");
Eptr = NULL;
}
else
{
Eptr = entry->attrIR.idtype;
child1->table[0] = entry;
}
}
else /*标识符无声明*/
ErrorPrompt(child1->lineno,child1->name[0],"is not declarations!\n");
}
else/*Var0[E]的情形*/
{ if(child1->attr.ExpAttr.varkind==ArrayMembV)
Eptr = arrayVar(child1);
else /*Var0.id的情形*/
if(child1->attr.ExpAttr.varkind==FieldMembV)
Eptr = recordVar(child1);
}
if(Eptr != NULL)
{
if((t->nodekind==StmtK)&&(t->kind.stmt==AssignK))
{
/*检查是不是赋值号两侧 类型等价*/
ptr = Expr(child2,NULL);
if (!Compat(ptr,Eptr))
ErrorPrompt(t->lineno,"","ass_expression error!\n");
}
/*赋值语句中不能出现函数调用*/
}
}
/************************************************************/
/* 函数名 callstatement */
/* 功 能 该函数处理函数调用语句分析 */
/* 说 明 函数调用语句的语义分析首先检查符号表求出其属性中 */
/* 的Param部分(形参符号表项地址表),并用它检查形参*/
/* 和实参之间的对应关系是否正确。 */
/************************************************************/
void Canalyze::callstatement(TreeNode * t)
{
AccessKind Ekind;
int present = FALSE;
SymbTable * entry=NULL;
TreeNode * p = NULL;
/*用id检查整个符号表*/
present = FindEntry(t->child[0]->name[0],&entry);
t->child[0]->table[0] = entry;
/*未查到表示函数无声明*/
if (present==FALSE)
{
ErrorPrompt(t->lineno,t->child[0]->name[0],"function is not declarationed!\n");
}
else
/*id不是函数名*/
if (FindAttr(entry).kind!=procKind)
ErrorPrompt(t->lineno,t->name[0],"is not function name!\n");
else/*形实参匹配*/
{
p = t->child[1];
/*paramP指向形参符号表的表头*/
ParamTable * paramP = FindAttr(entry).More.ProcAttr.param;
while((p!=NULL)&&(paramP!=NULL))
{
SymbTable * paraEntry = paramP->entry;
TypeIR * Etp = Expr(p,&Ekind);/*实参*/
/*参数类别不匹配*/
if ((FindAttr(paraEntry).More.VarAttr.access==indir)&&(Ekind==dir))
ErrorPrompt(p->lineno,"","param kind is not match!\n");
else
/*参数类型不匹配*/
if((FindAttr(paraEntry).idtype)!=Etp)
ErrorPrompt(p->lineno,"","param type is not match!\n");
p = p->sibling;
paramP = paramP->next;
}
/*参数个数不匹配*/
if ((p!=NULL)||(paramP!=NULL))
ErrorPrompt(t->child[1]->lineno,"","param num is not match!\n");
}
}
/************************************************************/
/* 函数名 ifstatement */
/* 功 能 该函数处理条件语句分析 */
/* 说 明 分析语法树的三个儿子节点 */
/************************************************************/
void Canalyze::ifstatment(TreeNode * t )
{
AccessKind * Ekind = NULL;
TypeIR * Etp = Expr(t->child[0],Ekind);
if(Etp!=NULL)
/*处理条件表达式*/
if (Etp->kind!= boolTy)
ErrorPrompt(t->lineno,"","condition expressrion error!\n"); /*逻辑表达式错误*/
else
{
TreeNode * p = t->child[1];
/*处理then语句序列部分*/
while ( p!=NULL)
{
statement(p);
p=p->sibling;
}
t = t->child[2]; /*必有三儿子*/
/*处理else语句不分*/
while ( t!=NULL)
{
statement(t);
t=t->sibling;
}
}
}
/************************************************************/
/* 函数名 whilestatement */
/* 功 能 该函数处理循环语句分析 */
/* 说 明 分析语法树的两个儿子节点 */
/************************************************************/
void Canalyze::whilestatement(TreeNode * t)
{
TypeIR * Etp = Expr(t->child[0],NULL);
if (Etp!=NULL)
/*处理条件表达式部分*/
if (Etp->kind!= boolTy)
ErrorPrompt(t->lineno,"","condition expression error!\n"); /*逻辑表达式错误*/
else
{
t = t->child[1];
/*处理循环部分*/
while ( t!=NULL)
{
statement(t);
t=t->sibling;
}
}
}
/************************************************************/
/* 函数名 readstatement */
/* 功 能 该函数处理输入语句分析 */
/* 说 明 分析语法树节点,检查变量有无声明和是否为变量错误 */
/************************************************************/
void Canalyze::readstatement (TreeNode * t)
{
SymbTable * entry=NULL;
int present = FALSE;
/*用id检查整个符号表*/
present = FindEntry(t->name[0],&entry);
t->table[0] = entry;
/*未查到表示变量无声明*/
if (present==FALSE)
ErrorPrompt(t->lineno,t->name[0], " is not declarationed!\n");
else
/*不是变量标识符错误*/
if(entry->attrIR.kind!=varKind)
ErrorPrompt(t->lineno,t->name[0],"is not var name!\n ");
}
/************************************************************/
/* 函数名 writestatement */
/* 功 能 该函数处理输出语句分析 */
/* 说 明 分析输出语句中的表达式是否合法 */
/************************************************************/
void Canalyze::writestatement(TreeNode * t )
{
TypeIR * Etp = Expr (t->child[0],NULL);
if(Etp!=NULL)
/*如果表达式类型为bool类型,报错*/
if (Etp->kind==boolTy)
ErrorPrompt(t->lineno,"","exprssion type error!");
}
/************************************************************/
/* 函数名 returnstatement */
/* 功 能 该函数处理函数返回语句分析 */
/* 说 明 分析函数返回语句是否在主程序中出现 */
/************************************************************/
void Canalyze::returnstatement(TreeNode * t )
{
if(Level==0)
/*如果返回语句出现在主程序中,报错*/
ErrorPrompt(t->lineno,"","return statement error!");
}
/************************************************************/
/* 函数名 analyze */
/* 功 能 该函数处理总的语义分析 */
/* 说 明 对语法树进行分析 */
/************************************************************/
int Canalyze::analyze(TreeNode * t)
{
SymbTable * entry= NULL;
TreeNode * p = NULL;
TreeNode * pp = t;
/*创建符号表*/
CreatTable();
/*调用类型内部表示初始化函数*/
initialize();
/*语法树的声明节点*/
p=t->child[1];
while (p!=NULL)
{
switch ( p->nodekind )
{ case TypeK: TypeDecPart(p->child[0]); break ;
case VarK : VarDecPart(p->child[0]); break ;
case ProcDecK: procDecPart(p); break ;
default:
ErrorPrompt(p->lineno,"","no this node kind in syntax tree!");
break;
}
p = p->sibling ;/*循环处理*/
}
/*程序体*/
t = t->child[2];
if(t->nodekind==StmLK)
Body(t);
/*撤销符号表*/
if (Level!=-1)
DestroyTable();
return(StoreNoff);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -