📄 analyuyi.java
字号:
package mycompiler.yuyi;
import java.util.*;
import java.io.*;
import java.awt.*;
/******************************************/
class SymbTable /* 在语义分析时用到 */
{
String idName;
AttributeIR attrIR=new AttributeIR();
SymbTable next=null;
}
class AttributeIR
{
TypeIR idtype=new TypeIR();
String kind;
Var var;
Proc proc;
}
class Var
{
String access;
int level;
int off;
boolean isParam;
}
class Proc
{
int level;
ParamTable param;
int mOff;
int nOff;
int procEntry;
int codeEntry;
}
class ParamTable
{
SymbTable entry=new SymbTable();
ParamTable next=null;
}
class TypeIR
{
int size;
String kind;
Array array;
FieldChain body;
}
class Array
{
TypeIR indexTy=new TypeIR();
TypeIR elementTy=new TypeIR();
int low;
int up;
}
class FieldChain
{
String id;
int off;
TypeIR unitType=new TypeIR();
FieldChain next=null;
}
/*******************************************/
class TreeNode /* 语法树结点的定义 */
{
TreeNode child[]=new TreeNode[3];
TreeNode sibling=null;
int lineno;
String nodekind;
String kind;
int idnum;
String name[]=new String[10];
SymbTable table[]=new SymbTable[10];
Attr attr=new Attr();
}
class Attr
{
ArrayAttr arrayAttr=null; /* 只用到其中一个,用到时再分配内存 */
ProcAttr procAttr=null;
ExpAttr expAttr=null;
String type_name=null;
}
class ArrayAttr
{
int low;
int up;
String childtype;
}
class ProcAttr
{
String paramt;
}
class ExpAttr
{
String op;
int val;
String varkind;
String type;
}
/************************************************/
class TokenType /****Token序列的定义*******/
{
int lineshow;
String Lex;
String Sem;
}
/********************************************************************/
/* 类 名 AnalYuyi */
/* 功 能 总程序的处理 */
/* 说 明 建立一个类,处理总程序 */
/********************************************************************/
public 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();
/*错误追踪标志*/
public boolean Error=false;
public boolean Error1=false;
public String ytable=" ";
public String yerror;
public String serror;
public TreeNode yuyiTree;
public 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;
}
/****************************************************/
/* 函数名 RecordTYPEA */
/* 功 能 构造记录类型的内部表示 */
/* 说 明 构造域表,指针存储在记录的内部表示中, */
/* 并计算记录的大小 */
/****************************************************/
TypeIR RecordTYPEA(TreeNode t)
{
TypeIR Ptr=new TypeIR(); /*新建记录类型的节点*/
Ptr.body=new FieldChain();
Ptr.kind="recordTy";
t = t.child[0]; /*从语法数的儿子节点读取域信息*/
FieldChain Ptr2=null;
FieldChain Ptr1=null;
FieldChain body=null;
while (t != null) /*循环处理*/
{
/*填写ptr2指向的内容节点*
*此处循环是处理此种情况int a,b; */
for(int i=0 ; i < t.idnum ; i++)
{
/*申请新的域类型单元结构Ptr2*/
Ptr2 = new FieldChain();
if(body == null)
{
body = Ptr2;
Ptr1 = Ptr2;
}
/*填写Ptr2的各个成员内容*/
Ptr2.id=t.name[i];
Ptr2.unitType = TYPEA(t,t.kind);
/*如果Ptr1!=Ptr2,那么将指针后移*/
if(Ptr2 != Ptr1)
{
/*计算新申请的单元off*/
Ptr2.off = (Ptr1.off) + (Ptr1.unitType.size);
Ptr1.next = Ptr2;
Ptr1 = Ptr2;
}
}
/*处理完同类型的变量后,取语法树的兄弟节点*/
t = t.sibling;
}
/*处理记录类型内部结构*/
/*取Ptr2的off为最后整个记录的size*/
Ptr.size = Ptr2.off + (Ptr2.unitType.size);
/*将域链链入记录类型的body部分*/
Fcopy(Ptr.body,body);
return Ptr;
}
/****************************************************/
/* 函数名 VarDecPart */
/* 功 能 变量声明序列分析函数 */
/* 说 明 处理所有的变量声明 */
/****************************************************/
void VarDecPart(TreeNode t)
{
varDecList(t);
}
/****************************************************/
/* 函数名 varDecList */
/* 功 能 处理一个变量声明或形参声明 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -