📄 analyuyi.java
字号:
/* 说 明 处理一个声明节点中声明的所有标识符, */
/* 将相关信息添入符号表中,若是形参,还要 */
/* 构造一个参数信息表,各个标识符在符号表的 */
/* 位置存储在表中,返回参数表的表头指针 */
/****************************************************/
void varDecList(TreeNode t)
{
boolean present = false;
SymbTable Entry=new SymbTable();
/*纪录变量的属性*/
AttributeIR Attrib=new AttributeIR();
while(t!=null) /*循环过程*/
{
Attrib.kind="varkind";
for(int i=0;i<(t.idnum);i++)
{
Attrib.idtype=TYPEA(t,t.kind);
/*判断识值参还是变参acess(dir,indir)*/
if((t.attr.procAttr!=null)&&(t.attr.procAttr.paramt.equals("varparamType")))
{
Attrib.var = new Var();
Attrib.var.access = "indir";
Attrib.var.level = Level;
/*计算形参的偏移*/
Attrib.var.off = Off;
Off = Off+1;
}/*如果是变参,则偏移加1*/
else
{
Attrib.var = new Var();
Attrib.var.access = "dir";
Attrib.var.level = Level;
/*计算值参的偏移*/
if(Attrib.idtype.size!=0)
{
Attrib.var.off = Off;
Off = Off + (Attrib.idtype.size);
}
}/*其他情况均为值参,偏移加变量类型的size*/
/*登记该变量的属性及名字,并返回其类型内部指针*/
present = Enter(t.name[i],Attrib,Entry);
if(present)
AnalyzeError(t," id repeat declaration ",t.name[0]);
else
t.table[i] = Entry;
}
if(t!=null)
t = t.sibling;
}
/*如果是主程序,则记录此时偏移,用于目标代码生成时的displayOff*/
if(Level==0)
{
mainOff = Off;
/*存储主程序AR的display表的偏移到全局变量*/
StoreNoff = Off;
}
/*如果不是主程序,则记录此时偏移,用于下面填写过程信息表的noff信息*/
else
savedOff = Off;
}
/****************************************************/
/* 函数名 procDecPart */
/* 功 能 一个过程声明的语义分析 */
/* 说 明 处理过程头,声明,过程体 */
/****************************************************/
void procDecPart(TreeNode t)
{
TreeNode p =t;
SymbTable entry = HeadProcess(t); /*处理过程头*/
t = t.child[1];
/*如果过程内部存在声明部分,则处理声明部分*/
while (t!=null)
{
if ( t.nodekind.equals("TypeK") )
TypeDecPart(t.child[0]);
else if ( t.nodekind.equals("VarK") )
VarDecPart(t.child[0]);
/*如果声明部分有函数声明,则跳出循环,先填写noff和moff等信息,*
*再处理函数声明的循环处理,否则无法保存noff和moff的值。 */
else if ( t.nodekind.equals("ProcDecK") ) {}
else
AnalyzeError(t,"no this node kind in syntax tree!",null);
if(t.nodekind.equals("ProcDecK"))
break;
else
t=t.sibling ;
}
entry.attrIR.proc.nOff = savedOff;
entry.attrIR.proc.mOff = entry.attrIR.proc.nOff + entry.attrIR.proc.level+1;
/*过程活动记录的长度等于nOff加上display表的长度*
*diplay表的长度等于过程所在层数加一 */
/*处理程序的声明部分*/
while(t!=null)
{
procDecPart(t);
t = t.sibling;
}
t = p;
BodyA(t.child[2]);/*处理Block*/
/*函数部分结束,删除进入形参时,新建立的符号表*/
if ( Level!=-1)
DestroySymbTable();/*结束当前scope*/
}
/****************************************************/
/* 函数名 HeadProcess */
/* 功 能 形参处理函数 */
/* 说 明 循环处理各个节点,并将处理每个节点得到 */
/* 的参数表连接起来,组成整个形参链表,返回 */
/* 这个表的指针 */
/****************************************************/
SymbTable HeadProcess(TreeNode t)
{
AttributeIR attrIr = new AttributeIR();
boolean present = false;
SymbTable entry = new SymbTable();
/*填属性*/
attrIr.kind = "prockind";
attrIr.idtype = null;
attrIr.proc = new Proc();
attrIr.proc.param = new ParamTable();
attrIr.proc.level = Level+1;
if(t!=null)
{
/*登记函数的符号表项*/
present = Enter(t.name[0],attrIr,entry);
t.table[0] = entry;
/*处理形参声明表*/
}
entry.attrIR.proc.param = ParaDecList(t);
return entry;
}
/****************************************************/
/* 函数名 ParaDecList */
/* 功 能 处理一个形参节点 */
/* 说 明 根据参数是形参还是变参,分别调用变量声明 */
/* 节点的处理函数,另一个实参是Add,表示处理*/
/* 的是函数的形参。 */
/****************************************************/
ParamTable ParaDecList(TreeNode t)
{
TreeNode p=null;
ParamTable Ptr1=null;
ParamTable Ptr2=null;
ParamTable head=null;
if(t!=null)
{
if(t.child[0]!=null)
p = t.child[0]; /*程序声明节点的第一个儿子节点*/
CreatSymbTable(); /*进入新的局部化区*/
Off = 7; /*子程序中的变量初始偏移设为8*/
VarDecPart(p); /*变量声明部分*/
SymbTable Ptr0 = scope[Level];
while(Ptr0 != null) /*只要不为空,就访问其兄弟节点*/
{
/*构造形参符号表,并使其连接至符号表的param项*/
Ptr2 = new ParamTable();
if(head == null)
{
head = Ptr2;
Ptr1 = Ptr2;
}
//Ptr0.attrIR.var.isParam = true;
copy(Ptr2.entry,Ptr0);
if(Ptr2 != Ptr1)
{
Ptr1.next = Ptr2;
Ptr1 = Ptr2;
}
Ptr0 = Ptr0.next;
}
}
return head; /*返回形参符号表的头指针*/
}
/****************************************************/
/* 函数名 BodyA */
/* 功 能 语句序列处理函数 */
/* 说 明 用于处理过程体或者程序体, */
/* 循环处理各个语句 */
/****************************************************/
void BodyA(TreeNode t)
{
/*令指针指向第一条语句*/
if (t.nodekind.equals("StmLK"))
t=t.child[0];
/*处理语句序列*/
while (t!=null)
{
/*调用语句处理函数*/
StatementA(t);
t= t.sibling;
}
}
/****************************************************/
/* 函数名 StatementA */
/* 功 能 语句处理函数 */
/* 说 明 根据语句的具体类型,分别调用相应的 */
/* 语句处理函数 */
/****************************************************/
void StatementA(TreeNode t)
{
if (t.kind.equals("AssignK"))
AssignSA(t);
else if (t.kind.equals("CallK"))
CallSA(t);
else if (t.kind.equals("ReadK"))
ReadSA(t);
else if (t.kind.equals("WriteK"))
WriteSA(t);
else if (t.kind.equals("IfK"))
IfSA(t);
else if (t.kind.equals("WhileK"))
WhileSA(t);
else if (t.kind.equals("ReturnK"))
ReturnSA(t);
else
AnalyzeError(t," bug:no this statement in syntax tree ",null);
}
/****************************************************/
/* 函数名 AssignSA */
/* 功 能 赋值语句处理函数 */
/* 说 明 检查左部标识符,调用表达式处理函数, */
/* 并检查标识符未声明错,非期望标识符错, */
/* 赋值不兼容错 */
/****************************************************/
void AssignSA(TreeNode t)
{
SymbTable entry = new SymbTable();
boolean present = false;
TypeIR ptr = null;
TypeIR Eptr = null;
TreeNode child1;
TreeNode child2;
child1 = t.child[0];
child2 = t.child[1];
if(child1.child[0]==null)
{
/*在符号表中查找此标识符*/
present = FindEntry(child1.name[0],entry);
if(present)
{ /*id不是变量*/
if (!(entry.attrIR.kind.equals("varkind")))
{
AnalyzeError(t," left and right is not compatible in assign ",null); Eptr = null;
}
else
{
Eptr = entry.attrIR.idtype;
child1.table[0] = entry;
}
}
else /*标识符无声明*/
AnalyzeError(t,"is not declarations!",child1.name[0]);
}
else/*Var0[E]的情形*/
{
if(child1.attr.expAttr.varkind.equals("ArrayMembV"))
Eptr = arrayVar(child1);
else /*Var0.id的情形*/
if(child1.attr.expAttr.varkind.equals("FieldMembV"))
Eptr = recordVar(child1);
}
if(Eptr != null)
{
if((t.nodekind.equals("StmtK"))&&(t.kind.equals("AssignK")))
{
/*检查是不是赋值号两侧 类型等价*/
ptr = Expr(child2,null);
if (!Compat(ptr,Eptr))
AnalyzeError(t,"ass_expression error!",child2.name[0]);
}
/*赋值语句中不能出现函数调用*/
}
}
/***********************************************************/
/* 函数名 Compat */
/* 功 能 判断类型是否相容 */
/* 说 明 由于TINY语言中只有整数类型、字符类型、数组类型和 */
/* 记录类型,故类型相容等于类型等价,只需判断每个结 */
/* 构类型的内部表示产生的指针值是否相同即可。 */
/***********************************************************/
boolean Compat(TypeIR tp1,TypeIR tp2)
{
boolean present;
if (tp1!=tp2)
present = false; /*类型不等*/
else
present = true; /*类型等价*/
return present;
}
/************************************************************/
/* 函数名 Expr */
/* 功 能 该函数处理表达式的分析 */
/* 说 明 表达式语义分析的重点是检查运算分量的类型相容性, */
/* 求表达式的类型。其中参数Ekind用来表示实参是变参 */
/* 还是值参。 */
/************************************************************/
TypeIR Expr(TreeNode t,String Ekind)
{
boolean present = false;
SymbTable entry = new SymbTable();
TypeIR Eptr0=null;
TypeIR Eptr1=null;
TypeIR Eptr = null;
if(t!=null)
{
if(t.kind.equals("ConstK"))
{
Eptr = intptr;
Eptr.kind = "intTy";
if(Ekind!=null)
Ekind = "dir"; /*直接变量*/
}
else if(t.kind.equals("VariK"))
{
/*Var = id的情形*/
if(t.child[0]==null)
{
/*在符号表中查找此标识符*/
present = FindEntry(t.name[0],entry);
t.table[0] = entry;
if(present)
{ /*id不是变量*/
if (!(entry.attrIR.kind.equals("varkind")))
{
AnalyzeError(t," syntax bug: no this kind of exp ",t.name[0]); Eptr = null;
}
else
{
Eptr = entry.attrIR.idtype;
if (Ekind!=null)
Ekind = "indir"; /*间接变量*/
}
}
else /*标识符无声明*/
AnalyzeError(t,"is not declarations!",t.name[0]);
}
else/*Var = Var0[E]的情形*/
{
if(t.attr.expAttr.varkind.equals("ArrayMembV"))
Eptr = arrayVar(t);
/*Var = Var0.id的情形*/
else if(t.attr.expAttr.varkind.equals("FieldMembV"))
Eptr = recordVar(t);
}
}
else if(t.kind.equals("OpK"))
{
/*递归调用儿子节点*/
Eptr0 = Expr(t.child[0],null);
if(Eptr0==null)
return null;
Eptr1 = Expr(t.child[1],null);
if(Eptr1==null)
return null;
/*类型判别*/
present = Compat(Eptr0,Eptr1);
if (present)
{
if((t.attr.expAttr.op.equals("LT"))||(t.attr.expAttr.op.equals("EQ")))
Eptr = boolptr;
else if((t.attr.expAttr.op.equals("PLUS"))||(t.attr.expAttr.op.equals("MINUS"))||(t.attr.expAttr.op.equals("TIMES"))||(t.attr.expAttr.op.equals("OVER")))
Eptr = intptr;
/*算数表达式*/
if(Ekind != null)
Ekind = "dir"; /*直接变量*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -