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

📄 plxcompiler.cpp

📁 一个PLX教学编译器IDE
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "plxCompiler.h"

/* 初始化初始值 */
const plus      = 0;              /*    +     */
const minus     = 1;              /*    -     */
const times     = 2;              /*    *     */
const slash     = 3;              /*    /     */
const lparen    = 4;              /*    (     */
const rparen    = 5;              /*    )     */
const eql       = 6;              /*    =     */
const comma     = 7;              /*    ,     */
const semicolon = 8;              /*    ;     */
const period    = 9;              /*    .     */
const lss       = 10;             /*    <     */
const gtr       = 11;             /*    >     */
const ident     = 12;             /*          */
const number    = 14;             /*          */
const becomes   = 15;             /*    :=    */
const geq       = 16;             /*    >=    */
const leq       = 17;             /*    <=    */
const neql      = 18;             /*    /=    */     
const odd       = 19;             /*    %     */
const ledge     = 101;            /*    [     */
const redge     = 102;            /*    ]     */

const progsym   = 20;
const intesym   = 21;
const logisym   = 22;
const constsym  = 23;
const ifsym     = 24;
const thensym   = 25;
const elsesym   = 26;
const whilesym  = 27;
const repeasym  = 28;
const beginsym  = 29;
const endsym    = 30;
const orsym     = 31;
const andsym    = 32;
const notsym    = 33;
const truesym   = 34;
const falsesym  = 35;
const dosym     = 36;
const untilsym  = 37;
const writesym  = 38;
const procsym   = 39;
const callsym   = 40;
const term      = 41;              /*  结束    */
const commentsym= 100;


plxCompiler::plxCompiler()
{
    cc = 0;
	ll = 0;
	tx = 0;                   /* 用0专门来做查询 */
	cx = 0;
    dx = 0;
    lev= 0;

	errornum  = 0;
	lineIndex = 0;
	codeIndex = 0;

	breakpoint = 0;

	strcpy(word[0]  ,"program");
    strcpy(word[1]  ,"integer");
    strcpy(word[2]  ,"logical");
    strcpy(word[3]  ,"const");
    strcpy(word[4]  ,"if");
    strcpy(word[5]  ,"then");
    strcpy(word[6]  ,"else");
    strcpy(word[7]  ,"while");
    strcpy(word[8]  ,"repeat");
    strcpy(word[9]  ,"begin");
    strcpy(word[10]  ,"end");
    strcpy(word[11] ,"or");
    strcpy(word[12] ,"and");
    strcpy(word[13] ,"not");
    strcpy(word[14] ,"true");
    strcpy(word[15] ,"false");
    strcpy(word[16] ,"do");
    strcpy(word[17] ,"until");
    strcpy(word[18] ,"write");
	strcpy(word[19] ,"procedure");
	strcpy(word[20] ,"call");

	wsym[0]  = progsym;
	wsym[1]  = intesym;
	wsym[2]  = logisym;
	wsym[3]  = constsym;
	wsym[4]  = ifsym;
	wsym[5]  = thensym;
	wsym[6]  = elsesym;
	wsym[7]  = whilesym;
	wsym[8]  = repeasym;
	wsym[9]  = beginsym;
	wsym[10] = endsym;
	wsym[11] = orsym;
	wsym[12] = andsym;
	wsym[13] = notsym;
	wsym[14] = truesym;
	wsym[15] = falsesym;
	wsym[16] = dosym;
	wsym[17] = untilsym;
	wsym[18] = writesym;
	wsym[19] = procsym;
	wsym[20] = callsym;

	for(int i=0;i<MAX_ANSICNUMBER;i++)
       ssym[i] = -1;

	ssym['+'] = plus;
	ssym['-'] = minus;
	ssym['%'] = odd;
	ssym['*'] = times;
	ssym['/'] = slash;
	ssym['('] = lparen;
	ssym[')'] = rparen;
	ssym['='] = eql;
	ssym[','] = comma;
	ssym[';'] = semicolon;
	ssym['.'] = period;
	ssym['<'] = lss;
	ssym['>'] = gtr;
	ssym['$'] = term;
	ssym['['] = ledge;
	ssym[']'] = redge;

	pOutputView = NULL;
	pDebugView  = NULL;
	pCodeView   = NULL;

	/********* 每一种可能出错的地方的follow  ******************/

	/* program的follow  */
	non_finis[0].num = 7;
    non_finis[0].followSym[0] = intesym;
    non_finis[0].followSym[1] = logisym;
    non_finis[0].followSym[2] = semicolon;
    non_finis[0].followSym[3] = constsym;
    non_finis[0].followSym[4] = procsym;
    non_finis[0].followSym[5] = term;
	non_finis[0].followSym[6] = beginsym;

	/* ds的follow      */
	non_finis[1].num = 4;  
    non_finis[1].followSym[0] = procsym;
    non_finis[1].followSym[1] = term;
	non_finis[1].followSym[2] = beginsym;
    non_finis[1].followSym[3] = semicolon;

	/* begin 和 ss 的follow  */
	non_finis[2].num = 8;  
    non_finis[2].followSym[0] = ident;
    non_finis[2].followSym[1] = term;
	non_finis[2].followSym[2] = ifsym;
    non_finis[2].followSym[3] = whilesym;
    non_finis[2].followSym[4] = repeasym;
	non_finis[2].followSym[5] = writesym;
    non_finis[2].followSym[6] = endsym;
	non_finis[2].followSym[7] = semicolon;

	/* ss的first       */
	non_finis[3].num = 5;  
    non_finis[3].followSym[0] = ident;
	non_finis[3].followSym[1] = ifsym;
    non_finis[3].followSym[2] = whilesym;
    non_finis[3].followSym[3] = repeasym;
	non_finis[3].followSym[4] = writesym;

	/* af 的first      */
	non_finis[4].num = 4;  
    non_finis[4].followSym[0] = ident;
	non_finis[4].followSym[1] = lparen;
    non_finis[4].followSym[2] = constsym;
    non_finis[4].followSym[3] = number;
}

plxCompiler::~plxCompiler()
{
}

/* 字符获取函数 */
void plxCompiler::getch()
{
    if( cc != ll)                 
    {
       ch = line[cc++];
	   return;

    }else
	{ 
	   if(InFile.eof())                      
	   {	  
	      ch = '$';
	      return;
	   }
	}

    cc = ll =0;

	lineIndex++;

    InFile.getline(line,MAX_LINECHAR);
    ll = strlen(line);
    line[ll++] = ' ';                   

    ch = line[cc++];
}

/* 词法获取函数 */
void plxCompiler::getsym()
{
     while(ch == ' ') getch();

	 /* 字符串识别 */
	 if(ch<='z'&&ch>='a')    
	 {
		 int i=0;

		 do{
			 if(i < MAX_INDENTFIERLEN-1)
			 {	
			    a[i++] = ch;			 
			 }else
			 {		 			   
				break;
			 }
			 getch();
		 }
		 while((ch<='z'&&ch>='a')||(ch<='9'&&ch>='0'));	

		 a[i] = '\0';
		 
		 strcpy(id,a); 
         sym = ident;                               

         for(i=0;i<MAX_KEYWORD;i++)
		 {
		    if(strcmp(id,word[i]) == 0)
			{
			   sym = wsym[i];
			}
		 }
	 }else 
	 {   
		 /* 数字识别 */
		 if(ch <= '9' && ch >= '0')
		 {
			 int i=0;
			 num = 0;
			 
			 do{
				 i++;
				 num = 10*num + ((int)ch - '0'); 
				 getch();
			 }
			 while(ch <= '9' && ch >= '0');
			 
			 if(i>MAX_NUMBERSIZE)
			 {
				 error("数字位数过长!");
			 }
			 
			 sym = number;
			 
		 }else
		 {
			 /* 赋值号识别 */
			 if(ch == ':')
			 {
				 getch();
				 
				 if(ch == '=')
				 {
					 getch();

					 sym = becomes;	 
				 }
				 else
				 {
				     error("赋值符号缺少 '=' 符号!");	 
				 }
			 }
			 else{
				 /* 小于号识别 */
				 if(ch == '<')
				 {
					 getch();
					 
					 if(ch == '=')
					 {
						 sym = leq; 
						 getch();
					 }
					 else
					 {
						 sym = lss;
					 }	 
				 }else 
				 {
					 /* 大于号识别 */
					 if(ch == '>')
					 {
						 getch();
						 
						 if(ch == '=')
						 {
							 getch();
							 sym = geq; 
						 }else
						 { 
							 sym = gtr;
						 }
					 }else
					 {	 						
						 if(ch == '/')
						 {
							getch();
						    
							/* C++注释处理 */
							if(ch == '/')
							{
								getch();
							
							    cc = ll;
                                sym = commentsym;
								
								getch();

								getsym();
                                 
								return;
							}else
							{
								/* C注释处理 */
							    if(ch == '*')
								{
								   getch();

								   while(true)
								   {
									   while(ch != '*')
									   {
									      getch();
										  
										  if(ch == '$')
										  {
										     sym = term;
									         error("缺少注释边界!");
										     
											 return;
										  }
									   }
									   
									   getch();
									   
									   if(ch == '/')
									   {
										   getch();
										   sym = commentsym;

										   getsym();

										   break;
									   }
								   }
								}
								/* 不等于处理 */
								else
								{
								    if(ch == '=')
									{
									   getch();
									   sym = neql;

									}else
									{
									   sym = slash;
									}
								}
							}
						 }else
						 {
							if(ch > 0)
							{
								sym = ssym[ch];
								
								//去除中文码问题
								if(sym == -1)
								{
									error("%s 使用不合法标识符",ch);
								}
								
								getch();
							}else
							{
							    error("unknown character '%x'",ch);
								getch();
							}
						 }
					 }
				 }		 
			 }
		 } 
	 }
}

/* 语法分析 */
void plxCompiler::enter(_kind indent, int value)
{
	ASSERT_VALID(pVariableView);

    if(position(id) != 0 )
	{
	    error("%s redefine.",id);

	}else
	{
		tx++;

		strcpy(table[tx].name , id);
        table[tx].kind  = indent;
         
	    switch(indent)
		{
		case varConst  : table[tx].val   = num; 			             					 
			             table[tx].ldex = pVariableView->AddText(table[tx].name,num);
						 break;
		case varInteger: table[tx].adr   = dx;
			             table[tx].level = lev;
						 table[tx].ldex  = pVariableView->AddText(table[tx].name,0);
                         dx++;
			             break;
		case varLogical: table[tx].adr   = dx;
			             table[tx].level = lev;
						 table[tx].ldex  = pVariableView->AddText(table[tx].name,0);
                         dx++;				
			             break;
		case varProc   : table[tx].level = lev; break;
		}
	}
}

/* 寻找标识符-为0表示失败 */
int plxCompiler::position(char *ident)
{
     strcpy(table[0].name,ident);
	 
	 int i = tx;	 
	 while(strcmp(table[i].name,ident) != 0) i--;	 
     return i;
}

/* 存储变量或者过程 */
void plxCompiler::vardeclaration(_kind varkind)
{
	if(sym == ident)
	{
	    enter(varkind);
	    getsym();

        if(sym == ledge)
		{
			getsym();

			if(sym == number)
			{
			    expandArray(num);
			    getsym();

				if(sym == redge)
				{
				    getsym();		
				}else
				{	
					error("缺少]");
				}
			}else
			{
			    error("缺少数字");
			}
		}
	}else
	{
	    error("unidentifiable definition.");
	}	
}

/* 开辟数组当然是比实际的要小一个,因为变量本身也是一个 */
void plxCompiler::expandArray(int len)
{
    dx += len - 1;
}
/* 常量定义函数 */
void plxCompiler::constdeclaration()
{
    if(sym == ident)
	{
	    getsym();

        if(sym == eql )
		{
		    getsym();

			if(sym == number)
			{
			    enter(varConst,num);
			    
				getsym();
			}
		}else
		{
		    if(sym == becomes)
			{
			   getsym();
			    
			   error("常量定义使用赋值号!");
			}else
			{
			   error("常量定义错误!");
			}
		}
	}else
	{
	    error("常量定义错误!");
	}
}

/* 主程序入口 */
void plxCompiler::Prog()
{
    if(sym == progsym)
	{
	   getsym();

	}else
	{
	   error("源文件缺少'program'入口.");

	   text(0);
	}
		
	block();
	
	if(sym == period)
	{
		getsym();
	}else
	{
		error("程序缺少结束符号!");
	}
}

/* block 非终结函数 */
void plxCompiler::block()
{
	dx      = 3;
    int tx0 = tx;

	/* 让每个table的入口 */
	table[tx0].adr = cx;         
	gen(JMP,0,0);

    ds();

	while(sym == procsym)
	{
	    getsym();
  
        if(sym == ident)
		{
			enter(varProc);

		    getsym();
  
			if(sym == semicolon)
			{
			   getsym();
			   
			   /* 保存当前层次和dx针 */
			   int oldlev = lev;
			   int olddx  = dx;

               lev ++;

			   block();

			   /* 恢复层次和数据针   */
               lev = oldlev;
			   dx  = olddx; 

			   if(sym == semicolon)
			   {
			       getsym();			   
			   }else
			   {
			       error("过程定义缺少结束分号!");
			   }
			}else
			{
			   error("过程定义缺少开始分号!");
			}
		}else
		{
		    error("不可识别的过程定义标识符!");
		}
	}
	
	code[table[tx0].adr].a = cx;   /* 回填,确定函数起始位置 */ 
	table[tx0].adr  = cx;
	gen(INT,0,dx);
    
	if(sym == beginsym)
	{
	   getsym();
	}else
	{
	   error("程序语句缺少'begin'关键字.");
	   text(2);
	}
	
	Satement();
	
	if(sym == endsym)
	{
		getsym();
		
		gen(OPR,0,0);
	}else
	{
		error("程序缺少'end'关键字.");
	}
	   
}

/* 主体语句 */
void plxCompiler::Satement()
{	
	ss();
	   
	while(sym == semicolon || textIn(3))
	{
		if(sym == semicolon)
		{
		   getsym();
		}else
		{
		   error("语句缺少';'号.");
		}

		ss();
	}	 	   
}

/* 定义变量的过程 */
void plxCompiler::ds()
{
    d();

	while(sym == semicolon)
	{		
	    getsym();	
	    d();	
	} 
}

/* 定义变量过程 */
void plxCompiler::d()
{	
	if(sym == intesym)
	{
		getsym();
		ddInt();
	}else
	{
		if(sym == logisym)
		{
			getsym();	
            ddBool();
		}else
		{
			if(sym == constsym)
			{
				getsym();
				ddConst();
			}else
			{
			}
		}		
	}	
}
/* did not finish the code which will realise the array. */
void plxCompiler::ddInt()
{  
	vardeclaration(varInteger);
		
	while(sym == comma)
	{
	    getsym();
		ddInt();
	}		
}

void plxCompiler::ddBool()
{  
	vardeclaration(varLogical);
		
	while(sym == comma)
	{
	    getsym();
		ddBool();
	}		
}

void plxCompiler::ddConst()
{  
	constdeclaration();
				
	while(sym == comma)
	{
		getsym();
		constdeclaration();
	}		
}

void plxCompiler::offset()
{  
    if(sym == ledge)
	{
	    getsym();
        ae();
		
		if(sym == redge)
		{
		    getsym();
		}else
		{
		    error("缺少右边界]!");
		}
	}else
	{
	    gen(LIT,1,0);	
	}
}
/* 语句过程 */
void plxCompiler::ss()
{
    if(sym == ident)
	{
        int index = position(id);
		
		if(index == 0)
		{
		    error("'%s' 不可识别的标识符!",id);
		    getsym();

			text(2);
		}else
		{
			int kind = table[index].kind;
			
			if(kind == varInteger)  
			{
				getsym();

				offset();
				
				if(sym == becomes || sym == eql)
				{				 
					if(sym == eql)
					{
						error("赋值语句不能使用 '=' 标识符!");					 
					}
					
					getsym();
					ae();
					gen(STO,lev-table[index].level,table[index].adr);
					
				}else
				{	
					error("左值使用出错!");
				}				
			}else if(kind == varLogical)
			{
				getsym();

				offset();
				
				if(sym == becomes || sym == eql)
				{				 
					if(sym == eql)
					{
						error("赋值语句不能使用 '=' 标识符!");					 
					}
					
					getsym();
					be();
					gen(STO,lev-table[index].level,table[index].adr);
					
				}else
				{	
					error("左值使用出错!");
				}
			}else
			{
				error("'%s' 为过程变量!");
			}
		} 		
	}else if(sym == ifsym)
	{
		getsym();

	    be();

		if(sym == thensym || textIn(3))
		{
			if(sym == thensym)
			{ 
				getsym();
			}else
			{
				error("'if' 语句缺少 'then'标识符!");
			}
			
			int cx1 = cx;
			gen(JPC,0,0);
			
			Satement();
			

⌨️ 快捷键说明

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