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

📄 语法分析ll1b.txt

📁 这是编译原理的源代码
💻 TXT
📖 第 1 页 / 共 3 页
字号:

/********************************************************************/
/* 函数名 gettoken				                    */
/* 功  能 从Token序列中取出一个Token	                            */				
/* 说  明 从文件中存的Token序列中依次取一个单词,作为当前单词.      */
/********************************************************************/
void CparseLL1::gettoken(TokenType *p)
{
	FILE *fp2;
   /*按只读方式打开文件*/
   fp2=fopen("Tokenlist","rb");
   if (fp2==NULL)   
   {		  AfxGetApp()->m_pMainWnd->MessageBox("不能打开token文件");
			  return;
	     }  
   fseek(fp2,fpnum*sizeof(TokenType),0);
   fread(p,sizeof(TokenType),1,fp2);
   fpnum++;
   fclose(fp2);
}


/********************************************************************/
/* 函数名 syntaxError												*/
/* 功  能 语法错误处理函数											*/
/* 说  明 将函数参数message指定的错误信息格式化写入列表文件listing	*/
/*		  设置错误追踪标志Error为TRUE								*/
/********************************************************************/
void CparseLL1::syntaxError(char * message)

{ fprintf(listing,"\n >> ");
  
  /* 将出错行号lineno和语法错误信息message格式化写入文件listing */
  fprintf(listing,"Syntax error at line %d: %s",lineno,message);

  /* 设置错误追踪标志Error为TRUE,防止错误进一步传递 */
  Error = TRUE;
}

void CparseLL1::process1()
{  
   Push(2, DOT);
   Push(1, ProgramBody);
   Push(1, DeclarePart);
   Push(1, ProgramHead);
    
}

/********************************************************************/
/* 函数名 CparseLL1::process2() 				     				*/
/* 功  能 处理程序头,并生成程序头节点Phead.                        */										
/* 说  明 产生式为:PROGRAM  ProgramName							*/
/********************************************************************/
void CparseLL1::process2()
{ 	
	Push(1,ProgramName);
    Push(2,PROGRAM);
	
	TreeNode  **t=PopPA();
	currentP=newPheadNode();  
    (*t)=currentP;
	/*程序头节点没有兄弟节点,下面的声明用用根节点的child[1]指向*/

}

void CparseLL1::process3()
{   
	Push(2,ID);
  
	strcpy( currentP->name[0] ,currentToken.Sem);
    currentP->idnum++;
}

void CparseLL1::process4()
{ 
	Push(1,ProcDec);
    Push(1,VarDec);
	Push(1,TypeDec);
}
void CparseLL1::process5()
{
}
void CparseLL1::process6()
{ 
    Push(1,TypeDeclaration);
   
}

void CparseLL1::process7()
{ 
	Push(1,TypeDecList);
    Push(2,TYPE);

	TreeNode  **t=PopPA();  
    currentP = newTypeNode();  /*生成Type作为标志的结点,它的子结点都是
    						     类型声明*/
   	(*t) = currentP;    /*头结点的兄弟结点指针指向此结点*/
	PushPA(&((*currentP).sibling));  /* 压入指向变量声明节点的指针*/
	PushPA(&((*currentP).child[0])); /*压入指向第一个类型声明节点的指针*/
}

void CparseLL1::process8()
{ 
	Push(1,TypeDecMore);
    Push(2,SEMI);
	Push(1,TypeName);
	Push(2,EQ);
	Push(1,TypeId);

	TreeNode  **t=PopPA();
    currentP = newDecNode(); /*生成一个表示类型声明的结点,
	                           不添任何信息*/

	(*t) = currentP; /*若是第一个,则是Type类型的子结点指向当前结点,
					   否则,是上一个类型声明的兄弟结点*/

    PushPA(&((*currentP).sibling)); 
}

void CparseLL1::process9()
{
	PopPA();
}

void CparseLL1::process10()
{  
   Push(1,TypeDecList);

}

void CparseLL1::process11()
{  
	Push(2,ID);
	
    strcpy( (*currentP).name[0] ,currentToken.Sem);
    currentP->idnum++;
}

void CparseLL1::process12()
{
	Push(1,BaseType);
	
	/*由于数组基类型的问题,这里不能直接用currentP->kind.dec=IntegerK;
	  而应该这么做,以适应所有情形*/
	temp=&(currentP->kind.dec);

}
void CparseLL1::process13()
{  
	Push(1,StructureType);
}

void CparseLL1::process14()
{ 
	Push(2,ID);

	/*声明的类型部分为类型标识符*/
    (*currentP).kind.dec=IdK;
    strcpy(currentP->attr.type_name ,currentToken.Sem);    
}

void CparseLL1::process15()
{
	Push(2,INTEGER);
	
	/*声明的类型部分为整数类型*/
    (*temp)=IntegerK;
}

void CparseLL1::process16()
{
	Push(2,CHAR1);

	/*声明的类型部分为子符类型*/
    (*temp) =CharK;
}
void CparseLL1::process17()
{  
	Push(1,ArrayType);
}
void CparseLL1::process18()
{ 
	Push(1,RecType);
}
void CparseLL1::process19()
{ 
   Push(1,BaseType);
   Push(2,OF);
   Push(2,RMIDPAREN);
   Push(1,Top);
   Push(2,UNDERANGE);
   Push(1,Low);
   Push(2,LMIDPAREN);
   Push(2,ARRAY);

   /*声明的类型为数组类型*/
   (*currentP).kind.dec=ArrayK;
   temp = &(currentP->attr.ArrayAttr.childtype);

}
void CparseLL1::process20()
{ 
	Push(2,INTC);
	
	/*存储数组的下届*/
	(*currentP).attr.ArrayAttr.low=atoi(currentToken.Sem);
}
void CparseLL1::process21()
{
	Push(2,INTC);
	
	/*存储数组的上届*/
	(*currentP).attr.ArrayAttr.up=atoi(currentToken.Sem);
}
void CparseLL1::process22()
{
   Push(2,END);
   Push(1,FieldDecList);
   Push(2,RECORD);
   
   /*声明的类型部分为记录类型*/
   (*currentP).kind.dec=RecordK;  

   saveP = currentP; /*压入当前节点,是为了处理完后回到当前节点,
				     主要是为了变量声明部分标识符部分在后面,考虑*/
   PushPA(&((*currentP).child[0]));
}
void CparseLL1::process23()
{
 	Push(1,FieldDecMore);
    Push(2,SEMI);
    Push(1,IdList);
    Push(1,BaseType);
	
	TreeNode  **t=PopPA();
    currentP = newDecNode(); /*生成记录类型的下一个域,不添任何信息*/
	temp=(&(currentP->kind.dec));
	(*t) = currentP; /*若是第一个,则是record类型的子结点指向当前结点,
                    	否则,是上一个纪录域声明的兄弟结点*/
	PushPA(&((*currentP).sibling)); 

}

void CparseLL1::process24()
{
    Push(1,FieldDecMore);
    Push(2,SEMI);
    Push(1,IdList);
    Push(1,ArrayType);
   
	TreeNode  **t=PopPA();
    currentP = newDecNode(); /*生成记录类型的下一个域,不添任何信息*/
	(*t) = currentP; /*若是第一个,则是record类型的子结点指向当前结点,
					   否则,是上一个纪录域声明的兄弟结点*/
	PushPA(&((*currentP).sibling)); 

}

void CparseLL1::process25()
{
    /*后面没有记录类型的下一个域了,恢复当前纪录类型节点的指针*/ 
	PopPA( );
	currentP = saveP; 
}

void CparseLL1::process26()
{ 
  	Push(1,FieldDecList);

}
void CparseLL1::process27()
{
	Push(1,IdMore);
    Push(2,ID);
	
	/*纪录一个域中各个变量的语义信息*/ 
	strcpy(currentP->name[currentP->idnum], currentToken.Sem);
    currentP->idnum++;
}
void CparseLL1::process28()
{
}

void CparseLL1::process29()
{
    Push(1,IdList);
    Push(2,COMMA);	
	
}
void CparseLL1::process30()
{ 
}

void CparseLL1::process31()
{  
  	Push(1,VarDeclaration);
    
}
void CparseLL1::process32()
{
   Push(1,VarDecList);
   Push(2,VAR);

   currentP=newVarNode();   /*生成一个标志变量声明的节点*/
   TreeNode **t=PopPA();
   (*t)=currentP;
   PushPA(&((*currentP).sibling));  /*压入指向函数声明的指针*/
   PushPA(&((*currentP).child[0])); /*压入指向第一个变量声明节点的指针*/ 
}
void CparseLL1::process33()
{
    Push(1,VarDecMore);
    Push(2,SEMI);
    Push(1,VarIdList);
    Push(1,TypeName);
	
	TreeNode  **t=PopPA();
	currentP = newDecNode();/*建立一个新的声明节点,这里表示变量声明*/
	(*t) = currentP;       /*若是第一个节点,则变量声明的头指针指向它,
					         否则它是前一个变量声明的后继*/
	PushPA(&((*currentP).sibling));

}
void CparseLL1::process34()
{
	PopPA( );
}

void CparseLL1::process35()
{ 
	Push(1,VarDecList);

}
void CparseLL1::process36()
{
   Push(1,VarIdMore);
   Push(2,ID);
   
   strcpy(currentP->name[currentP->idnum], currentToken.Sem);
   currentP->idnum++;

}
void CparseLL1::process37()
{ 
}

void CparseLL1::process38()
{
	Push(1,VarIdList);
    Push(2,COMMA);
	
}
void CparseLL1::process39()
{
}

void CparseLL1::process40()
{
	Push(1,ProcDeclaration);
  
}
void CparseLL1::process41()
{  
   Push(1,ProcDecMore);
   Push(1,ProcBody);
   Push(1,ProcDecPart);
   Push(2,SEMI);
   Push(2,RPAREN);
   Push(1,ParamList);
   Push(2,LPAREN);
   Push(1,ProcName);
   Push(2,PROCEDURE);

   
   currentP=newProcNode();
   TreeNode **t=PopPA();
   (*t)=currentP;
   
   PushPA(&(currentP->sibling));
   
   PushPA(&(currentP->child[2])); /*指向语句序列*/  

   PushPA(&(currentP->child[1]));  /*指向函数的声明部分*/
   
   PushPA(&(currentP->child[0]));  /*指向参数声明部分*/
}

void CparseLL1::process42()
{   /*弹出过程节点的兄弟节点指针*/
	//PopPA( );  /*为了统一处理,不能现在弹出*/
}

void CparseLL1::process43()
{ 
	Push(1,ProcDeclaration);
}

void CparseLL1::process44()
{
    Push(2,ID);
	
	strcpy( currentP->name[0] , currentToken.Sem );
	currentP->idnum++;
}

void CparseLL1::process45()
{   
	/*形参部分为空,弹出指向形参的指针*/
    PopPA();
}

void CparseLL1::process46()
{  
	Push(1,ParamDecList);
}
void CparseLL1::process47()
{  
	Push(1,ParamMore);
    Push(1,Param);
}
void CparseLL1::process48()
{  
	PopPA( );
}

void CparseLL1::process49()
{  
	Push(1,ParamDecList);
    Push(2,SEMI);

}
void CparseLL1::process50()
{
	Push(1,FormList);
    Push(1,TypeName);

	TreeNode **t=PopPA();
    currentP=newDecNode();
	/*函数的参数类型是值类型*/

⌨️ 快捷键说明

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