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

📄 byylscanner.java

📁 S语言编译器的完整实现
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    	case '[':
    	             currentToken.name.append(ch);
    		         currentToken.code=59;
    		         currentToken.address=-1;
    		         currentToken.label=labelCount++;
    		         outPut();
    		         ch=getNextChar();
    		         break;	         	     	         
    	case ']':
    	             currentToken.name.append(ch);
    		         currentToken.code=60;
    		         currentToken.address=-1;
    		         currentToken.label=labelCount++;
    		         outPut();
    		         ch=getNextChar();
    		         break;	    	         
    	case 10:     
    	        	 ch=getNextChar();
    	        	 break;
    	case 13:    
    	        	 ch=getNextChar();
    	        	 break;         	               
    	case ' ':	 ch=getNextChar();
    	        	 break;
    	case '	':   ch=getNextChar();  //Tab键
    	             break;        	   
    	case 1000:   error(4);   //结束
    	             break;
    	default:     
    	             error(1);
    	             ch=getNextChar(); 
    	             break;                    	                   	                 	                  		                
    	}
    }
 /**
  *输出和保存token串并填符号表
  */
public void outPut()
{   
   int flag=0,m,i;    //输出token字
   if(currentToken.code==3) //由于begin要匹配end;或end.不管哪种情况都匹配两次
        beginCode+=2; 
   if(currentToken.code==11)
        endCode++; 
   if(currentToken.code==47||currentToken.code==52) 
      if(endCode%2==1)
        endCode++;    //程序正常结束
  
   if(currentToken.address==-1) //保留字
         tokenTextArea.append(currentToken.label +" ( "+currentToken.code+","+"_  "+")"+"  "+currentToken.name+"\n");
      else     
         tokenTextArea.append(currentToken.label +" ( "+currentToken.code+","+currentToken.address+")"+" "+currentToken.name+"\n");
      //保存token串
      //tokenList[]从1开始 
       tokenList[tokenCount].label=currentToken.label;
       tokenList[tokenCount].address=currentToken.address;
       tokenList[tokenCount].code=currentToken.code;
       tokenList[tokenCount].name.append(currentToken.name.toString());
       tokenCount++;
       
      if((currentToken.code==35)||(currentToken.code==36))  
      {
      	flag=numberExist();
      	if(flag==-1)
      	{
      	   
      	   switch(currentToken.code)
      	  {
      		case 35:currentSymbol.type.append("整");
      		        currentSymbol.kind.append("常数");
      		        break;
      		case 36:currentSymbol.type.append("实");
      		        currentSymbol.kind.append("常数");
      		        break;
      	  }
      	  currentSymbol.name.start=0;
          currentSymbol.name.length=0;
      	  currentSymbol.addr=currentToken.address;
      	  currentSymbol.val.append(currentToken.name.toString());
      	  currentSymbol.sign.append(currentToken.name.toString());
      	  symbolTableTextArea.append(+currentSymbol.addr+"               "+currentSymbol.type+"    "+currentSymbol.kind+"     "+currentSymbol.val+"        "+currentSymbol.sign+"\n");
          symbolList[varCount].sign.append(currentSymbol.sign.toString());
          symbolList[varCount].name.start=currentSymbol.name.start;
          symbolList[varCount].name.length=currentSymbol.name.length;
          symbolList[varCount].type.append(currentSymbol.type.toString());
          symbolList[varCount].val.append(currentSymbol.val.toString());
          symbolList[varCount].kind.append(currentSymbol.kind.toString());
          symbolList[varCount].addr=currentSymbol.addr;       
          varCount++;	
      	}
      	
      } 
       //查填符号表和字母表
	  if((currentToken.code==34)||(currentToken.code==37))
	  {
	    flag=wordExist();
        if(flag==-1)  //字母表中没有
          {   
           currentSymbol.name.start=alphabet.length();
           currentSymbol.name.length=currentToken.name.length();
           currentSymbol.addr=currentToken.address;//入口地址
           currentSymbol.sign.append(currentToken.name.toString());
           alphabet.append(currentToken.name);
           symbolTableTextArea.append(+currentSymbol.addr+"      "+currentSymbol.name.start+"  "+currentSymbol.name.length+"     "+currentSymbol.type+"    "+currentSymbol.kind+"    "+currentSymbol.val+"                "+currentSymbol.sign+"\n");
           symbolList[varCount].sign.append(currentSymbol.sign.toString());
           symbolList[varCount].name.start=currentSymbol.name.start;
           symbolList[varCount].name.length=currentSymbol.name.length;
           symbolList[varCount].type.append(currentSymbol.type.toString());
           symbolList[varCount].val.append(currentSymbol.val.toString());
           symbolList[varCount].kind.append(currentSymbol.kind.toString());
           symbolList[varCount].addr=currentSymbol.addr;       
          
           varCount++;
         } 
     //clear the currentToken
     }
     currentToken.name.delete(0,currentToken.name.length());
     currentSymbol.sign.delete(0,currentSymbol.sign.length());
     currentSymbol.type.delete(0,currentSymbol.type.length());
     currentSymbol.val.delete(0,currentSymbol.val.length());
     currentSymbol.kind.delete(0,currentSymbol.kind.length());
     currentSymbol.name.start=0;
     currentSymbol.name.length=0;
 }  
 /**
  *检测数字是否在符号表中
  *@return 在符号表中就返回入口地址,不在就返回-1
  */
 public int numberExist()
 {
 	int flag=-1,i;
 	for(i=0;i<varCount;i++)
 	{
 		if((symbolList[i].name.start==0)&&(symbolList[i].name.length==0)&&(symbolList[i].val.toString().equals(currentToken.name.toString())))
 		 return i;
 	}
 	return flag;
 }
/**
 *检查标识符是否在字母表中 
 *@return 在符号表中就返回入口地址,不在就返回-1
 */
 public int wordExist()
 {
 	int flag=-1;
 	for(int i=0;i<varCount;i++)  //如果在符号表中则返回入口地址否则返回-1
 	{
 		if(currentToken.name.toString().equals(alphabet.substring(symbolList[i].name.start,symbolList[i].name.start+symbolList[i].name.length)))
 		flag=symbolList[i].addr;
 		}
 	return flag;
 } 
 /**
  *错误处理
  */ 	
public void error(int a)
{    errorCount++;
	switch(a)
	{  
	    case 0: resultTextArea.append("错误"+errorCount+"整数出错于"+rowCount+"行"+columnCount+"列"+"\n");break; 
		case 1: resultTextArea.append("错误"+errorCount+"非法字符于"+rowCount+"行"+columnCount+"列"+"\n");break;
		case 2: resultTextArea.append("错误"+errorCount+"实常数出错于"+rowCount+"行"+columnCount+"列"+"\n"); break;
		case 3: resultTextArea.append("错误"+errorCount+"没有匹配的注释符"+rowCount+"行"+columnCount+"列"+"\n"); break;
		case 4: resultTextArea.append("错误"+errorCount+"begin和end不匹配或程序非正常结束"+"\n"); break;
	    case 5: resultTextArea.append("错误"+errorCount+"未声明的字符出现于"+rowCount+"行"+columnCount+"列"+"\n");break;
	}
} 

/**
 *获得下一个token,将其保存在属性变量中
 */
public void getNextToken()
{
	if(tokenId<tokenCount)	
    {
      code=tokenList[tokenId].code;
      address=tokenList[tokenId].address;
      ID.delete(0,ID.length());
 	  ID.append(tokenList[tokenId].name.toString());
 	  tokenId++;	
    }
 else
    code=-1;
}
/**
 *分析说明语句之前是否正确,然后调用declare()进行说明语句的分析<br>
 *   调用beginAnalyse()进行其它语句的分析
 *@see #declare()
 *@see #beginAnalyse()
 */
public void parser()
{ 
   int a;
   if(errorCount>0)
   {
   	resultTextArea.append("\n无法进行语法/语义分析,请先改正词法分析时出现的错误\n");
   	return;
   }
   else
     analyseInit();
   //建立四元
   getNextToken();
   
   	if(code==21||code==22) //program or procedure
   	 {
   	 	
   	 	getNextToken();
   	 	if(code==34) //标志符
   	 	{
   	 	   getNextToken();
   	 		if(code==52)//分号
   	 		   {
   	 		   	getNextToken();
   	 		   	lineOfPro++;
   	 		   }
   	 		   else
   	 		    {anaError(3); return;} 
   	 		   if (code!=31)
   	 		    {anaError(4);return ;}
   	 		   else
   	 		     while((code==31))   //var
   	 		      {
   	 		       a=declare();
   	 		        if(a==-1)
   	 		         return ;	
   	 		       }
   	 		        //变量说明分析
   	 		if(code==3)
   	 		   {
   	 		   	if(beginAnalyse()==-1)
   	 		   	   return;
   	 		   	if((code!=47)&&(code!=52))
   	 		   	  anaError(29);
   	 		   }
   	 		 else
   	 		   anaError(8);
   	    }
   	 	else
   	 	  anaError(2);
   	 }
   	 else
   	   anaError(1);
      if(error_count==0)
      {
      	resultTextArea.setText("");
      	resultTextArea.append("语法/语义分析的结果:\n\n");
        resultTextArea.append("恭喜,已成功通过语法/语义分析");
      }
       
    
    lastresult();       
 }
 /**
  *初始化语法分析时用的变量和数组
  */
 public void analyseInit()
 {
 	int i;
 	pos=0;
 	tokenId=0;
    error_count=0;
    lineOfEqu=0;
    lineOfPro=1;
    address=0;
    tempCount=TEMPBOUNDARY;
    nowAddr=0;
    isFor=0;
   falseLine=trueLine=0;
   ID=new StringBuffer();
   expr=new stack[EXP_LEN];
   trueAddress=new int[EXP_LEN];
   falseAddress=new int[EXP_LEN];
   for(i=0;i<EXP_LEN;i++)
    {
   	  expr[i] =new stack();
   	  trueAddress[i]=0;
   	  falseAddress[i]=0;
    }
   Equ=new equ[EQU_LEN];
   for(i=0;i<EQU_LEN;i++)
   Equ[i]=new equ();
   trueAddress=new int[EXP_LEN];
   falseAddress=new int[EXP_LEN];
   initStack();
 }
 /**
  *分析说明语句并修改符号表
  *@return 说明语句是否出错的标志,0 未出错 -1 出错
  */
public int  declare()
{
	int a=1,i=0,j=0;
	int df;
	initStack();
	if(code==31) //var
	{
		getNextToken();
		if(code==3) //说明语句,不能出现begin
		{
			anaError(5);
			return -1;
		}
		while((code!=3)&&(code!=-1)&&(code!=31))//只分析一行 
		{
			push(); //标志符
			getNextToken();
		}
		while(pos>i)
		{
			if(expr[i].cod==34) //是标志符
			       i++;
			else
			{ anaError(6);return -1;}
			 
			 if(expr[i].cod==50)//冒号
			 {	
			    i++;
	            df=expr[i].cod;
	            switch(df)
	            {
	            	case 4:
	            	     for(j=0;j<=i-2;j++)
	            	       if(expr[j].addr!=-1)
	            	       {
	            	       	symbolList[expr[j].addr].type.append("布尔");
	            	        symbolList[expr[j].addr].kind.append("简变");
	            	       }	            	       
	            	       break;
	                case 7:
	                     for(j=0;j<=i-2;j++)
	            	       if(expr[j].addr!=-1)
	            	       {
	            	       	symbolList[expr[j].addr].type.append("字符");
	            	        symbolList[expr[j].addr].kind.append("简变");
	            	       }	                     
	                      break;	       
	            	case 16:
	            	    for(j=0;j<=i-2;j++)
	            	       if(expr[j].addr!=-1)
	            	       {
	            	       	symbolList[expr[j].addr].type.append("整");
	            	        symbolList[expr[j].addr].kind.append("简变");
	            	       }	                     
	                      break;	       
	            	       
	            	case 24:
	            	       for(j=0;j<=i-2;j++)
	            	       if(expr[j].addr!=-1)
	            	       {
	            	       	symbolList[expr[j].addr].type.append("实");
	            	        symbolList[expr[j].addr].kind.append("简变");
	            	       }	                     
	                      break;	       
	            	default:  anaError(6);return -1;     	         
	            }
	           	i++;
	           	if(expr[i].cod==52) //分号
	              {i++;lineOfPro++;}
	            else       //bool,char,integer,real后必须是分号 
	              {anaError(7);lineOfPro++; return -1;}
	            
			 }
			 else
			 {
			 if(expr[i].cod==44)
			    i++;     //逗点
			 else
			    {anaError(6); return -1;}
			 }
	 }
	}
	return 0;
}
/**
 *处理begin开始的各种语句,调用函数sentenceAnalize()
 *@return -1 表示出错<br>
 *      非 -1 表示语句生成的第一个四元式的序号
 *@see #sentenceAnalize()
 */
public int beginAnalyse()
{
  int rtn=0;
   getNextToken();
  if(code==52) 
     { anaError(9);return -1;}
  else
    {
    	lineOfPro++; //begin 与后面的语句差一行
     	
     	if(code==11)
     	  {anaError(10);return -1;}
     	  isChange=1; //简单赋值语句要修改符号表
     	  rtn=sentenceAnalize();
     	if(rtn==-1)   //语句出错,无法预测下一个token
     	    return rtn;   
        if(code!=11)  //end
         {
         	anaError(28);
       	    //lineOfPro++;
       	    return -1;
         }
        else
         {
       	  //lineOfPro++;
       	  getNextToken(); //符号.
         }
    }
     	
       
 	return rtn;      //四原式的序号
}
/**
 *匹配当前token,调用不同的程序进行分析
 *@return -1 表示出错<br>
 *      非 -1 表示语句生成的第一个四元式的序号
 *@see #startEvaluate()
 *@see #startIf()
 *@see #startWhile()
 *@see #startRepeat()
 *@see #startFor()
 */
public int sentenceAnalize()
{
	int rtn=0;
	switch(code)
	{
		case 34:
		        rtn=startEvaluate(); 
		        break;
		case 14:
		        rtn=startIf();
		        break;
		case 32:
		        rtn=startWhile(); 
		        break;
		case 25:
		        rtn=startRepeat();
		        break;
		case 13:
		        rtn=startFor();  
		        break;

⌨️ 快捷键说明

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