📄 gongg.java
字号:
last.next = newItem;
}
}
/****************************************************/
/* 函数名 AppendUsExpr */
/* 功 能 将中间代码和相应的映象码写可用表达式表中 */
/* 说 明 */
/****************************************************/
void AppendUsExpr(CodeFile code,MirrorCode mirror)
{
UsableExpr last;
UsableExpr newItem = new UsableExpr();
newItem.code = code;
newItem.mirrorC = mirror;
if (usableExprT==null)
usableExprT = newItem;
else
{
last = usableExprT;
while (last.next!=null)
last = last.next;
last.next = newItem;
}
}
/****************************************************/
/* 函数名 FindECC */
/* 功 能 判断可用表达式表中是否有可用的表达式代码 */
/* 说 明 若有,返回用于替换的中间代码引用 */
/* 否则,返回为空 */
/****************************************************/
void FindECC(String codekind,int op1Code,int op2Code,CodeFile substiCode)
{
UsableExpr currentItem = usableExprT;
while ((currentItem!=null)&&(substiCode.codeR.arg3==null))
{ /*语句类别相同*/
if (currentItem.code.codeR.codekind == codekind)
/*对应分量编码都相同,可替换*/
if ((currentItem.mirrorC.op1==op1Code)&&(currentItem.mirrorC.op2==op2Code))
{
substiCode.codeR = currentItem.code.codeR;
substiCode.former = currentItem.code.former;
substiCode.next = currentItem.code.next;
}
else
{
/*可交换运算符,分量编码交叉相同,也可替换*/
if ((codekind.equals("ADD"))||(codekind.equals("MULT")))
if ((currentItem.mirrorC.op1==op2Code)&&(currentItem.mirrorC.op1==op2Code))
{
substiCode.codeR = currentItem.code.codeR;
substiCode.former = currentItem.code.former;
substiCode.next = currentItem.code.next;
}
}
currentItem = currentItem.next;
}
}
/****************************************************/
/* 函数名 GenMirror */
/* 功 能 构造映象码 */
/* 说 明 */
/****************************************************/
MirrorCode GenMirror(int op1,int op2,int result)
{
MirrorCode mirror = new MirrorCode();
mirror.op1 = op1;
mirror.op2 = op2;
mirror.result = result;
return mirror;
}
/****************************************************/
/* 函数名 SubstiVcode */
/* 功 能 将当前变量,及其值编码写入编码表 */
/* 说 明 若变量首次出现,则添加一项;否则,将表中 */
/* 此变量的值编码替换为新的值编码 */
/****************************************************/
void SubstiVcode(ArgRecord arg,int Vcode)
{
ValuNum Entry = new ValuNum();
SearchValuNum(arg,Entry);
/*若操作数首次出现,则填入编码表*/
if (Entry.access==null)
AppendValuNum(arg,Vcode);
else
{
/*间接临时变量*/
if (Entry.access.equals("indir"))
Entry.codeInfo.twoCode.valuecode = Vcode;
/*非间接临时变量*/
else
Entry.codeInfo.valueCode = Vcode;
}
}
/****************************************************/
/* 函数名 DelUsExpr */
/* 功 能 将可用表达式代码表中用到arg的值编码的项 */
/* 删除 */
/* 说 明 */
/****************************************************/
void DelUsExpr(ArgRecord arg)
{
boolean same = false;
UsableExpr Item = usableExprT;
UsableExpr former = Item;
while (Item!=null)
{ /*因为AADD用的是地址码,所以不考虑*/
if (!(Item.code.codeR.codekind.equals("AADD")))
{
if ((Item.code.codeR.arg1 == arg)||(Item.code.codeR.arg2 == arg)||(Item.code.codeR.arg3 == arg))
same = true;
if (same)
{ /*删除这个可用表达式项*/
if (Item == usableExprT)
{
usableExprT = Item.next;
former = usableExprT;
Item = usableExprT;
}
else
{
former.next = Item.next;
Item = former.next;
}
/*跳到下一次循环开始处*/
continue;
}
}
/*指针后移,比较下一个节点*/
former = Item;
Item = Item.next;
}
}
/********************************************************/
/* 函数名 DivBaseBlock */
/* 功 能 为中间代码划分基本块 */
/* 说 明 基本块从0开始编号,若有变参传递,则相应过程 */
/* 调用做为当前基本块的结束 */
/********************************************************/
int DivBaseBlock()
{
/*初始化基本块数目*/
int blocknum = 0;
CodeFile code = firstCode;
while (code!=null)
{
if ((code.codeR.codekind.equals("LABEL"))||(code.codeR.codekind.equals("WHILESTART"))||(code.codeR.codekind.equals("PENTRY"))||(code.codeR.codekind.equals("MENTRY")))
{
/*进入一个新的基本块*/
baseBlock[blocknum] =code;
blocknum++;
}
else if ((code.codeR.codekind.equals("JUMP"))||(code.codeR.codekind.equals("JUMP0"))||(code.codeR.codekind.equals("RETURNC"))||(code.codeR.codekind.equals("ENDPROC"))||(code.codeR.codekind.equals("ENDWHILE")))
{
/*从下一条语句开始,进入一个新的基本块*/
if (code.next!=null)
{
code = code.next;
baseBlock[blocknum] =code;
blocknum++;
}
}
else if (code.codeR.codekind.equals("VARACT"))
{
/*找到对应的过程调用语句,作为本基本块的结束*/
code = code.next;
while (!(code.codeR.codekind.equals("CALL")))
code = code.next;
/*从下一条语句开始,进入一个新的基本块*/
if (code.next!=null)
{
code = code.next;
baseBlock[blocknum] =code;
blocknum++;
}
}
code = code.next;
}
return blocknum;
}
}
/********************************************************************/
/* 类 名 AnalYuyi */
/* 功 能 总程序的处理 */
/* 说 明 建立一个类,处理总程序 */
/********************************************************************/
class AnalYuyi
{
/* SCOPESIZE为符号表scope栈的大小*/
int SCOPESIZE = 1000;
/*scope栈*/
SymbTable scope[]=new SymbTable[SCOPESIZE];
/*记录当前层数*/
int Level=-1;
/*记录当前偏移;*/
int Off;
/*记录主程序的displayOff*/
int mainOff;
/*记录当前层的displayOff*/
int savedOff;
/*注:域成员的偏移量从0开始。*/
int fieldOff = 0;
/*记录主程序display表的偏移量*/
int StoreNoff;
/*根据目标代码生成需要,initOff应为AR首地址sp到形参变量区的偏移7*/
int initOff=7;
/*分别指向整型,字符型,bool类型的内部表示*/
TypeIR intptr = new TypeIR();
TypeIR charptr = new TypeIR();
TypeIR boolptr = new TypeIR();
/*错误追踪标志*/
boolean Error=false;
boolean Error1=false;
String yerror;
String serror;
TreeNode yuyiTree;
AnalYuyi(String s)
{
Recursion r=new Recursion(s);
Error1=r.Error;
if (Error1)
serror=r.serror;
else
{
yuyiTree=r.yufaTree;
Analyze(yuyiTree);
}
}
/****************************************************/
/****************************************************/
/****************************************************/
/* 函数名 Analyze */
/* 功 能 语义分析主函数 */
/* 说 明 从语法树的根节点开始,进行语义分析 */
/****************************************************/
void Analyze(TreeNode t)
{
TreeNode p = null;
TreeNode pp = t;
/*建立一个新的符号表,开始语义分析*/
CreatSymbTable();
/*调用类型内部表示初始化函数*/
initiate();
/*语法树的声明节点*/
p=t.child[1];
while (p!=null)
{
if(p.nodekind.equals("TypeK") )
TypeDecPart(p.child[0]);
else if(p.nodekind.equals("VarK") )
VarDecPart(p.child[0]);
else if(p.nodekind.equals("ProcDecK") )
procDecPart(p);
else
AnalyzeError(t,"no this node kind in syntax tree!",null);
p = p.sibling ;/*循环处理*/
}
/*程序体*/
t = t.child[2];
if(t.nodekind.equals("StmLK"))
BodyA(t);
/*撤销符号表*/
if (Level!=-1)
DestroySymbTable();
/*输出语义错误*/
if(Error)
AnalyzeError(null," Analyze Error ",null);
}
/****************************************************/
/* 函数名 TypeDecPart */
/* 功 能 处理一个类型声明 */
/* 说 明 根据语法树中的类型声明节点,取相应内容, */
/* 将类型标识符添入符号表. */
/****************************************************/
void TypeDecPart(TreeNode t)
{
boolean present=false;
AttributeIR Attrib=new AttributeIR(); /*存储当前标识符的属性*/
SymbTable entry = new SymbTable();
Attrib.kind="typekind";
while (t!=null)
{
/*调用记录属性函数,返回是否重复声明错和入口地址*/
present = Enter(t.name[0],Attrib,entry);
if (present)
{
AnalyzeError(t," id repeat declaration ",t.name[0]);
entry = null;
}
else
entry.attrIR.idtype = TYPEA(t,t.kind);
t = t.sibling;
}
}
/****************************************************/
/* 函数名 TYPEA */
/* 功 能 建立类型的内部表示 */
/* 说 明 调用具体类型处理完成类型内部表示的构造 */
/* 返回指向类型内部表示的指针. */
/****************************************************/
TypeIR TYPEA(TreeNode t,String kind)
{
TypeIR typeptr=null;
/*根据不同类型信息,调用相应的类型处理函数*/
if (kind.equals("IdK"))
typeptr= NameTYPEA(t);
else if (kind.equals("IntegerK"))
typeptr= intptr;
else if (kind.equals("CharK"))
typeptr= charptr;
else if (kind.equals("ArrayK"))
typeptr= ArrayTYPEA(t);
else if (kind.equals("RecordK"))
typeptr= RecordTYPEA(t);
else
{
AnalyzeError(t,"bug: no this type in syntax tree ",null);
return null;
}
return typeptr;
}
/****************************************************/
/* 函数名 NameTYPEA */
/* 功 能 处理类型为类型标识符时的情形 */
/* 说 明 不构造新的类型,返回此类型标识符的类型, */
/* 并检查语义错误 */
/****************************************************/
TypeIR NameTYPEA(TreeNode t)
{
SymbTable Entry=new SymbTable();
TypeIR temp=null;
boolean present;
present= FindEntry(t.attr.type_name,Entry);
/*检查类型标识符未声明错*/
if (!present)
AnalyzeError(t," id use before declaration ",t.attr.type_name);
/*检查非类型标识符错*/
else if (!(Entry.attrIR.kind.equals("typekind")))
AnalyzeError(t," id is not type id ",t.attr.type_name);
/*返回标识符的类型的内部表示*/
else
{
temp= Entry.attrIR.idtype;
return temp;
}
return temp;
}
/****************************************************/
/* 函数名 ArrayTypeA */
/* 功 能 构造数组类型的内部表示 */
/* 说 明 处理下标类型,成员类型,计算数组大小, */
/* 并检查下标超界错误 */
/****************************************************/
TypeIR ArrayTYPEA(TreeNode t)
{
TypeIR tempforchild;
/*建立一个新的数组类型的内部表示*/
TypeIR typeptr=new TypeIR();
typeptr.array=new Array();
typeptr.kind="arrayTy";
/*下标类型是整数类型*/
typeptr.array.indexTy=intptr;
/*成员类型*/
tempforchild=TYPEA(t,t.attr.arrayAttr.childtype);
typeptr.array.elementTy=tempforchild;
/*检查数组下标出界错误*/
int up=t.attr.arrayAttr.up;
int low=t.attr.arrayAttr.low;
if (up < low)
AnalyzeError(t," array up smaller than under ",null);
else /*上下界计入数组类型内部表示中*/
{
typeptr.array.low = low;
typeptr.array.up = up;
}
/*计算数组的大小*/
typeptr.size= (up-low+1)*(tempforchild.size);
/*返回数组的内部表示*/
return typeptr;
}
/****************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -