⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xunh.java

📁 一个java编译器
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        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 				    */
/* 功  能  处理一个变量声明或形参声明		    */
/* 说  明  处理一个声明节点中声明的所有标识符,	    */	
/*	   将相关信息添入符号表中,若是形参,还要   */
/*	   构造一个参数信息表,各个标识符在符号表的 */
/*	   位置存储在表中,返回参数表的表头指针     */					
/****************************************************/
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];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -