编译器的设计

内容摘要
  对源文件进行词法分析,语法分析每需要一个单词时调用词法分析程序,分析当前单词,回送给语法分析程序同时产生相应的二元式文件和符号表。在此过程中,应用SLR(1)文法。同时设计3个和结果相关的栈,观察每一步操作所产生的结果,在进行语法分析时,也伴随着语义的分析,根据算数表达式和赋值语句的文法及相应的语义子程序,最后生成一个四元式文件,存放结果。
关键字
  SLR(1) 符号栈 状态栈 语义栈 词法、语法、语义分析

在这里插入图片描述

一、课程设计目的

  《编译原理》课程设计是编译原理课程必不可少的一个环节,通过课程设计,加深对编译原理的教学内容的了解,以及实现编译原理各部分知识的融合。进而提高学生分析问题、解决问题,从而运用所学知识解决实际问题的能力。

二、课程设计要求

1.明确课设任务,复习与查阅有关资料
2.按要求完成课设内容,课设报告要求文字和图工整、思路清楚、正确。
3.注意增强程序界面的友好性。凡用户输入时,给出足够的提示信息使用户感到方便使用。
4.注意提高程序的可读性和可理解性:程序中应有适当的注释,变量命名应符合实际含义,程序结构清晰,易于阅读和理解。

三、课程设计内容

1.题目

编译程序构造

2.内容
涉及词法分析、自下而上语法分析程序的实现:SLR(1)分析器的实现以及生成中间代码
3.具体要求

根据LR分析算法构造SLR(1)分析程序,并完成语法分析动作(当需要一个单词时,调用词法分析程序获取),同时完成语义分析生成四元式输出。要求程序具有通用性,改变文法时只需改变程序的数据初值,无需改变程序主体;
要求完成算数表达式和赋值语句的翻译,生成中间代码。
算数表达式和赋值语句的文法及相应的语义子程序。
( 1 ) A → i d = E p = l o o k u p ( i d . n a m e ) ; e m i t ( E . P A L C E , , p ) ; (1)A→id=E {p=lookup(id.name);emit(E.PALCE, , p);} (1)Aid=Ep=lookup(id.name);emitE.PALCE,,p;
( 2 ) E → E ( 1 ) + T E . P A L C E = n e w t e m p ( ) ; e m i t ( + , E ( 1 ) . P A L C E , T . P A L C E , E . P A L C E ) (2)E→E(1)+T {E.PALCE=newtemp(); emit(+,E(1).PALCE,T.PALCE,E.PALCE)} (2)EE(1)+TE.PALCE=newtemp();emit(+E(1).PALCET.PALCEE.PALCE)
( 3 ) E → T E . P A L C E = T . P A L C E ; (3)E→T {E.PALCE=T.PALCE;} (3)ETE.PALCE=T.PALCE;
( 4 ) T → T ( 1 ) ∗ F T . P A L C E = n e w t e m p ( ) ; e m i t ( + , T ( 1 ) . P A L C E , F . P A L C E , T . P A L C E ) (4)T→T(1)*F {T.PALCE=newtemp(); emit(+,T(1).PALCE,F.PALCE,T.PALCE)} (4)TT(1)FT.PALCE=newtemp();emit(+T(1).PALCEF.PALCET.PALCE)
( 5 ) T → F T . P A L C E = F . P A L C E ; (5)T→F {T.PALCE=F.PALCE;} (5)TFT.PALCE=F.PALCE;
( 6 ) F → ( E ) F . P A L C E = E . P A L C E ; (6)F→(E) { F.PALCE=E.PALCE;} (6)F(E)F.PALCE=E.PALCE;
( 7 ) F → i d P = L O O K U P ( i d . n a m e ) ; F . P A L C E = P ; (7)F→id {P=LOOKUP(id.name);F.PALCE=P;} (7)FidP=LOOKUP(id.name);F.PALCE=P;
构造其用于SLR(1)分析的识别活前缀的DFA以及action表和goto表。然后编程实现。

4.程序设计提示

(1)分析栈设计时可以用一个栈完成,也可以设计三个栈:一个符号栈,一个状态栈,一个语义栈,则归约时,则需要在符号栈中退掉n个符号,在状态栈中退掉n个符号(n为产生式符号个数),语义栈中退掉n个符号对应的语义;
(2)终结符表和非终结符表的组织和预测分析程序中相同(将符号对应到一个数字,表示在分析表中对应的下标)。
(3)action表中的错误处理:简化的错误处理:当查找action表出现空白时,则当前单词无法移进和规约,可简单的认为当前单词为多余的单词,则抛弃当前单词,读下一单词继续分析。

四、课程设计解决方案

在这里插入图片描述
主要程序图

在这里插入图片描述
语法分析+语义分析方法中关于三个栈设计的程序结构图:
在这里插入图片描述
程序流程图:
在这里插入图片描述

五、主要程序源代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.lang.String.*;
class AA  extends JFrame 
{   int a=0;
    int ii=-1;//状态栈的栈顶指针
    int e=1;//记录错误数
    int u=-1;//符号栈的栈顶指针
    int h=-1;//控制中间变量的数组下表;
    int y=-1;//语义栈的栈顶指针
    int weizhi=-1;//符号表中符号的总数;
    int i=0;//当把输入的表达式映射为数组,i为数组下标;
    int ll=0;//如果输入的字符是不可识别,ll=1;如果是可识别的ll=0;
    String s=" ";
    String kk="";
    String id;//记录识别出来的字符是标示符还是符号,值为i,或*,=,...;
    String iweizhi;//记录所识别出来的字在符号表里的位置。
    String pp="";//将符号表里的所有内容,全部取出付给pp,便于查询;
    String Eplace,Tplace,Fplace,Aplace;//记录E,T,F,A的实际值,可以为a,b,x,或中间变量;
    char lookhead;
    int state_stack[]=new int[ 40];//状态栈
	char symbol_stack[]=new char[40];//符号栈
	String grammer_stack[]=new String[100];//语义栈
	String name[]={"A","B","C","D","F","G","H","J","K","L","Q","T1","T2","T3","T4","T5","T6","T7","T8","T9","A1","A2","A3","A4","A5","A6"};//中间变量的值
	char N[] ={'+','*','i','=','(',')','#','E','F','T','A'};//这个文法所能识别出的符号,相当于slr表里的行坐标
    char grammer_right[][] ={{'i','=','E'} , {'E','+','T'}, {'T'}, {'T','*','F'}, {'F'}, {'(','E',')'},{'i'} };
    //每个产生式右边对应的符号
    String iii;
    JTextArea text1=new JTextArea();
    int fenxi[][] ={ {-1, -1, 2, -1,-1, -1, -1, -1, -1,-1,1}, { -1, -1, -1, -1, -1,-1,0, -1, -1, -1,-1 }, { -1, -1, -1, 3,-1, -1, -1, -1,-1,-1,-1}, { -1, -1, 12, -1, 9, -1, -1, 4,10,11, -1}, { 5, -1, -1, -1, -1 ,-1 ,101,-1,-1,-1,-1},{-1,-1,12,-1,9,-1,-1,-1,10,6,-1},{102,7,-1,-1,-1,102,102,-1,-1,-1,-1},{-1,-1,12,-1,9,-1,-1,-1,8,-1,-1},{104,104,-1,-1,-1,104,104,-1,-1,-1,-1},{-1,-1,12,-1,9,-1,-1,13,10,11,-1},{105,105,-1,-1,-1,105,105,-1,-1,-1,-1},{103,7,-1,-1,-1,103,103,-1,-1,-1,-1},{107,107,-1,-1,-1,107,107,-1,-1,-1,-1},{5,-1,-1,-1,-1,14,-1,-1,-1,-1,-1},{106,106,-1,-1,-1,106,106,-1,-1,-1,-1}};
//************************************
	AA(JTextArea a)
	{text1=a;}
//****************输出结构************
 int jianyan(char b)//寻找分析表的列坐标
		{
			    int k=N.length;
			    for (int j = 0; j < k; j++)
				{ 
				    if (b == N[j]) 
				    return j; 
				}
				return -2;			
        }
      void printz()//输出状态栈
        {
        	for(int p=0;p<=ii;p++)    
           { 
              String pp=state_stack[p]+" ";
              text1.append(pp);
           }               
      	}
      void	printf()//输出符号栈
      	{
      	  String h="  ";
      	  text1.append(h);
          for(int p=0;p<=u;p++)
		  {
		    String pp=symbol_stack[p]+" ";
		    text1.append(pp);
		  }
        }
      void printy()//输出语义栈
      {
      	String h="  ";
      	  text1.append(h);
      	for(int p=0;p<=u;p++)
      	{
      	String pp=grammer_stack[p]+" ";
        text1.append(pp);
      	}
      }
  void print_grammer_right(int pv,int bv)
      //输出每个产生式右边;
      {      	    	 
          for(int p=0;p<bv;p++)
		  {
		  	String pp=grammer_right[pv][p]+" ";
		  	text1.append(pp);
		  }
      }  
  void emit(String a,String b,String c,String d)
      //四元式 输出
      {
      	String dd="  四原式输出是:("+a+","+b+","+c+","+d+")";
      	text1.append(dd + '\n');
      }
//**************栈的结构**************
   void state_push(int a)
	{  
	 if(ii<39 )
	{ii++;state_stack[ii] = a;}
		
  	}
    void symbol_push(char a)
	{  
		if(u<39)
		{
		u++;symbol_stack[u] = a;	
	    }
	}    
   void grammer_push(char a) 
    	{  
		if(y<40)
		{
		y++;
		symbol_stack[y] = a;	
	    if(a=='i')	         grammer_stack[y]=chaxun(iweizhi);
      		 else if(a=='E')grammer_stack[y]=Eplace;
      		 else if(a=='F')grammer_stack[y]=Fplace;
      		 else if(a=='T')grammer_stack[y]=Tplace;
      		 else if(a=='A')grammer_stack[y]=Aplace;
      		 else grammer_stack[y]="_";     
		}	
       }
//***************出栈结构*************
	void state_pop(int zhan[])
	{  ii--; }
	char symbol_pop(char zhan[])
    { 
	  char p=symbol_stack[u];
	  symbol_stack[u]=' ' ;
	  u--; 
	  return p;
	}
	void grammer_pop(String zhan[])
	{ y--; }
//************************************
String chaxun(String iwei)//输入标识符的在符号表里边的位置,找到相应的符号;
  {
  	
     StringTokenizer fenxi1=new StringTokenizer(pp); 
     String token="";
     while(fenxi1.hasMoreTokens())
       { 
         String xx=fenxi1.nextToken();
         if( xx.compareTo(iwei)==0) 
         {  token=fenxi1.nextToken();}
       }             
     return token;//返回标识符的真值,比如a,b,c;
  	 } 
//***********进行规约的函数**********
void guiyue(int m) 
   {
   	String a="",b="",c="",d="";//四元式输出所需要 的参数 T1;
   	int k=m-10 ;//k为规约到哪一状态
   	int j=0;//j为产生式右边字符的个数
   	int jj=0;//jj为产生式左边字符的个数
   	char q='*';//q为产生式左边的字符  	 
   	switch(k)
   	//看规约到哪个产生式,j为产生式右边字符的个数;jj为产生式左边;q为产生式左边的字符;进行四元式值得初始化;
   	{
   		case 1:
   		      jj=0;j=3;q='A';a="=";
   		      b=grammer_stack[u];c="";
   		      d=grammer_stack[u-2];
   		      Aplace=Eplace;break;
   		case 2:
   		      jj=1;j=3;q='E';
   		      if(h==name.length)h=0;
   		      else h++; 
   		      //取中间变量,当数组中的中间变量都用完时循环取用;   		                       a="+";b=grammer_stack[y-2];
   		      c=grammer_stack[y];
   	Eplace=name[h];d=Eplace; break;
   		case 3:
   		      jj=2;j=1;q='E';
   		      Eplace=grammer_stack[u];break;
   		case 4:
   		      jj=3;j=3;q='T';
   		      if(h==name.length)h=0;
   		      else h++;a="*";
   		      b=grammer_stack[y-2];
   		      c=grammer_stack[y];
   		      Tplace=name[h];
   		      d=Tplace;break;
   		case 5:
   		      jj=4;j=1;q='T';
   		      Tplace=Fplace;break;
   		case 6:
   		      jj=5;j=3;q='F';
   		      Fplace=Eplace;break;
   		case 7:
   		      jj=6;j=1;q='F';
   		      Fplace=grammer_stack[y];break;
   	}   	
        String ppp="       用"+q+"-->";
        text1.append(ppp);
        //写到文本中
        print_grammer_right(jj,j);
        //打印字符串右边的部分;
   		for(int p1=0;p1<j;p1++)
   		//将规约好的产生式出栈,对应的语义,状态分别出栈
   		{
   	char kk=symbol_pop(symbol_stack);
   		 grammer_pop(grammer_stack);
   		 state_pop(state_stack);
   		}
   	     ppp="进行归约";
   	     text1.append(ppp);
   	     symbol_push(q);
   	     //将规约式左边的符号入符号栈;
   	     grammer_push(q);
   	     //入语义栈
   	     int l=jianyan(q);
   	     //调用函数,查询slr表对应的列坐标
   	     int g=state_stack[ii];
   	     //取出状态栈的栈顶元素
   	     int ru=fenxi[g][l];
   	     //查询slr表找出所对应的状态,
   	     pp="且将状态"+ru+"入栈";text1.append(pp);
   	     state_push(ru);
   	     //蒋新状态入栈;    
   	     if(a!="")
   	     //如果需要四元式输出的话,将其输出;
   	     emit(a,b,c,d);
   	     else text1.append( " "+'\n'); 	      	   
   	  }
  //***********输出函数**************
   void Output(String a,FileWriter out)//向文件里写东西;
   { 
     try{  out.append(a+"\n");   } 
     catch(IOException e)
       {  System.out.println(e);  }
  }
//************************************
void error(FileWriter file,int t,String d)
{
   	String ss= " 第"+t+"    出错"+d+"是多余的";
   	text1.append(ss+'\n');
   	Output(ss,file);   	
}
//**********词法分析函数**************
//**********建字符表整数表************
   String jianbiao(String s,String bj,FileWriter file,FileWriter file1)
   //查询符号表看新识别出的标示符是不使已经存在;
   {  
     int n=0;
     //如果已存在n为1;如果不存在为零;
     int vvv=-1;//
     String token=" ";
       //用来记录所识别处的标示符
     String v="";
     StringTokenizer fenxi=new StringTokenizer(s); 
     while(fenxi.hasMoreTokens())
       //循环查询看是否有存在;
            { 
             vvv++;
             String xx=fenxi.nextToken(); 
             if( xx.compareTo(bj)==0) 
             {
            	n++;
            	String p=String.valueOf( (vvv-1)/2);
//计算此标识符在符号表里的位置
iweizhi=p;
//将位置赋值给全变量iweizhi; 
token="(i,"+p+") ";
Output(token ,file);
//调用函数写入二元式表
break;
}
}
if(n==0)
//如果在符号表里不存在
{
   weizhi++;
//符号表共有的符号数加一;
   v=weizhi+" "+bj+" ";
   pp=pp+v;
//将记录符号的字符串更新;
   s=s+v;
   Output(v ,file1);
//调用函数将新的符号写入符号表
   token="(i,"+weizhi+") "; 
   iweizhi=""+weizhi;       
   Output(token ,file);
//将符号写入二元式表
}
id="i";
//给全局变量id 赋值,以便语法分析器对其进行分析;
return s;    
   }  
//**********识别标识符函数************
    int Isalpha(char ch[],FileWriter file,FileWriter file1,int f,int t,FileWriter file2)
   {  
     String biaoliu=" int 1 char 2 float 3 void 4 const 5 for 6 if 7 else 8 then 9 while 10 switch 11 break 12 begin 13 end 14  ";
     StringTokenizer fenxi=new StringTokenizer(biaoliu); 
     int i=f,tt=0;String token="";    
  for(int j=f;j<ch.length;j++)     {     
   if(((int)ch[j]>47&&(int)ch[j]<58)||((int)ch[j]>64&&(int)ch[j]<123))
//用ASC值判断输入的是不是字母或数字
{ 
  token=token+ch[j];
   i++;
}//i加一表明当前的符号串由两个字符或多个字符组成
            else break;
         }  
         while(fenxi.hasMoreTokens())
//查看此字符串是不是保留字
{ 
  String xx=fenxi.nextToken();
  if( xx.compareTo(token)==0)
{      
token="("+token+","+fenxi.nextToken()+") ";
tt=1;
}                
 }     
if(tt==0)
 //如果不是的话,调用函数进行写入
 { 
     kk=this.jianbiao(kk,token,file,file1);
     token="(i,"+weizhi+") ";
 }      
return i;
}
//*********特殊字符识别函数 + * *******
int Isother(char ch[],FileWriter file,int i,int t,FileWriter file1)
  {
     int p=0;
     String a="+ 19  *  21  ( 24 )  = rlop  # 44";
     StringTokenizer fenxi1=new StringTokenizer(a);     
     String token="";
//如果输入的字符是可以识别的标示符时,     
for(int f=i;f<ch.length;f++)
{ 
  token="";token=token+ch[i];         
  while(fenxi1.hasMoreTokens())
  { String xx=fenxi1.nextToken();               if( xx.compareTo(token)==0) 
               {  id=token;token="("+token+",) "; 
   p=1;
   i++;
} 
   f++; 
}
}  
if(p==0)  
{
  token="";
  ll++;
String n="第" + t+"行  "+ch[i] +"无法识别的特殊符号           ";
Output(n,file1);
e++;
i++;  }
//如果是不可识别的 写入错误表,错误个数加一;
     this.Output( token,file);
     return i;
 }
 //*********词法分析总函数******
 void Initscanner(char ch[],FileWriter out,FileWriter ouf,FileWriter ouc,int t)
   {   
     int n=0;int p=0;int g=0;int hh=0;int x=0;
if(i<ch.length)
  { 
               if(((int)ch[i]>64)&&((int)ch[i]<123))
{ 
 i= this.Isalpha(ch,out,ouf,i,t,ouc);
}
//调用的是符号判别函数
else 
{ i= this.Isother(ch,out,i,t,ouc);}
//调用特殊字符判别函数
}                              
}
//************************************
void fenxi(String s)//分析总过程
{  
	int t=0;
File file = new File(s);
//要分析的文件名称
try
{
String ys="danciliubiao.doc ";
//三个 输出表,二元式输出,符号表输出,错误输出
String fh="symbol_stackbiao.doc";
String cw="错误分析表.doc";
File  yu=new File(ys);
File yu1=new File(fh);
File yu2=new File(cw);
int  d=0;
FileWriter out=new FileWriter(yu);
FileWriter ouf=new FileWriter(yu1);
FileWriter ouc=new FileWriter(yu2);
FileReader in = new FileReader(file);
BufferedReader in2 = new BufferedReader(in);
String str = "";
while ((str = in2.readLine()) != null)
//逐行进行分析
{  t++;
StringTokenizer fenxi1 = new StringTokenizer(str);
while (fenxi1.hasMoreTokens())
//每一行中逐词进行分析
{  String BB="---------------------------语法分析过程----------------------------";
text1.append( BB+ '\n');
ii=-1;u=-1;y=-1;i=0;
//每分析一个表达式各个变量重新初始化;ii为状态栈栈顶指针,u符号栈,y语义栈
state_push(0); 
symbol_push('#'); 
grammer_push('#');
//开始将开始符号入栈
String  ss = fenxi1.nextToken(); 
ss=ss+'#';
//给表达式加结束符
char x='0';int f=0;
String SS="状态栈    符号栈    语义栈   动作说明";
text1.append(SS+ '\n');
char zxl[]=ss.toCharArray();
lookhead=zxl[0];
int p=zxl.length;
Initscanner(zxl,out,ouf,ouc,t);
//进行词法分析,out
//二元式文件,符号文件,错误输出文件	       
do
	{
		if(ll==0)
//当单词是可以识别时,进行循环语法分析
	{
		if(f<p&&ii>=0)
//f是已经识别的字符个数,p为表达式的总个数;当ii>0即符号栈不为空时;		   
{
		printz();
//将三个栈打印输出
		printf();
		printy();	
		int g=-1;
		char aaa[]=id.toCharArray();
//将词法分析识别出的单词i,或+,*。(,)..赋值给数组
lookhead=aaa[0];
//取第一个元素赋值给lookhead调用查询函数得到slr表的列坐标
 int m=jianyan(lookhead);
 int k=state_stack[ii];
//取状态栈的栈顶元素;		                    if(k<15&&m<11)
//一共有十五个状态,十一个列元素,当不越界时
{		                        g=fenxi[k][m]; 
		                        if(g<100&&g>0&&ll==0)
//进行移进动作
{		                      state_push(g);symbol_push(lookhead);		                      grammer_push(lookhead);
//分别入栈
f++;
Initscanner(zxl,out,ouf,ouc,t);
//重新调用词法分析,识别下一个字符
SS="       状态"+g+"进栈";
text1.append(SS + '\n');
}
else if(g>100&&ll==0)
	{guiyue(g);}
//规约,ll=0,可以分析
else 
if(g==0&&ll==0)
//当分析成功时:
{ 
SS="分析成功";text1.append(SS + '\n');
x='#';
}
else 
{		                
if(lookhead=='#')
	{
  state_pop(state_stack);
symbol_pop(symbol_stack);
  grammer_pop(grammer_stack);
	}
//当输入字符串是a=a+b+#时,将最后一字符调过,返回去分析前面的		                   
else//当在中间出错时,直接调过,不回调分析
{  f++;
Initscanner(zxl,out,ouf,ouc,t);
//调用词法分析分析下个单词
}
error(ouc,t,id);	  
 }
   }
}
else
//识别a+n#这种情况;
{
	SS="分析 不成功,表达式错误";
	text1.append(SS + '\n');
	break;
 }
}		                
else { //当不能识别的时候		                        
SS=zxl[i-1]+"单词不能识别,跳过";
text1.append(SS + '\n');
Initscanner(zxl,out,ouf,ouc,t);
ll=0;
 }
}while(x!='#');
//次表达式分析完毕		   		  
} 
}
out.close();
ouf.close();
ouc.close();
}
catch (IOException e)
	{	System.out.println(e);	}
}			 
}
class JieMian  extends JFrame  implements ActionListener
{	                                                    
  JButton bCompile=new JButton("编译");	
	JButton bOut1=new JButton("保存");
	JButton bOut2=new JButton("二元式输出");
	JButton bOut3=new JButton("错误处理");
	JButton bOut4=new JButton("符号表输出");
	JTextArea bText1=new JTextArea();
	JTextArea bText2=new JTextArea();
    JieMian(String s){	
	super(s);	
	bCompile.addActionListener(this);
	bOut1.addActionListener(this);
	bOut2.addActionListener(this);
	bOut3.addActionListener(this);
	bOut4.addActionListener(this); 
	
	Container pane=getContentPane();
    pane.add(new JScrollPane (bText2));
	pane.setLayout(null);
	bText1.setBounds(0,0,2000,40);
	pane.add(bText1);
	bText2.setBounds(0,50,2000,400);
	pane.add(bText2);
	bCompile.setBounds(50,500,150,40);
	pane.add(bCompile);
	bOut1.setBounds(250,500,150,40);
	pane.add(bOut1);
	bOut2.setBounds(450,500,150,40);
	pane.add(bOut2);
	bOut3.setBounds(650,500,150,40);
    pane.add(bOut3);
    bOut4.setBounds(850,500,150,40);
    pane.add(bOut4);    
	setVisible(true);
	setBounds(0,0,2000,2000);
	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    validate();      
 }  
  public void actionPerformed(ActionEvent e)
  {
  	if(e.getSource()==bOut1)
  	  {
  	  	File file = new File("hello.txt");
		try
		{         
    FileWriter out=new FileWriter(file);
	String ss=bText1.getText();
	out.write(ss);
	out.close();				 
		}
	catch (Exception ee)
		{	ee.printStackTrace();	}	
  	  }
 else 
  if(e.getSource()==bOut2)
  	 {
  	File file = new File("danciliubiao.doc");
	try
		{
			bText2.setText("");
			String s = null;
FileReader in = new FileReader(file);
BufferedReader intwo = new BufferedReader(in);
int n = 0;
if (e.getSource() == bOut2)
	{
		while ((s = intwo.readLine()) != null)
		{
	bText2.append(s + '\n');
		}
	in.close();
	intwo.close();
	}				 
}
catch (Exception ee)
	{  ee.printStackTrace();  }		
}  	   
else
  if(e.getSource()==bOut3)
  {
  File file = new File("错误分析表.doc");
	try
	{
		bText2.setText("");
		String s = null;
		FileReader in = new FileReader(file);
		BufferedReader intwo = new BufferedReader(in);
		int n = 0;
		if (e.getSource() == bOut3)
		{
		while ((s = intwo.readLine()) != null)
		{
bText2.append(s + '\n');
		}
		in.close();
		intwo.close();
		}				 
		}
		catch (Exception ee)
		{  ee.printStackTrace();  }  
  	    }
  	    else 
  	      if(e.getSource()==bCompile)
  	    {
  	     try{			  
			bText2.setText("");
		    AA a=new AA(bText2 );
		    a.fenxi("hello.txt");
		    }
	    catch (Exception ee)
		 {	ee.printStackTrace();  }
  	    }
  	    else
  	    {
File file = new File("符号表.doc");
try
  {
	bText2.setText("");
	String s = null;
	FileReader in = new FileReader(file);
BufferedReader intwo = new BufferedReader(in);
	int n = 0;
	if (e.getSource() == bOut4)
		{
	while ((s = intwo.readLine()) != null)
{  bText2.append(s + '\n'); }
in.close();
intwo.close();
		}				 
}
catch (Exception ee)
{	ee.printStackTrace();  }
}  }  
}  
class meng
{  public static void main(String args[])
{  JieMian j=new JieMian("语法分析"); }

**测试文档**

```c
a+b*(a+c)
b*a
**程序测试数据和结果:**

![在这里插入图片描述](https://img-blog.csdnimg.cn/dcf873d10b08401f8cc192b68e62779e.png)


**二元式输出、错误处理及符号表输出如下:**


![在这里插入图片描述](https://img-blog.csdnimg.cn/1a2d0188ca1243519c0d3240c5e5cc8e.png)



### 六、课设总结

&emsp;&emsp;在这次课程设计过程中,由于时间有限,对于词法分析方面采用的方法不是很容易扩展,在语法分析的过程中嵌套了语义分析的操作。本程序实现了对输入内容进行词法分析,产生二元式,符号表,再根据二元式及符号表进行语法和语义分析,生成四元式及输出动作过程的功能,实现此次课程设计的基本功能。
&emsp;&emsp;在编写程序的过程中,经过仔细分析我明白了分析表的构造和分析原理。本以为不是很难,但当我把写好的程序敲到电脑上并运行时才发现,在程序中我遇到了很多实际的小问题,比如程序中三个栈的输出问题,因为是三个栈分别定义的,所以经常会出现输出结果正确但位置不正确的问题。用数组模拟栈,又出现了比如数组越界,输出的分析过程移进或者规约滞后一个状态等问题,但经过和老师同学的交流,这些都一一解决。同时在此次编程的过程中,也让我学到了一些常用的小技巧。比如,用输出语句测试程序哪块出错。
&emsp;&emsp;和老师、同学的交流也使得我更深入的理解了课本上的有关知识。正向别人所说的,“实践出真知”,没有实践的过程,就不可能完全理解课本的知识。因此,在以后的学习过程中,要努力把理论和实践相结合来学习,这样自己的专业基础才会越来越扎实。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YoLo-8

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值