• 编译实践(词法/语法/语义)


    每次由不同组员编写 未整合故无关联
    in.txt

    program test (a,b);
    begin 
    	x:=19;
    	y:=x+5*6;
    	if x<y then y:=x
    	else begin
    		while x+y<x do y:=y+1; 
    		z:=z*7
    	end
    end.
    

    词法分析 _by GaHingZ

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<list>
    #include <math.h>
    #include <windows.h>
    #define BOOL int
    #define TRUE 1
    #define FALSE 0
    #define MAXSIZE 50
    #define MAXNUM 16777216
    #include<set>
    #include<string>
    #include<fstream>
    using namespace std;
    #define ERROR_SYN -1
    //#define KEY_SYN=1~6
    #define FINISH_SYN 0//#
    #define IDENTIFIER_SYN 10//标识符
    int lineIndex=1;
    int error_index=0;
    string sign_type[4]={"保留字",//for if ..
    "特殊符号",//+ ( / ..
    "常量",//num
    "标识符"//还应该细分 以及属性(address) 先不考虑
    };
    string error_info[4]={
    "标识符不能带有符号",
    "整数越界",
    "标识符长度大于32",
    "非法识别num"
    };
    list<string> type0,type1,type2,type3;
    list<string>::iterator finditer;
    char *object;
    typedef char datatype;
    typedef struct                              /*定义缓冲队列*/
    
    {
    
      datatype data[MAXSIZE*2];
    
      int front,rear;
    
    }Queue;
    
    void setnull(Queue *q)                      /*队列初始化*/
    
    {
    
      q->front = MAXSIZE*2 - 1;
    
      q->rear = MAXSIZE*2 - 1;
    
    }
    
    BOOL empty(Queue *q)                   /*判队空*/
    
    {
    
      if(q->front==q->rear)
    
           return TRUE;
    
      return FALSE;
    
    }
    
    BOOL full(Queue *q)                         /*判队满*/
    
    {
    
      if(q->front == (q->rear+1) % (MAXSIZE*2))
    
           return TRUE;
    
      return FALSE;
    
    }
    
    int quantity(Queue *q)                      /*求队列中元素个数*/
    
    {
    
      int n;
    
      n = q->rear - q->front;
    
        if(n<0)
    
           n += MAXSIZE*2;
    
      return n;
    
    }
    
    datatype front(Queue *q)               /*取队头元素*/
    
    {
    
      int n;
    
      if(empty(q))
    
           return 0;
    
      n = (q->front+1) % (MAXSIZE*2);
    
      return q->data[n];
    
    }
    
    BOOL enqueue(Queue *q,datatype x)      /*入队*/
    
    {
    
      if(full(q))
    
           return FALSE;
    
      q->rear = ++q->rear % (MAXSIZE*2);
    
      q->data[q->rear]=x;
    
      return TRUE;
    
    }
    
    datatype dequeue(Queue *q)                  /*出队*/
    
    {
    
      if(empty(q))
    
           return 0;
    
      q->front = ++q->front % (MAXSIZE*2);
    
      return q->data[q->front];
    
    }
    
    int lengtharray(char *a){
       return strlen(a);
    }
    
    
    char token[MAXSIZE];
    
    
    char* rwtab[6]={"begin","if","then","while","do","end"};//定义关键字
    
    
    int syn;//标识符数字
    
    
    Queue prog;
    
     
    
    BOOL letter(char &ch)                   /*判断是否字母*/
    
    {
    
    	if(ch>='a'&&ch<='z' ){
    		return TRUE;}
    	else if(ch>='A'&&ch<='Z'){
    		ch=ch+32;
    	return TRUE;
    	}//全部转换成小写
    
      return FALSE;
    
    }
    
    BOOL digit(char ch,char ch2)                         /*判断是否36进制开头*/
    
    {
    
      if(ch =='0'&& (ch2 =='X' || ch2 == 'x'))
    
           return TRUE;
    
      return FALSE;
    }
    BOOL digit1(char ch)                         /*判断是否10进制*/
    
    {
    
      if(ch >='0'&& ch<= '9')
    
           return TRUE;
    
      return FALSE;
    }
    BOOL symbol(char ch){
    	if((ch>=34&&ch<=36)||ch==39||ch==64||(ch>=44&&ch<46))return TRUE;
    	else return FALSE;
    }
    BOOL isPoint(char ch){
    	if(ch==46)return true;
    	else return false;
    }
    BOOL isBottomLine(char ch){
    	if(ch==95)return true;
    	else return false;
    }
    //判断整数字符
    BOOL digitagain(char ch){
         if ((ch >= '0' && ch <= '9')||(ch>='a'&&ch<='z' ) ||(ch>='A'&&ch<='Z'))return TRUE;
    	 return FALSE;
    	 
    }
    
    int translate(char c){
       int p;
       if(c>='0'&&c<='9')p=c-'0';
       if(c>='a'&&c<='z')p=c-'a'+10;
       if(c>='A'&&c<='Z')p=c-'A'+10;
       return p ;
    }
    BOOL explain(char ch,char ch2){
           
    	if(ch == '-' && ch2 == '-')
    		return TRUE;
    	return FALSE;
    	 
    }
    
    
    
    void scanner()                                /*扫描器*/
    
    {
    
      int i;
      int num,num1;
      char ch;
      char ch2;
    
      for(i=0;i<50;i++){
    
    	  token[i]=0;}
    
      i=0;
    
      do                                        /*去除多余空格、换行及制表符*/
    
      {
           ch=dequeue(&prog);
    	   if(ch=='
    '){
    		   lineIndex++;
    	   }
      }while(ch==' ' || ch=='
    ' || ch=='	');//读到不是空格、换行及制表符
     
      ch2 =  prog.data[prog.front+1];
     
     
      if(letter(ch))                            /*识别标识符(编号10)*/
    
      {
    	   int flag = 0;//
           while(1)
           {
               token[i++]=ch;
               ch=front(&prog);
               if(letter(ch) || digitagain(ch)||isBottomLine(ch))
                    dequeue(&prog);
               else if(symbol(ch)||isPoint(ch)){
    			   dequeue(&prog);
    				flag=1;//非法变量
    		   }
    		   else break;
           }
    	   if(flag!=0)
    	   {
    		   syn=ERROR_SYN;error_index=0; return;
    	   }
           //标识符长度大于32报错
    	   if(lengtharray(token)>32){syn=ERROR_SYN;error_index=2; return;}
    	   //标识符的有效长度为8
    	   if(lengtharray(token)>7)token[8]='';
           token[i]='';
           syn=10;
           for(i=0;i<6;i++)
               if(!strcmp(token,rwtab[i]))
                    syn=i+1;                    /*识别关键字(编号1到6)*/
      }
    
      else if(explain(ch,ch2)){                /*识别注释*/
           prog.front=prog.front+1;     //移动到--后面
    	   while(1){
    	     ch = front(&prog);
    		 if(ch!='
    ')dequeue(&prog);
    		 else {syn=-2;break;}    		
    	  }
      }
    
      else if(digit(ch,ch2))                   /*识别无符号整数(编号11)*/
      {
    	  prog.front=prog.front+1;       //移动到0X后面
          int flag=0;
           while(1)
           {
    		   ch=front(&prog);
    
    		   if(digitagain(ch)){
    
    			   dequeue(&prog);
    		   }
               else{            
    			   break;
    		   }  		  
    		   token[i++]=ch;
           }
           //转换成36进制数
    	   int j,k;
    	   k=0;num=0;
           for(j = i-1;j>=0;j--){	  
              num+=translate(token[j])*(int)pow(36,k);
    //		  printf("%d
    " ,translate(token[j]));
    			   k++;
    	   }
           if (num > MAXNUM){
    			token[0]='';
    			syn=ERROR_SYN;error_index=1;
    //		   printf("error
    ");
    		   //break;
    	   }
           else{
    	   //将十进制数输入到文本
    	   int num_1;
    	   num_1 = num;
    	   int q;
    	   for (q=1;;q++){
    	       num/=10;
    		   if (num==0) break;
    	   }
    	   int w,e;
    	   e=q-1;
    	   for (w=0;w<q;w++){
    		    token[w] = (num_1/((int)pow(10,e))) +48;
    			 num_1 %= ((int)pow(10,e));
                  e--;
    	   }	  
           token[e]='';
           syn=11;
    	   }
    
      }
      else if(digit1(ch)){
    	   int flag = 0;
    	   int k=0;
    	   BOOL havaPoint = FALSE;
           while(1)
           {
               token[i++]=ch;
               ch=front(&prog);	   
               if(digit1(ch))
    		   {
    			   k++;
    			   dequeue(&prog);
                    //nothing
    		   }
               else if(symbol(ch)||letter(ch)||isBottomLine(ch)){
    			   dequeue(&prog);
    				flag=1;//非法变量
    		   }
    		   else if(isPoint(ch)){
    			    dequeue(&prog);
    				havaPoint=TRUE;
    				break;
    		   }
    		   else break;
           }
    	   if(havaPoint==TRUE){
    		   while(1)
    		  {
    			   token[i++]=ch;
    			   ch=front(&prog);	   
    			   if(digit1(ch))
    			  {
    				   dequeue(&prog);
    			       //nothing
    			  }
    			  else if(symbol(ch)||letter(ch)||isBottomLine(ch)||isPoint(ch)){
    				   dequeue(&prog);
    					flag=1;//非法变量
    			  }
    			  else break;
    		   }
    		   if(flag==0)flag=2;
    	   }
    	   if(flag==1){
    	    syn=ERROR_SYN;error_index=3; return;
    	   }
    	   token[i]='';
    		 //转换成10进制数
    	   int j;
    	   num1=0;
    	   k--;
           for(j = 0;j<=i-1;j++){
    		   if(isPoint(token[j])){break;}
              num1+=translate(token[j])*(int)pow(10,k);
    			   k--;
    	    if (num1 > MAXNUM){
    			token[0]='';
    		   syn=ERROR_SYN;error_index=1;
    		   return;
    	   }
    	   }
    	   if(flag==2)syn=12;
    	   syn=11;
    	   
    
      }
      else
    
           switch(ch)
    
           {
    
           case '#':                        /*识别结束符‘#’(编号0)*/
    
               syn=0;
    
               token[i++]='#';
    
               token[i]='';
    
               break;
    
           case '+':                        /*识别‘+’(编号13)*/
    
               syn=13;
    
               token[i++]='+';
    
               token[i]='';
    
               break;
    
           case '-':                        /*识别‘-’(编号14)*/
    
               syn=14;
    
               token[i++]='-';
    
               token[i]='';
    
               break;
    
           case '*':                        /*识别‘*’(编号15)*/
    
               syn=15;
    
               token[i++]='*';
    
               token[i]='';
    
               break;
    
           case '/':                        /*识别‘/’(编号16)*/
    
               syn=16;
    
               token[i++]='/';
    
               token[i]='';
    
               break;
    
           case ':':
    
               token[i++]=':';
    
               ch=front(&prog);
    
               switch(ch)
    
               {
    
               case '=':                   /*识别‘:=’(编号18)*/
    
                    syn=18;
    
                    token[i++]='=';
    
                    token[i]='';
    
                    dequeue(&prog);
    
                    break;
    
               default:                    /*识别‘:’(编号17)*/
    
                    syn=17;
    
                    token[i]='';
    
                    break;
    
               }
    
               break;
    
           case '<':
    
               token[i++]='<';
    
               ch=front(&prog);
    
               switch(ch)
    
               {
    
               case '>':                   /*识别‘<>’(编号21)*/
    
                    syn=21;
    
                    token[i++]='>';
    
                    token[i]='';
    
                    dequeue(&prog);
    
                    break;
    
               case '=':                   /*识别‘<=’(编号22)*/
    
                    syn=22;
    
                    token[i++]='=';
    
                    token[i]='';
    
                    dequeue(&prog);
    
                    break;
    
               default:                    /*识别‘<’(编号20)*/
    
                    syn=20;
    
                    token[i]='';
    
                    break;
    
               }
    
               break;
    
           case '>':
    
               token[i++]='>';
    
               ch=front(&prog);
    
               switch(ch)
    
               {
    
               case '=':                   /*识别‘>=’(编号24)*/
    
                    syn=24;
    
                    token[i++]='=';
    
                    token[i]='';
    
                    dequeue(&prog);
    
                    break;
    
               default:                    /*识别‘>’(编号23)*/
    
                    syn=23;
    
                    token[i]='';
    
                    break;
    
               }
    
               break;
    
           case '=':                        /*识别‘=’(编号25)*/
    
               syn=25;
    
               token[i++]='=';
    
               token[i]='';
    
               break;
    
           case ';':                        /*识别‘;’(编号26)*/
    
               syn=26;
    
               token[i++]=';';
    
               token[i]='';
    
               break;
    
           case '(':                        /*识别‘(’(编号27)*/
    
               syn=27;
    
               token[i++]='(';
    
               token[i]='';
    
               break;
    
           case ')':                        /*识别‘)’(编号28)*/
    
               syn=28;
    
               token[i++]=')';
    
               token[i]='';
    
               break;
    
           default:                         /*出错!*/
    
               syn=-1;
    
               break;
    
           }
    
    }
    
     
    
    int main()
    
    {
    
      FILE *in,*out;
      ofstream outfile;
      ofstream inputfile;
      set<string> mset;
      int i;
      string ms;
      char ch;
    
    
      setnull(&prog);                           /*缓冲队列初始化*/
      printf("在input.txt里面输入内容(结束符为#),out.txt中查看输出
    
    ");
      char *argv[]={"E:/ofname.txt","input.txt","out.txt"};
    //w+ 存在则清空内容,否则新建文件 
           if(!(in=fopen(argv[1],"r+")))
           {
    		   
               printf("请在input.txt中输入内容!(结束符为#)
    ");
               in=fopen(argv[1],"w+");
    		   fputc('#',in);
    		    fclose(in);
    		   return 0;
           }
    
        out=fopen(argv[2],"w+");
    	outfile.open(argv[2],ios::in);
    	do
    	{
            do
               {
                    ch=fgetc(in);
                    enqueue(&prog,ch);
               }while(ch!='#' && !full(&prog));        
               if(ch=='#')
                    fclose(in);
           do
           {
               scanner();
               switch(syn)
               {
               case -2:			  
                    break;
               case 0:
                    break;
               case -1:
    			   outfile <<">>>>  error:在第"<<lineIndex<<"行,原因:"<<error_info[error_index]<<endl;
                    break;
               default:
    				outfile <<">>>>  ";
                    i=0;
    				ms="";
                    do
                    {
    					ms+=token[i];
    					outfile<<token[i++];
                        // fputc(token[i++],out);
                    }while(token[i]!='');
    				if(syn==10){
    					outfile<<"      "<<sign_type[3];
    					finditer=find(type3.begin(),type3.end(),ms);
    					if(finditer==type3.end())
    					type3.push_back(ms);//没找到就插入
    				}
    				else if(syn==11||syn==12){
    					outfile<<"      "<<sign_type[2];
    					finditer=find(type2.begin(),type2.end(),ms);
    					if(finditer==type2.end())
    					type2.push_back(ms);//没找到就插入
    				}
    				else if(syn>=13&&syn<=28){
    					outfile<<"      "<<sign_type[1];
    					finditer=find(type1.begin(),type1.end(),ms);
    					if(finditer==type1.end())
    					type1.push_back(ms);//没找到就插入
    				}
    				else if(syn>=1&&syn<=6){
    					outfile<<"      "<<sign_type[0];
    					finditer=find(type0.begin(),type0.end(),ms);
    					if(finditer==type0.end())
    					type0.push_back(ms);//没找到就插入
    				}
    			    outfile<<endl;
                    //fputc(',',out);
                   // i=syn/10;
                    //if(i!=0)outfile<<i+48;
    				//outfile<<syn%10+48<<endl;
                    //fputc(syn%10+48,out);
                    //fputc('
    ',out);
                    break;
    
               }
    
           }while(syn!=0 && (quantity(&prog) > MAXSIZE || ch=='#'));//以警号作为程序结束标志
    
    
      }while(ch!='#');
      outfile <<endl<<"符号表:"<<endl;
      list<string>::iterator eachit;
      outfile << sign_type[0] <<endl;
      for(eachit=type0.begin();eachit!=type0.end();++eachit){
        outfile << *eachit <<endl;
      }
    
       outfile << sign_type[1] <<endl;
      for(eachit=type1.begin();eachit!=type1.end();++eachit){
        outfile << *eachit <<endl;
      }
     /*
       outfile << sign_type[2] <<endl;
      for(eachit=type2.begin();eachit!=type2.end();++eachit){
        outfile << *eachit <<endl;
      }
      */
       outfile << sign_type[3] <<endl;
      for(eachit=type3.begin();eachit!=type3.end();++eachit){
        outfile << *eachit <<endl;
      }
      outfile.close();
      return 0;
    }
    

    语法分析 slr(1) _by MichaelZ

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<list>
    using namespace std;
    char KeyWords[10][10] = { "do", "else",  "if", "return", "void", "while","program","begin","end","then"};
    
    int slr1[102][26];// 分析表 赋值(s9=900,r1=1;acc=30)
    
    
    char creat[23][15]={"0","A->pi(H);C.","H->i","H->H,i","C->bOe","O->S","O->","S->T",
    "S->S;T","T->i:E","T->C","T->fBtT","T->fBtTlT","T->wBdT","B->E<E","E->E+M","E->M","M->M*F","M->F","F->i","F->n"};//文法单元;
    
    
    char temp[10],p,in[100],table[100][10];//存放识别字符串;
    
    
    int t,j,val,b,flag;
    char flag1,put[100],*arr;
    int begin=0,forward=0,pos;// 开始符号和向前看指针;
    FILE *out=fopen("out.txt","w");//用文件进行输出
    int main()
    {
    //SLR(1)分析表
    int	slr1[45][32]={
    
    	{0, 200,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0,   0,0,0,0,0,  100,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,0,    0,0,0,0,0,  0,0,0,0,0,   0,0,0,0,30,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,300,0,0,0,  0,0,0,0,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,400,0,0,  0,0,0,0,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
        {0, 0,600,0,0,0,  0,0,0,0,0,  0,0,0,0,0,   0,0,0,0,0,  0,500,0,0,0,  0,0,0,0,0 },
    	
    	{0, 0,0,0,700,0,  0,800,0,0,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,2,0,    0,2,0,0,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,900,  0,0,0,0,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,1000,0,0,0, 0,0,0,0,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,0,    0,0,1200,0,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,1100,0,0,  0,0,0,0,0 },
    	
    	{0, 0,0,0,3,0,  0,3,0,0,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,0,  1300,0,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,1700,0,0,0,  0,0,1200,0,0,  1900,0,0,2000,0,   0,0,0,0,0,  0,0,1800,1400,1500,  1600,0,0,0,0 },
    	{0, 0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0,   0,0,0,0,1,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,0,  0,0,0,2100,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	
    	{0, 0,0,0,0,2200,  0,0,0,5,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,7,     0,0,0,7,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,0,     0,0,0,0,2300,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,10,    0,0,0,10,0,  0,0,10,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,2800,0,0,0,  0,0,0,2900,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,2400,2500,2600,2700 },
    	
    	{0, 0,2800,0,0,0,  0,0,0,2900,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,3000,2500,2600,2700 },
    	{0, 0,0,0,0,4,  4,0,0,4,0,  0,0,4,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,1700,0,0,0,  0,0,1200,0,0,  1900,0,0,2000,0,   0,0,0,0,0,  0,0,1800,0,0,  3100,0,0,0,0 },
    	{0, 0,2800,0,0,0,  0,0,0,0,0,  0,0,0,0,0,   0,0,0,2900,0,  0,0,0,0,0,  0,0,3200,2600,2700 },
    	{0, 0,0,0,0,0,  0,0,0,0,0,  0,3300,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    
    	{0, 0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0,   3400,3500,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,16,  0,0,0,16,0,  0,16,16,0,16,   16,16,3600,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,18,  0,0,0,18,0,  0,18,18,0,18,   18,18,18,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,19,  0,0,0,19,0,  0,19,19,0,19,   19,19,19,0,0,  0,0,0,0,0,  0,0,0,0,0 },
        {0, 0,0,0,0,20,  0,0,0,20,0,  0,20,20,0,20,   20,20,20,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	
    	{0, 0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,3700,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,8,  0,0,0,8,0,  0,0,0,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,9,  0,0,0,9,0,  0,0,9,0,0,   0,3500,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,1700,0,0,0,  0,0,1200,0,0,  1900,0,0,2000,0,   0,0,0,0,0,  0,0,1800,0,0,  3800,0,0,0,0 },
    	{0, 0,2800,0,0,0,  0,0,0,0,0,  0,0,0,0,0,   0,0,0,2900,0,  0,0,0,0,0,  0,0,3900,2600,2700 },
    	
    	{0, 0,2800,0,0,0,  0,0,0,0,0,  0,0,0,0,0,   0,0,0,2900,0,  0,0,0,0,0,  0,0,0,4000,2700 },
    	{0, 0,2800,0,0,0,  0,0,0,0,0,  0,0,0,0,0,   0,0,0,2900,0,  0,0,0,0,0,  0,0,0,0,4000,2700 },
    	{0, 0,1700,0,0,0,  0,0,1200,0,0,  1900,0,0,2000,0,   0,0,0,0,0,  0,0,1800,0,0,  4200,0,0,0,0 },
    	{0, 0,0,0,0,11,  0,0,0,11,0,  0,0,4300,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,0,  0,0,0,0,0,  0,14,0,0,14,   0,3500,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	
    	{0, 0,0,0,0,15,  0,0,0,15,0,  0,15,15,0,15,   15,15,3600,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,17,  0,0,0,17,0,  0,17,17,0,17,   17,17,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,0,0,0,13,  0,0,0,13,0,  0,0,13,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 },
    	{0, 0,1700,0,0,0,  0,0,1200,0,0,  1900,0,0,2000,0,   0,0,0,0,0,  0,0,1800,0,0,  4400,0,0,0,0 },
    	{0, 0,0,0,0,12,  0,0,0,12,0,  0,0,12,0,0,   0,0,0,0,0,  0,0,0,0,0,  0,0,0,0,0 }
        };
    
        list<int> list1;//链表定义
    	list<char> list2;
    	list<int>::iterator it1;//itrator做指针
    	list<char>::iterator it2;
    	
    	//读取文件以达到输入的目的
    
    	void print(int flag);//print函数用于输入字符的类别判断与输出,并且将得到的类型存入in[]中
    	//in[]作为简化后的输入串
    	int group(char flag1 );//group函数用于确定项在分析表中的列号数
    	int size,i=0,l=1;
    	char ch; 
    	FILE *fp=fopen("file.txt","r");//用文件进行输入
    
        if (out==NULL){ return 0;}
    	if (fp==NULL){ return 0;}
    	fseek(fp,0,2);//找到文件尾
    	size=ftell(fp); //ftell存入的是偏移地址
    	arr=new char[size];
    	if ((fp=fopen("file.txt","r"))==NULL) exit(1);
    	if ((out=fopen("out.txt","w"))==NULL) exit(1);
    	while (!feof(fp))
    	{
    		ch=fgetc(fp);
    		arr[i++]=ch;//array用于存储文件中的字符
    	}
    	fclose(fp);  
    	size=i-1;
    	int state;//状态;
    	i=0; 
    	
    
        //词法分析器
    
    	while(i<=size)
    	{
    				for(t=0;t<8;t++)
    				temp[t]=0;
    		if(begin==forward)
    		{
    			ch=arr[forward];
    			if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z') state=9;
    			else if(ch>='0'&&ch<='9')state=12;
    			else if(ch=='+'||ch=='-'||ch=='*'||ch=='/')state=25;
    			else if(ch=='<'||ch=='>'||ch==':')state=0;
    			else if(ch=='.'||ch==','||ch==';'||ch=='('||ch==')')state=30;
    			else if (ch=='
    '||ch=='	'||ch==' ') state=22;
    			else state=31;
    			
    		}		
    		
    
    
    switch(state)
    		{
    		case 0: {ch=arr[i++];forward++;}	
    			if(ch=='<')state=1;
    			else if(ch=='='){state=5;}
    			else if(ch=='>')state=6;
    			break;
    		case 1:{ch=arr[i++];forward++;}	
    			if(ch=='=')state=2;
    			else if(ch=='>')state=3;
    			else state=4;
    			break;
    		case 2:print(5);	break;		
    		case 3:print(5);	break;		
    		case 4:{i=i-1;forward=forward-1;print(5);}
    			break;
    		case 5:print(5);break;
    		case 6:{ch=arr[i++];forward++;}	
    			if(ch=='=')state=7;
    			else state=8;
    			break;
    		case 7:print(5);break;			
    		case 8:{i=i-1;forward=forward-1;print(5);}
    			break;
    	
    		
    		case 9:{ch=arr[i++];forward++;}	
    			if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))state=10;
    			break;
    		
    		
    		case 10:{ch=arr[i++];forward++;}	
    			if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))state=10;
    			else if(ch>='0'&&ch<='9')state=10;
    			else state=11;
    			break;
    		case 11:
    			i=i-1;forward=forward-1;print(1);
    			break;
    		
    		case 12:{ch=arr[i++];forward++;}	
    			if(ch>='0'&&ch<='9')state=13;
    			break;
    		case 13:{ch=arr[i++];forward++;}	
    			if(ch>='0'&&ch<='9')state=13;
    			else if (ch=='E')state=16;
    			else if(ch=='.')state=14;
    			else state=20;
    			break;
    		case 14:{ch=arr[i++];forward++;}	
    			if(ch>='0'&&ch<='9')state=15;
    			else state=32;
    			break;
    		case 15:{ch=arr[i++];forward++;}	
    			if(ch>='0'&&ch<='9')state=15;
    			else if(ch=='E')state=16;
    			else state=21;
    			break;
    		case 16:{ch=arr[i++];forward++;}	
    			if(ch>='0'&&ch<='9')state=18;
    			else if(ch=='+'||ch=='-')state=17;
    			else state=32;
    			break;
    		case 17:{ch=arr[i++];forward++;}	
    			if(ch>='0'&&ch<='9')state=18;
    			else state=32;
    			break;
    		case 18:{ch=arr[i++];forward++;}	
    			if(ch>='0'&&ch<='9')state=18;
    			else   state=19;
    			break;
    		case 19:{i=i-1;forward=forward-1;print(2);}break;
    		case 20:{i=i-1;forward=forward-1;print(2);}break;
    		case 21:{i=i-1;forward=forward-1;print(2);}break;
    		case 22:{ch=arr[i++];forward++;}	
    			if(ch=='
    '||ch=='	'||ch==' ')
    				state=23;
    			break;
    		case 23:{ch=arr[i++];forward++;}	
    			if(ch=='
    '||ch=='	'||ch==' ')	state=23;
    			else   state=24;
    			break;
    		case 24:{i=i-1; forward=forward-1;begin+=1; forward=begin;}
    			break;
    
    
    		case 25:{ch=arr[i++];forward++;}	
    			if(ch=='+')state=26;
    			else if(ch=='-')state=27;
    			else if(ch=='*')state=28;
    			else if(ch=='/')state=29;	
    			break;
    		
    		case 26:print(4);break;
    		case 27:print(4);break;
    		case 28:print(4);break;
    		case 29:print(4);break;
    		case 30:{ch=arr[i++];forward++;}print(3);break;
    		case 31:{ch=arr[i++];forward++;}print(6);break;	
    		case 32:{i=i-1;forward=forward-1;}print(6);break;	
    		}
    
    	
    }
    
    	//语法分析;字符串输入以$结束
    	printf("输入的字符串以结束$
    ");
    	
    	fputs("输入的字符串以结束$
    ",out);
    	
    	in[val]='$';
    	printf("%s",in);
    	printf("
    ");
    	fputs(in,out);
    	fputs("
    ",out);
    	i=0;j=0;
    	list1.push_back(0);//push_back() //增加一元素到链表尾
    	char n,c;
    	int m,st,len;
    	printf("栈              符号                      输入                     动作 
    "); 
        fputs("栈                                   符号                                    输入                                                     动作 
    ",out);
    	while(1) 
    	{ 
    		char s[10];
    		char b[1000]={0};
    		//begin() 返回第一个元素的指针(iterator)
    		//返回最后一个元素的下一位置的指针(list为空时end()=begin())
    		for(it1=list1.begin();it1!=list1.end();it1++){	
    		//printf("%d",*it1);
    	    //整形字符串拼接
    		sprintf(s, "%d",*it1);
    		sprintf(b,"%s%s",b,s); 
    		}
            //printf("%s",b);
            fputs(b,out);
    	//	printf("                  ");
    		fputs("                                   ",out);
    		for(it2=list2.begin();it2!=list2.end();it2++){
    	//		printf("%c",*it2); 
    			fputc(*it2,out);
    		}
    	//	printf("                              ");	
    		fputs("                  ",out);
    		for(i=j;i<=val;i++){
    			printf("%c",in[i]);
    			fputc(in[i],out);
    		}
    		//printf("                              ");
    		fputs("                                 ",out);
    		st=list1.back();
    		
    		n=in[j];
    		flag=group(n);//得到当前状态行数 
    		
    		if(slr1[st][flag]>100)
    		{
    			m=slr1[st][flag]/100;
         
    			printf("移入
    ");
    			fputs("移入
    ",out);
    			list1.push_back(m);
        
    			list2.push_back(in[j]);
    			j++;
    		}
    		else if(slr1[st][flag]<100&&slr1[st][flag]!=30&&slr1[st][flag]!=0)
    		{
    			m=slr1[st][flag];
    			printf("根据%s规约
    ",creat[m]);
    			fputs("根据",out);
    			fputs(creat[m],out);
    		    fputs("规约
    ",out);
    			c=creat[m][0]; 			  
    			flag=group(c);		  
    			len=strlen(creat[m])-3;
    			for(i=0;i<len;i++)
    
    			{	 list1.pop_back();
    			list2.pop_back();
    			}
    
    			st=list1.back();
    			//printf("
    %d
    ",st);
                //printf("
    %d
    ",flag);
    			list2.push_back(c);
    			m=slr1[st][flag]/100;
    
    			list1.push_back(m);
    		}
    		else if(slr1[st][flag]==30)
    		{ 
    			printf("接受
    ");
    			fputs("接受
    ",out);
    			break;
    		}
    		else if(slr1[st][flag]==0)
    		{
    			printf("
    ");
    			fputs("
    ",out);
                printf("%s",table[j-1]);
    			fputs(table[j-1],out);
    			printf("%s ",table[j]);
    			fputs(table[j],out);
    			printf("ERROR
    ");
    			fputs("ERROR
    ",out);
    			break;
    		}
    	}
        fclose(out);
    	return 0;
    	}	
    	void print(int b) //输出 
    	{	
    		pos=begin;
    		for(t=0;t<forward-begin;t++)
    		{
    			p=arr[pos++];temp[t]=p;			
    		}
    		begin=forward;
    		
    		switch(b)
    		{
            case 1:        
    			{
    				for(j=0; j<55; j++)
    				
    					if(strcmp(temp,KeyWords[j])==0)
    					{
    						printf("<%s keyword>
    ",temp);
    					     fputs("<",out);
    						 fputs(temp,out);
    						 fputs(" keyword>
    ",out);
    						if(strcmp(temp,"if")==0)
    						{	
    							strcpy(table[val],temp);
    							in[val++]='f';	break;}
    						else if(strcmp(temp,"program")==0)
    						{
    							strcpy(table[val],temp);
    							in[val++]='p';	break;}
    						else if(strcmp(temp,"end")==0)
    						{
    							strcpy(table[val],temp);
    							in[val++]='e';	break;}
    						else if(strcmp(temp,"else")==0)
    						{
    							strcpy(table[val],temp);
    							in[val++]='l';	break;}
    						else if(strcmp(temp,"while")==0)
    						{
    							strcpy(table[val],temp);	
    							in[val++]='w';	break;}
    						else if(strcmp(temp,"do")==0)
    						{
    							strcpy(table[val],temp);
    					    	in[val++]='d';	break;}
    						else if(strcmp(temp,"then")==0)
    						{
    								strcpy(table[val],temp);
    							in[val++]='t';	break;}
    						else 
    						{ 
    							strcpy(table[val],temp);
    							in[val++]='b';	break;	}										   
    					}
    					if(j==55) 
    					{	printf("<%s id>
    ",temp);
    					 fputs("<",out);
    						 fputs(temp,out);
    						 fputs(" id>
    ",out);
    					strcpy(table[val],temp);
    					in[val++]='i';}
                }break;
    		case 2:
    		 	printf("<%s num>
    ",temp);
    			fputs("<",out);
    			fputs(temp,out);
    		    fputs(" num>
    ",out);
    			strcpy(table[val],temp);
    			in[val++]='n';			 
    			break;
    		case 3:
    		 	printf("<%s division>
    ",temp);
    			fputs("<",out);
    			fputs(temp,out);
    		    fputs(" division>
    ",out);
    			 strcpy(table[val],temp);
    			in[val++]=temp[0];			
    			break;
    		case 4:
    			printf("<%s relation>
    ",temp);
    			fputs("<",out);
    			fputs(temp,out);
    		    fputs(" relation>
    ",out);
    		    strcpy(table[val],temp);
    			in[val++]=temp[0];
    			break;
    		case 5: 
    			    
    			printf("<%s operator>
    ",temp);
    			fputs("<",out);
    			fputs(temp,out);
    		    fputs(" operator>
    ",out);
    			strcpy(table[val],temp);
    			in[val++]=temp[0];	
    			
    			break;
    		case 6:
    			 	printf("<%s ERROR>
    ",temp);
    				fputs("<",out);
    		    	fputs(temp,out);
    		        fputs(" ERROR>
    ",out);
    			break;
    		}		
    	}
    
    
    	int group(char flag1 )
    	{
    		if(flag1=='p')
    			flag=1;
    		else if(flag1=='i')
    			flag=2;
    		else if(flag1=='(')
    			flag=3;		
    		else if(flag1==')')
    			flag=4;
    		else if(flag1==';')
    			flag=5;
    		else if(flag1=='.')
    			flag=6;
    		else if(flag1==',')
    			flag=7;
    		else if(flag1=='b')
    			flag=8;
    		else if(flag1=='e')
    			flag=9;
    		else if(flag1==':')
    			flag=10;
    		else if(flag1=='f')
    			flag=11;
    		else if(flag1=='t')
    			flag=12;
    		else if(flag1=='l')
    			flag=13;
    		else if(flag1=='w')
    			flag=14;
    		else if(flag1=='d')
    			flag=15;
    		else if(flag1=='<')
    			flag=16;
    		else if(flag1=='+')
    			flag=17;
    		else if(flag1=='*')
    			flag=18;
    		else if(flag1=='n')
    			flag=19;
    		else if(flag1=='$')
    			flag=20;
    		else if(flag1=='A')
    			flag=21;
    		else if(flag1=='H')
    			flag=22;
    		else if(flag1=='C')
    			flag=23;
    		else if(flag1=='O')
    			flag=24;
    		else if(flag1=='S')
    			flag=25;
    		else if(flag1=='T')
    			flag=26;
            else if(flag1=='B')
    			flag=27;
    		else if(flag1=='E')
    			flag=28;
    		else if(flag1=='M')
    			flag=29;
    		else if(flag1=='F')
    			flag=30;
    		return(flag);
    	} 
    	
    	
    

    语义分析 by france&lola

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<cstring>
    using namespace std;
    //词法分析双向链表(存已识别的词单元(endSign))
    typedef struct WordAnalysisList
    {
    	struct WordAnalysisList *last;
    	char index;//以字母作为标号 其index为在endSign中对应的元素
    	char value[128];//对应值字符串
    	struct WordAnalysisList *next;
    }WordAnalysisList;
    //headWAL 对应语法分析时的输入
    WordAnalysisList *headWAL, *currendWAL;
    //headSignStack:符号栈 从null到最后被规约成S tail4:反着显示要用到
    WordAnalysisList *headSignStack, *tail4;
    typedef struct Tree
    {
    	int number;
    	char bb[128];
    	struct Tree *haveF;
    	struct Tree *child[4];
    }Tree;
    Tree *root;
    //语法分析栈
    typedef struct stack
    {
    	struct stack *last;
    	//当前栈的值(规约规则的序号)
    	int number;
    	//非终结符的个数
    	int flag;
    	char bb[128];
    	struct Tree *haveF;
    	struct stack *next;
    }Stack;
    Stack *stackHead, *tail2;
    //存规约顺序
    Stack *guiYueOrderheadTemp;
    //在guiYueOrderheadTemp初始化的时候赋值给guiYueOrderhead 存的是第一个规约
    Stack *guiYueOrderhead;
    //对语法树进行前序遍历
    Stack * grammarTreePreorderHead;
    //用来存储 id或者number 
    typedef struct Str2
    {
    	char sstr[128];
    	struct Str2 *next;
    }Str2;
    //head*:规约时将识别到的id或num放入list
    Str2 *headid, *headnum, *headid2, *headnum2;
    int id = 0, num = 0, ok = 1;
    char str[128], Bool[128];
    
    //初始化词法分析
    void initMorphology(){
    	headWAL = NULL;
    	currendWAL = NULL;
    }
    //行号
    int line = 1;
    
    //act[i][j]=a:第i个状态在第j个终结符执行的操作:a>0表示sa,a<0表示ra a=0表示acc
    int act[45][20];
    //gt[i][j]=b:规约pop stack后第i个状态在第j个终结符时跳转到第b个状态
    int gt[45][10];
    //haveF[i][j] = c第i个字母在第j个产生式中存在c次
    int haveF[10][21];
    //全局的Lx Tx;
    int L = 0, T = 0;
    //具体的产生式规则
    char gg[21][128] = { "s'->A", "S -> program id ( id_lists );  compound_stmt .", "id_lists -> id ", "id_lists -> id_lists , id ", "compound_stmt -> begin optional_stmts end", "optional_stmts -> stmts ", "optional_stmts -> ε", "stmts -> stmt ", "stmts -> stmts; stmt ", "stmt -> id := expr ", "stmt -> compound_stmt", "stmt -> if bool then stmt ", "stmt -> if bool then stmt else stmt ", "stmt -> while bool  do stmt", "bool ->  expr < expr ", "expr -> expr + term  ", "expr -> term", "term -> term * factor ", "term -> factor", "factor -> id ", "factor -> num" };
    //简化的产生式规则
    char g[21][12] = { "s'->A", "A->bcdBefCg", "B->c", "B->Bhc", "C->iDj", "D->E", "D->ε", "E->F", "E->EfF", "F->ckH", "F->C", "F->lGmF", "F->lGmFnF", "F->oGpF", "G->HqH", "H->HrI", "H->I", "I->IsJ", "I->J", "J->c", "J->t" };
    //规约时栈pop的个数
    int Number[21] = { 1, 8, 1, 3, 3, 1, 0, 1, 3, 3, 1, 4, 6, 4, 3, 3, 1, 3, 1, 1, 1 };
    //非终结符
    char noend[10][15] = { "S", "id_lists", "compound_stmt", "optional_stmts", "stmts", "stmt", "bool", "expr", "term", "factor" };
    //终结符
    char endSign[21][8] = { "ε", "program", "id", "(", ")", ";", ".", ",", "begin", "end", ":=", "if", "then", "else", "while", "do", "<", "+", "*", "num", "$" };
    /*
    初始化语法分析表(手动)
    act[i][j]=a:第i个状态在第j个终结符执行的操作:a>0表示sa,a<0表示ra a=0表示acc
    gt[i][j]=b:规约pop stack后第i个状态在第j个终结符时跳转到第b个状态
    haveF[i][j] = c第i个字母在第j个产生式中存在c次
    */
    void initGrammar()
    {
    	act[0][0] = 2;
    	act[1][19] = 0;
    	act[2][1] = 3;
    	act[3][2] = 4;
    	act[4][1] = 6;
    	act[5][3] = 7; act[5][6] = 8;
    	act[6][3] = -2; act[6][6] = -2;
    	act[7][4] = 9;
    	act[8][1] = 10;
    	act[9][7] = 12;
    	act[10][3] = -3; act[10][6] = -3;
    	act[11][5] = 13;
    	act[12][1] = 17; act[12][7] = 12; act[12][8] = -6; act[12][10] = 19; act[12][13] = 20;
    	act[13][19] = -1;
    	act[14][8] = 21;
    	act[15][4] = 22; act[15][8] = -5;
    	act[16][4] = -7; act[16][8] = -7;
    	act[17][9] = 23;
    	act[18][4] = -10; act[18][8] = -10; act[18][12] = -10;
    	act[19][1] = 28; act[19][18] = 29;
    	act[20][1] = 28; act[20][18] = 29;
    	act[21][4] = -4; act[21][5] = -4; act[21][8] = -4; act[21][12] = -4;
    	act[22][1] = 17; act[22][7] = 12; act[22][10] = 19; act[22][13] = 20;
    	act[23][1] = 28; act[23][18] = 29;
    	act[24][11] = 33;
    	act[25][15] = 34; act[25][16] = 35;
    	act[26][4] = -16; act[26][8] = -16; act[26][11] = -16; act[26][12] = -16; act[26][14] = -16; act[26][15] = -16; act[26][16] = -16; act[26][17] = 36;
    	act[27][4] = -18; act[27][8] = -18; act[27][11] = -18; act[27][12] = -18; act[27][14] = -18; act[27][15] = -18; act[27][16] = -18; act[27][17] = -18;
    	act[28][4] = -19; act[28][8] = -19; act[28][11] = -19; act[28][12] = -19; act[28][14] = -19; act[28][15] = -19; act[28][16] = -19; act[28][17] = -19;
    	act[29][4] = -20; act[29][8] = -20; act[29][11] = -20; act[29][12] = -20; act[29][14] = -20; act[29][15] = -20; act[29][16] = -20; act[29][17] = -20;
    	act[30][14] = 37;
    	act[31][4] = -8; act[31][8] = -8;
    	act[32][4] = -9; act[32][8] = -9; act[32][12] = -9; act[32][16] = 35;
    	act[33][1] = 17; act[33][7] = 12; act[33][10] = 19; act[33][13] = 20;
    	act[34][1] = 28; act[34][18] = 29;
    	act[35][1] = 28; act[35][18] = 29;
    	act[36][1] = 28; act[36][18] = 29;
    	act[37][1] = 17; act[37][7] = 12; act[37][10] = 19; act[37][13] = 20;
    	act[38][4] = -11; act[38][8] = -11; act[38][12] = 43;
    	act[39][11] = -14; act[39][14] = -14; act[39][16] = 35;
    	act[40][4] = -15; act[40][8] = -15; act[40][11] = -15; act[40][12] = -15; act[40][14] = -15; act[40][15] = -15; act[40][16] = -15; act[40][17] = 36;
    	act[41][4] = -17; act[41][8] = -17; act[41][11] = -17; act[41][12] = -17; act[41][14] = -17; act[41][15] = -17; act[41][16] = -17; act[41][17] = -17;
    	act[42][4] = -13; act[42][8] = -13; act[42][12] = -13;
    	act[43][1] = 17; act[43][7] = 12; act[43][10] = 19; act[43][13] = 20;
    	act[44][4] = -12; act[44][8] = -12; act[44][12] = -12;
    
    	gt[0][0] = 1;
    	gt[4][1] = 5;
    	gt[9][2] = 11;
    	gt[12][2] = 18; gt[12][3] = 14; gt[12][4] = 15; gt[12][5] = 16;
    	gt[19][6] = 24; gt[19][7] = 25; gt[19][8] = 26; gt[19][9] = 27;
    	gt[20][6] = 30; gt[20][7] = 25; gt[20][8] = 26; gt[20][9] = 27;
    	gt[22][2] = 18; gt[22][5] = 31;
    	gt[23][7] = 32; gt[23][8] = 26; gt[23][9] = 27;
    	gt[33][2] = 18; gt[33][5] = 38;
    	gt[34][7] = 39; gt[34][8] = 26; gt[34][9] = 27;
    	gt[35][8] = 40; gt[35][9] = 27;
    	gt[36][9] = 41;
    	gt[37][2] = 18; gt[37][5] = 42;
    	gt[43][2] = 18; gt[43][5] = 44;
    
    	haveF[1][1] = 1; haveF[1][3] = 1;
    	haveF[2][1] = 1; haveF[2][10] = 1;
    	haveF[3][4] = 1;
    	haveF[4][5] = 1; haveF[4][8] = 1;
    	haveF[5][7] = 1; haveF[5][8] = 1; haveF[5][11] = 1; haveF[5][12] = 2; haveF[5][13] = 1;
    	haveF[6][11] = 1; haveF[6][12] = 1; haveF[6][13] = 1;
    	haveF[7][9] = 1; haveF[7][14] = 2; haveF[7][15] = 1;
    	haveF[8][15] = 1; haveF[8][16] = 1; haveF[8][17] = 1;
    	haveF[9][17] = 1; haveF[9][18] = 1;
    }
    /*
    增加词法节点
    以标号c和值s[]建一个节点,并加到词法分析链表的最后面
    */
    void addWordNode(char c, char s[])
    {
    	WordAnalysisList *temp;
    	//创建WAL_Node
    	temp = (WordAnalysisList*)malloc(sizeof(WordAnalysisList));
    	temp->index = c;
    	if (s)
    		strcpy(temp->value, s);
    
    	if (headWAL == NULL)
    	{
    		headWAL = temp;
    		currendWAL = headWAL;
    	}
    	else
    	{
    		printf("currend value:%s
    ", currendWAL->value);
    		if (headWAL->next == NULL){
    			headWAL->next = temp;
    			currendWAL = headWAL->next;
    		}
    		else{
    			currendWAL->next = temp;
    			currendWAL = currendWAL->next;
    		}
    		currendWAL->next = NULL;
    	}
    }
    /*
    识别关键字
    传入文件开始识别指针
    返回关键字所在endSign数组中的位置 或 报error返回
    */
    void keyword(FILE *fp)
    {
    	char ch, instring[128];
    	int n = 0;
    	do{
    		ch = fgetc(fp);
    		instring[n++] = ch;
    	} while ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'));
    	fseek(fp, -1L, 1);
    	instring[--n] = 0;
    	_strlwr(instring);//将字符串中的字符转换为小写
    	int i;
    	for (i = 1; i<20; i++)
    	{
    		if (i != 2 && i != 19)
    		{
    			if (strcmp(instring, endSign[i]) == 0)
    				break;
    		}
    	}
    	if (i<20)
    	{
    		//加入关键字
    		addWordNode(97 + i, instring);
    	}
    	else
    	{
    		if (n>32)
    			printf("-->>error标识符过长!  line:%d
    ", line);
    		//加入id
    		addWordNode(97 + 2, instring);
    	}
    }
    void number(FILE *fp, int flag)
    {
    	char ch, instring[128];//,instring2[128];
    	int n = 0; int number = 0; int m;
    	do{
    		ch = fgetc(fp);
    		instring[n++] = ch;
    	} while (ch >= '0'&&ch <= '9');
    	fseek(fp, -1L, 1);
    	instring[--n] = '';
    	for (int i = 0; i<n; i++)
    	{
    		m = 1;
    		for (int j = 0; j<(n - i - 1); j++)
    			m *= 10;
    		number += (instring[i] - 48)*m;
    	}
    	//加入number
    	addWordNode(97 + 19, instring);
    }
    void number36(FILE *fp)
    {
    	char ch, instring[128];
    	int n = 0;
    	int number = 0, m;
    	do{
    		ch = fgetc(fp);
    		if (ch == '
    ')
    			line++;
    		instring[n++] = ch;
    	} while ((ch >= '0'&&ch <= '9') || (ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'));
    	fseek(fp, -1L, 1);
    	instring[--n] = '';
    	for (int i = 0; i<n; i++)
    	{
    		m = 1;
    		for (int j = 0; j<(n - i - 1); j++)
    			m *= 36;
    		if (instring[i] >= '0'&&instring[i] <= '9')
    			number += (instring[i] - 48)*m;
    		else if (instring[i] >= 'a'&&instring[i] <= 'z')
    			number += (instring[i] - 87)*m;
    		else
    			number += (instring[i] - 55)*m;
    	}
    	if (number >= 16777216)
    		printf("-->> 7、error越界错误! line:%d
    ", line);
    	//加入number
    	addWordNode(97 + 19, instring);
    }
    void other(FILE *fp)
    {
    	int endIndex = 0;
    	char ch = fgetc(fp);
    	if (ch == ' ' || ch == '
    ' || ch == '	')
    		endIndex = -2;
    	char s[3];
    	s[0] = ch;
    	if (ch == ':')
    	{
    		ch = fgetc(fp);
    		if (ch == '=')
    		{
    			s[1] = ch; s[2] = '';
    		}
    		else
    		{
    			endIndex = -1;
    		}
    	}
    	else
    	{
    		s[1] = '';
    	}
    	int i;
    	for (i = 1; i<20; i++)
    	{
    		if (i != 2 && i != 19)
    		{
    			if (strcmp(endSign[i], s) == 0)
    			{
    				break;
    			}
    		}
    	}
    	if (i<20)
    	{
    		endIndex = i;
    	}
    	else
    	{
    		endIndex = -1;
    	}
    	if (endIndex>-1)
    	{
    		addWordNode(97 + endIndex, endSign[endIndex]);
    	}
    }
    //在词法最后增加一个表示识别结束的$符号
    void addWordNodeEnd()
    {
    	WordAnalysisList *endNode;
    	endNode = (WordAnalysisList*)malloc(sizeof(WordAnalysisList));
    	endNode->index = '$';
    	endNode->next = NULL;
    	currendWAL->next = endNode;
    }
    //添加当前要移入的词法单元到符号栈
    void addCurrentInputWord(char c, char s[])
    {
    	WordAnalysisList *p1;
    	p1 = (WordAnalysisList*)malloc(sizeof(WordAnalysisList));
    	p1->index = c;
    	if (s)
    		strcpy(p1->value, s);
    	p1->next = headSignStack;
    	p1->last = NULL;
    	headSignStack->last = p1;
    	headSignStack = p1;
    }
    //传入的s为类型number或者id的值 c=1 表示传入的是id 0 number
    void addheadstr(int c, char s[])
    {
    	printf("
     addheadstr s:%s
    ", s);
    	Str2 *p1, *p2, *p3 = NULL;
    	p1 = (Str2*)malloc(sizeof(Str2));
    	strcpy(p1->sstr, s);
    	p1->next = NULL;
    	if (c == 1)
    	{
    		p2 = headid;
    		if (p2 == NULL)
    		{
    			headid = p1;
    		}
    		else
    		{
    			while (p2)
    			{
    				p3 = p2;
    				p2 = p2->next;
    			}
    			p3->next = p1;
    		}
    	}
    	else
    	{
    		p2 = headnum;
    		if (p2 == NULL)
    		{
    			headnum = p1;
    		}
    		else
    		{
    			while (p2)
    			{
    				p3 = p2;
    				p2 = p2->next;
    			}
    			p3->next = p1;
    		}
    	}
    }
    //移入或规约时产生的push
    void addstack(int t)
    {
    	Stack *p1;
    	p1 = (Stack*)malloc(sizeof(Stack));
    	p1->number = t;
    	p1->next = stackHead;
    	p1->last = NULL;
    	stackHead->last = p1;
    	stackHead = p1;
    }
    //存语法分析的规约顺序(t为第几条规约规则)
    void addGuiyueOrder(int t)
    {
    	Stack *p1;
    	p1 = (Stack*)malloc(sizeof(Stack));
    	p1->number = t;
    	p1->flag = 0;
    	p1->next = guiYueOrderheadTemp;
    	p1->last = NULL;
    	if (guiYueOrderheadTemp == NULL)
    		guiYueOrderheadTemp = guiYueOrderhead = p1;
    	else guiYueOrderheadTemp->last = p1;
    	guiYueOrderheadTemp = p1;
    }
    //规约时状态栈产生的pop
    void popstack(int i)
    {
    
    	int j = Number[i];
    	while (j--)
    	{
    		stackHead = stackHead->next;
    	}
    	stackHead->last = NULL;
    }
    //规约时符号栈产生的pop
    void popSignStack(int i)
    {
    	WordAnalysisList *p1;
    	p1 = headSignStack;
    	int j = Number[i];
    	while (j--)
    	{
    		p1 = p1->next;
    	}
    	if (p1)
    	{
    		p1->last = NULL;
    
    	}
    	headSignStack = p1;
    }
    //将原来缩略的产生字母转为对应的词法单元
    void Printf(char aa)
    {
    	if (aa>'a' && aa <= 'z')
    	{
    		printf("%s ", endSign[aa - 97]);
    	}
    	else if (aa >= 'A' && aa <= 'Z')
    	{
    		printf("%s ", noend[aa - 65]);
    	}
    	else if (aa == '$')
    	{
    		printf("$");
    	}
    }
    void output(int t, int j)
    {
    	Stack *p1;
    	WordAnalysisList *p2, *p3, *p4;
    	p2 = headWAL;
    	p1 = tail2;
    	p3 = headSignStack;
    	p4 = tail4;
    	if (t != 3)
    	{
    		if (t == 1)
    			printf("移入
    ");
    		else if (t == 2) printf("归约%s
    ", gg[j]);
    		while (p1)
    		{
    			printf("%d ", p1->number);
    			p1 = p1->last;
    		}
    		printf("                          ");
    		while (p4)
    		{
    			Printf(p4->index);
    			p4 = p4->last;
    		}
    		printf("                          ");
    		while (p2)
    		{
    			Printf(p2->index);
    			p2 = p2->next;
    		}
    		printf("                          ");
    	}
    	else printf("接受
    ");
    }
    //由词法单元去执行语法分析,得到一个规约顺序(实验二为直接输出)
    void grammarAnalysis()
    {
    	WordAnalysisList *temp;
    	int i, j, k;
    	Stack *p1;
    	p1 = (Stack*)malloc(sizeof(Stack));
    	//初始化栈
    	p1->number = 0;
    	p1->next = NULL;
    	p1->last = NULL;
    	stackHead = tail2 = p1;
    	WordAnalysisList *p2;
    	//headWAL 对应语法分析时的输入
    	while (1)
    	{
    		if (headWAL->index == '$')
    		{
    			j = headWAL->index - 17;
    		}
    		else
    			j = headWAL->index - 98;
    		//移入 入栈
    		if (act[stackHead->number][j]>0)
    		{
    			addstack(act[stackHead->number][j]);
    			if (tail4 == NULL)
    			{
    				//p2:当前输入的词法单元
    				p2 = (WordAnalysisList*)malloc(sizeof(WordAnalysisList));
    				p2->index = headWAL->index;
    				strcpy(p2->value, headWAL->value);
    				p2->next = NULL;
    				p2->last = NULL;
    				//加到符号栈
    				headSignStack = tail4 = p2;
    			}
    			else addCurrentInputWord(headWAL->index, headWAL->value);
    
    			headWAL = headWAL->next;
    			output(1, 0);
    		}
    		//规约 改栈
    		else if (act[stackHead->number][j]<0)
    		{
    			i = -act[stackHead->number][j];
    			//存第i条规约顺序
    			addGuiyueOrder(i);
    			//存入id或者number到2个list中
    
    			//stmt->id := expr 以前是一直移入 直到 id := expr head4为expr要找到前面的id 执行下面的操作
    			if (i == 9)
    			{
    				k = 2;
    				temp = headSignStack;
    				while (k--)
    				{
    					//printf("?%s
    ", temp->value);
    					temp = temp->next;
    				}
    				addheadstr(1, temp->value);
    			}
    			//factor->id 规则
    			else if (i == 19)
    			{
    				addheadstr(1, headSignStack->value);
    			}
    			//factor->num
    			else if (i == 20)
    			{
    				addheadstr(0, headSignStack->value);
    			}
    
    			popstack(i);
    			popSignStack(i);
    			if (headSignStack == NULL)
    			{
    				p2 = (WordAnalysisList*)malloc(sizeof(WordAnalysisList));
    				p2->index = g[i][0];
    				p2->next = NULL;
    				p2->last = NULL;
    				headSignStack = tail4 = p2;
    			}
    			else addCurrentInputWord(g[i][0], 0);
    
    			//第i条规则 左部符号在非终结符中排的位置(如B排66-65=1) 即gt中的j 
    			addstack(gt[stackHead->number][g[i][0] - 65]);
    			output(2, i);
    		}
    		else if (act[stackHead->number][j] == 0)
    		{
    
    			if (headWAL->index != '$' || (tail4->index != 'A' || tail4->last != NULL))
    			{
    				printf("
    error!
    ");
    				ok = 0;
    			}
    			else
    				output(3, 0);
    			break;
    		}
    	}
    }
    //规约的产生式有几个非终结符存入flag中
    void noendNumToflag()
    {
    	int t;
    	Stack *pp;
    	pp = guiYueOrderhead;
    	while (pp)
    	{
    		pp->haveF = NULL;
    		//printf("%d ",pp->number);
    		t = pp->number;
    		if (t == 2 || t == 19 || t == 20 || t == 6)
    		{
    			pp->flag = -1;//只有这句用到
    		}
    		else if (t == 3 || t == 5 || t == 7 || t == 8 || t == 9 || t == 10 || t == 16 || t == 18)
    		{
    			pp->flag = 1;
    		}
    		else if (t == 1 || t == 11 || t == 13 || t == 14 || t == 15 || t == 17)
    		{
    			pp->flag = 2;
    		}
    		else if (t == 12)
    		{
    			pp->flag = 3;
    		}
    		pp = pp->last;
    	}
    }
    //创建leaf节点(传入一条规约规则)
    Tree *creatleaf(Stack *rule)
    {
    	Tree *p1;
    	p1 = (Tree*)malloc(sizeof(Tree));
    	p1->number = rule->number;
    	//rule19:factor->id rule9: stmt->id := expr
    	if (rule->number == 19 || rule->number == 9)
    	{
    		strcpy(p1->bb, headid->sstr);
    		headid = headid->next;
    	}
    	//rule20:factor->num
    	else if (rule->number == 20)
    	{
    		strcpy(p1->bb, headnum->sstr);
    		headnum = headnum->next;
    	}
    	p1->haveF = NULL;
    	p1->child[0] = NULL;
    	p1->child[1] = NULL;
    	p1->child[2] = NULL;
    	p1->child[3] = NULL;
    	return p1;
    }
    Tree *creathaveF(Stack *pp, Tree *child)
    {
    	Tree *p1;
    	p1 = (Tree*)malloc(sizeof(Tree));
    	p1->number = pp->number;
    	///*
    	if (pp->number == 19 || pp->number == 9)
    	{
    		strcpy(p1->bb, headid->sstr);
    		headid = headid->next;
    	}
    	else if (pp->number == 20)
    	{
    
    		strcpy(p1->bb, headnum->sstr);
    		headnum = headnum->next;
    	}
    	//*/
    	p1->child[0] = child;
    	p1->child[1] = NULL;
    	p1->child[2] = NULL;
    	p1->child[3] = NULL;
    	p1->haveF = NULL;
    	return p1;
    }
    //为child的添加一个产生式为p的haveF
    void addhaveF(Tree *child, Stack *p)
    {
    	int i = 0;
    	Tree *node;
    	//产生式的haveF存在 说明之前有另外一天产生式以其作为haveF了 
    	//如A->B p:A->D C->A+A 在p找haveF时就是p->haveF =C->A+A存在 
    	//
    	if (p->haveF)
    	{
    		node = p->haveF;
    		while (node->child[i] && i <= 3)
    		{
    			i++;
    		}
    		//寻找一个空 to添加节点
    		node->child[i] = child;
    	}
    	//p:A->B 的haveF没有找到 child:B->id
    	else
    	{
    		node = creathaveF(p, child);
    		p->haveF = node;
    	}
    }
    //从当前的规约顺序guiYueOrderhead开始寻找child的haveF
    Stack *findhaveF(Stack *start, Tree *child)
    {
    	Stack *p1;
    	p1 = start->last;
    	int i = 1;
    	int j, k;
    	int flag = 0;
    	while (p1&&flag == 0)
    	{
    		//得到当前规约规则产生式左边的标号在后面产生式右边占有j个
    		//实际按语法规则 出现 A->B A->B C->A+A 的顺序是对的 不会出现 A->B  C->A+A A->B 的顺序
    		//A->B A->B A->B C->A+A D->A E->DC 那么第一条A->B的haveF为D->A (有待研究)
    		j = haveF[g[start->number][0] - 65][p1->number];
    		if (j>0)
    		{
    			for (k = 0; k<j&&flag == 0; k++)
    			{
    				i--;
    				if (i == 0)
    				{
    					flag = 1;
    					//如 找到p1:A->B child:带有id的leaf
    					addhaveF(child, p1);
    					guiYueOrderhead = guiYueOrderhead->last;
    					guiYueOrderhead->next = NULL;
    				}
    			}
    
    		}
    
    		if (flag == 0)
    		{
    			//中途遇到产生式左边与当前产生式左边一样的
    			if (g[p1->number][0] == g[start->number][0])
    			{
    				i++;
    			}
    			p1 = p1->last;
    		}
    
    	}
    	return guiYueOrderhead;
    }
    //构建语法分析树:语法树规约结束 从下往上建
    void newGrammarTree()
    {
    	Stack *ppp;
    	Tree *child;
    	//guiYueOrderhead一开始处于最底端 要不断的找他的last
    	while (guiYueOrderhead)
    	{
    		//第一条规约规则 当前guiYueOrderhead_haveF为root
    		if (guiYueOrderhead->number == 1)
    		{
    			root = guiYueOrderhead->haveF;
    			guiYueOrderhead = guiYueOrderhead->last;
    		}
    		else{
    			ppp = guiYueOrderhead;
    			//只有终结符的 创建leaf节点
    			if (guiYueOrderhead->flag == -1)
    			{
    				// B->id 创建一个leaf节点 里面存的是规约index和id的具体值
    				child = creatleaf(guiYueOrderhead);
    				//B->id 建完leaf节点要让leaf找到他的haveF,从当前的规约顺序guiYueOrderhead开始
    				guiYueOrderhead = findhaveF(guiYueOrderhead, child);
    			}
    			else
    			{
    				//如果是非终结符 A->B 
    				child = guiYueOrderhead->haveF;
    				guiYueOrderhead = findhaveF(guiYueOrderhead, child);
    			}
    		}
    		//guiYueOrderhead = guiYueOrderhead->last;
    		//guiYueOrderhead->next = NULL;
    	}
    }
    //前序遍历得到的序列 p1:语法树root h:节点
    Stack *creatGrammarTreePreOrder(Tree *p1, Stack *h)
    {
    	Stack *pp, *p2;
    	pp = (Stack*)malloc(sizeof(Stack));
    	pp->number = p1->number;
    	if (p1->bb)
    		strcpy(pp->bb, p1->bb);
    	pp->next = NULL;
    	if (h == NULL)
    	{
    		h = pp;
    	}
    	else h->next = pp;
    	if (p1->child[0])
    	{
    		p2 = creatGrammarTreePreOrder(p1->child[0], pp);
    		if (p1->child[1])
    		{
    			while (p2)
    			{
    				pp = p2;
    				p2 = p2->next;
    			}
    			p2 = creatGrammarTreePreOrder(p1->child[1], pp);
    			if (p1->child[2])
    			{
    				while (p2)
    				{
    					pp = p2;
    					p2 = p2->next;
    				}
    				p2 = creatGrammarTreePreOrder(p1->child[2], pp);
    				if (p1->child[3])
    				{
    					while (p2)
    					{
    						pp = p2;
    						p2 = p2->next;
    					}
    					p2 = creatGrammarTreePreOrder(p1->child[3], pp);
    				}
    			}
    		}
    	}
    
    	return h;
    }
    //具体的语义分析操作
    Stack *semanticsAnalysisDetail(Stack *h)
    {
    	int l1, l2, l3, t1, t, i;
    	char str1[128], str2[128];
    	Stack *p;
    	p = h;
    	h = h->next;
    	if (p->number == 9)
    	{
    		h = semanticsAnalysisDetail(h);
    		printf("%s=%s
    ", p->bb, str);
    	}
    	//if then
    	else if (p->number == 11)
    	{
    		L++;
    		l1 = L;
    		L++;
    		l2 = L;
    		h = semanticsAnalysisDetail(h);//继续往下
    		printf("if (%s) gt L%d
    gt L%d
    ", Bool, l2, l1);
    		printf("L%d:", l2);
    		grammarTreePreorderHead = semanticsAnalysisDetail(h);
    		printf("L%d:
    ", l1);
    	}
    	else if (p->number == 12)
    	{
    		L++;
    		l1 = L;
    		L++;
    		l2 = L;
    		L++;
    		l3 = L;
    		h = semanticsAnalysisDetail(h);
    		printf("if (%s) gt L%d
    gt L%d
    ", Bool, l2, l3);
    		printf("L%d:", l2);
    		h = semanticsAnalysisDetail(h);
    		printf("gt L%d
    ", l1);
    		printf("L%d:", l3);
    		h = semanticsAnalysisDetail(h);
    		printf("L%d:
    ", l1);
    	}
    	else if (p->number == 13)
    	{
    		L++;
    		l1 = L;
    		L++;
    		l2 = L;
    		L++;
    		l3 = L;
    		printf("
    L%d:", l1);
    		h = semanticsAnalysisDetail(h);
    		printf("if (%s) gt L%d
    gt L%d
    ", Bool, l2, l3);
    		printf("L%d:", l2);
    		h = semanticsAnalysisDetail(h);
    		printf("gt L%d
    ", l1);
    		printf("L%d:
    ", l3);
    	}
    	else if (p->number == 14)
    	{
    		h = semanticsAnalysisDetail(h);
    		strcpy(Bool, str);
    		str[0] = '<';
    		str[1] = '';
    		strcat(Bool, str);
    		h = semanticsAnalysisDetail(h);
    		strcat(Bool, str);
    	}
    	//str(全局)存的是addr 
    	else if (p->number == 15 || p->number == 17)
    	{
    
    		h = semanticsAnalysisDetail(h);
    		strcpy(str1, str);
    		h = semanticsAnalysisDetail(h);
    		strcpy(str2, str);
    		T++;
    		t1 = T;
    		str[0] = 't';
    		i = 1;
    		while (t1)
    		{
    			t = t1 % 10;
    			t1 = (t1 - t) / 10;
    			str[i] = t + 48;
    			i++;
    		}
    		str[i] = '';
    		if (p->number == 15)
    			printf("%s=%s+%s
    ", str, str1, str2);
    		else printf("%s=%s*%s
    ", str, str1, str2);
    	}
    	//赋值
    	else if (p->number == 16 || p->number == 18)
    	{
    		h = semanticsAnalysisDetail(h);
    	}
    	else if (p->number == 19 || p->number == 20)
    	{
    		strcpy(str, p->bb);
    	}
    	else if (p->number == 1 || p->number == 8)
    	{
    		h = semanticsAnalysisDetail(h); h = semanticsAnalysisDetail(h);
    	}
    	else if (p->number == 3 || p->number == 4 || p->number == 5 || p->number == 7 || p->number == 10)
    	{
    		h = semanticsAnalysisDetail(h);
    	}
    
    	return h;
    
    }
    //语义分析
    void semanticsAnalysis(){
    	grammarTreePreorderHead = creatGrammarTreePreOrder(root, grammarTreePreorderHead);
    	//该序列遍历: 相当于自顶向下分析
    	while (grammarTreePreorderHead)
    	{
    		grammarTreePreorderHead = semanticsAnalysisDetail(grammarTreePreorderHead);
    	}
    }
    int main(){
    	/*
    	读输入文件
    	*/
    	FILE *fp;
    	if ((fp = fopen("in.txt", "r")) == NULL)
    	{
    		printf("cannot open the file!
    ");
    		exit(0);
    	}
    	/*
    	初始化词法分析
    	*/
    	initMorphology();
    	/*
    	初始化语法分析表
    	*/
    	initGrammar();
    	/*
    	将输出写文件
    	*/
    	freopen("out.txt", "w", stdout);
    	/*
    	词法分析
    	*/
    	char ch;
    	printf("词法分析:
    ");
    	while (!feof(fp))
    	{
    		ch = fgetc(fp);
    		if (ch == '
    ')
    			line++;//行号
    		if (feof(fp))
    			break;
    		fseek(fp, -1L, 1);//读指针退一位 所以传入的是fp
    		if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'))
    		{
    			keyword(fp);
    		}
    		else
    		{
    			if (ch>'0'&&ch <= '9')
    			{
    				number(fp, 1);
    			}
    			else if (ch == '0')
    			{
    				ch = fgetc(fp);
    				ch = fgetc(fp);
    				if (ch == 'x' || ch == 'X')
    				{
    					number36(fp);
    				}
    				else
    				{
    					fseek(fp, -1L, 1);
    					number(fp, 1);
    				}
    			}
    			else
    			{
    				other(fp);
    			}
    		}
    	}
    	addWordNodeEnd();
    	printf("
    语法分析:
    ");
    	grammarAnalysis();
    	if (ok){//用于判断是否有文法错误
    		printf("
    语义分析:
    ");
    		noendNumToflag();
    		newGrammarTree();
    		semanticsAnalysis();
    	}
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    SOM 的两种算法
    moco响应结果浏览器访问乱码
    moco的启动及第一个demo
    IDEA 解决 terminal 中文乱码
    moco框架的下载
    ExtentReport测试报告的使用
    testNG超时测试
    testNG 多线程测试(xml文件实现)
    testNG @DataProvider参数化
    testNG xml文件参数化
  • 原文地址:https://www.cnblogs.com/france/p/5120576.html
Copyright © 2020-2023  润新知