france

https://github.com/francecil

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

每次由不同组员编写 未整合故无关联
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=='\n'){
		   lineIndex++;
	   }
  }while(ch==' ' || ch=='\n' || ch=='\t');//读到不是空格、换行及制表符
 
  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]='\0';
       token[i]='\0';
       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!='\n')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\n" ,translate(token[j]));
			   k++;
	   }
       if (num > MAXNUM){
			token[0]='\0';
			syn=ERROR_SYN;error_index=1;
//		   printf("error\n");
		   //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]='\0';
       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]='\0';
		 //转换成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]='\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]='\0';

           break;

       case '+':                        /*识别‘+’(编号13)*/

           syn=13;

           token[i++]='+';

           token[i]='\0';

           break;

       case '-':                        /*识别‘-’(编号14)*/

           syn=14;

           token[i++]='-';

           token[i]='\0';

           break;

       case '*':                        /*识别‘*’(编号15)*/

           syn=15;

           token[i++]='*';

           token[i]='\0';

           break;

       case '/':                        /*识别‘/’(编号16)*/

           syn=16;

           token[i++]='/';

           token[i]='\0';

           break;

       case ':':

           token[i++]=':';

           ch=front(&prog);

           switch(ch)

           {

           case '=':                   /*识别‘:=’(编号18)*/

                syn=18;

                token[i++]='=';

                token[i]='\0';

                dequeue(&prog);

                break;

           default:                    /*识别‘:’(编号17)*/

                syn=17;

                token[i]='\0';

                break;

           }

           break;

       case '<':

           token[i++]='<';

           ch=front(&prog);

           switch(ch)

           {

           case '>':                   /*识别‘<>’(编号21)*/

                syn=21;

                token[i++]='>';

                token[i]='\0';

                dequeue(&prog);

                break;

           case '=':                   /*识别‘<=’(编号22)*/

                syn=22;

                token[i++]='=';

                token[i]='\0';

                dequeue(&prog);

                break;

           default:                    /*识别‘<’(编号20)*/

                syn=20;

                token[i]='\0';

                break;

           }

           break;

       case '>':

           token[i++]='>';

           ch=front(&prog);

           switch(ch)

           {

           case '=':                   /*识别‘>=’(编号24)*/

                syn=24;

                token[i++]='=';

                token[i]='\0';

                dequeue(&prog);

                break;

           default:                    /*识别‘>’(编号23)*/

                syn=23;

                token[i]='\0';

                break;

           }

           break;

       case '=':                        /*识别‘=’(编号25)*/

           syn=25;

           token[i++]='=';

           token[i]='\0';

           break;

       case ';':                        /*识别‘;’(编号26)*/

           syn=26;

           token[i++]=';';

           token[i]='\0';

           break;

       case '(':                        /*识别‘(’(编号27)*/

           syn=27;

           token[i++]='(';

           token[i]='\0';

           break;

       case ')':                        /*识别‘)’(编号28)*/

           syn=28;

           token[i++]=')';

           token[i]='\0';

           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中查看输出\n\n");
  char *argv[]={"E:/ofname.txt","input.txt","out.txt"};
//w+ 存在则清空内容,否则新建文件 
       if(!(in=fopen(argv[1],"r+")))
       {
		   
           printf("请在input.txt中输入内容!(结束符为#)\n");
           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]!='\0');
				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('\n',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=='\n'||ch=='\t'||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=='\n'||ch=='\t'||ch==' ')
				state=23;
			break;
		case 23:{ch=arr[i++];forward++;}	
			if(ch=='\n'||ch=='\t'||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("输入的字符串以结束$\n");
	
	fputs("输入的字符串以结束$\n",out);
	
	in[val]='$';
	printf("%s",in);
	printf("\n");
	fputs(in,out);
	fputs("\n",out);
	i=0;j=0;
	list1.push_back(0);//push_back() //增加一元素到链表尾
	char n,c;
	int m,st,len;
	printf("栈              符号                      输入                     动作 \n"); 
    fputs("栈                                   符号                                    输入                                                     动作 \n",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("移入\n");
			fputs("移入\n",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规约\n",creat[m]);
			fputs("根据",out);
			fputs(creat[m],out);
		    fputs("规约\n",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("\n%d\n",st);
            //printf("\n%d\n",flag);
			list2.push_back(c);
			m=slr1[st][flag]/100;

			list1.push_back(m);
		}
		else if(slr1[st][flag]==30)
		{ 
			printf("接受\n");
			fputs("接受\n",out);
			break;
		}
		else if(slr1[st][flag]==0)
		{
			printf("\n");
			fputs("\n",out);
            printf("%s",table[j-1]);
			fputs(table[j-1],out);
			printf("%s ",table[j]);
			fputs(table[j],out);
			printf("ERROR\n");
			fputs("ERROR\n",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>\n",temp);
					     fputs("<",out);
						 fputs(temp,out);
						 fputs(" keyword>\n",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>\n",temp);
					 fputs("<",out);
						 fputs(temp,out);
						 fputs(" id>\n",out);
					strcpy(table[val],temp);
					in[val++]='i';}
            }break;
		case 2:
		 	printf("<%s num>\n",temp);
			fputs("<",out);
			fputs(temp,out);
		    fputs(" num>\n",out);
			strcpy(table[val],temp);
			in[val++]='n';			 
			break;
		case 3:
		 	printf("<%s division>\n",temp);
			fputs("<",out);
			fputs(temp,out);
		    fputs(" division>\n",out);
			 strcpy(table[val],temp);
			in[val++]=temp[0];			
			break;
		case 4:
			printf("<%s relation>\n",temp);
			fputs("<",out);
			fputs(temp,out);
		    fputs(" relation>\n",out);
		    strcpy(table[val],temp);
			in[val++]=temp[0];
			break;
		case 5: 
			    
			printf("<%s operator>\n",temp);
			fputs("<",out);
			fputs(temp,out);
		    fputs(" operator>\n",out);
			strcpy(table[val],temp);
			in[val++]=temp[0];	
			
			break;
		case 6:
			 	printf("<%s ERROR>\n",temp);
				fputs("<",out);
		    	fputs(temp,out);
		        fputs(" ERROR>\n",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\n", 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\n", 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] = '\0';
	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 == '\n')
			line++;
		instring[n++] = ch;
	} while ((ch >= '0'&&ch <= '9') || (ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'));
	fseek(fp, -1L, 1);
	instring[--n] = '\0';
	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\n", line);
	//加入number
	addWordNode(97 + 19, instring);
}
void other(FILE *fp)
{
	int endIndex = 0;
	char ch = fgetc(fp);
	if (ch == ' ' || ch == '\n' || ch == '\t')
		endIndex = -2;
	char s[3];
	s[0] = ch;
	if (ch == ':')
	{
		ch = fgetc(fp);
		if (ch == '=')
		{
			s[1] = ch; s[2] = '\0';
		}
		else
		{
			endIndex = -1;
		}
	}
	else
	{
		s[1] = '\0';
	}
	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("\n addheadstr s:%s\n", 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("移入\n");
		else if (t == 2) printf("归约%s\n", 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("接受\n");
}
//由词法单元去执行语法分析,得到一个规约顺序(实验二为直接输出)
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\n", 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("\nerror!\n");
				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\n", 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\ngt L%d\n", Bool, l2, l1);
		printf("L%d:", l2);
		grammarTreePreorderHead = semanticsAnalysisDetail(h);
		printf("L%d:\n", l1);
	}
	else if (p->number == 12)
	{
		L++;
		l1 = L;
		L++;
		l2 = L;
		L++;
		l3 = L;
		h = semanticsAnalysisDetail(h);
		printf("if (%s) gt L%d\ngt L%d\n", Bool, l2, l3);
		printf("L%d:", l2);
		h = semanticsAnalysisDetail(h);
		printf("gt L%d\n", l1);
		printf("L%d:", l3);
		h = semanticsAnalysisDetail(h);
		printf("L%d:\n", l1);
	}
	else if (p->number == 13)
	{
		L++;
		l1 = L;
		L++;
		l2 = L;
		L++;
		l3 = L;
		printf("\nL%d:", l1);
		h = semanticsAnalysisDetail(h);
		printf("if (%s) gt L%d\ngt L%d\n", Bool, l2, l3);
		printf("L%d:", l2);
		h = semanticsAnalysisDetail(h);
		printf("gt L%d\n", l1);
		printf("L%d:\n", l3);
	}
	else if (p->number == 14)
	{
		h = semanticsAnalysisDetail(h);
		strcpy(Bool, str);
		str[0] = '<';
		str[1] = '\0';
		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] = '\0';
		if (p->number == 15)
			printf("%s=%s+%s\n", str, str1, str2);
		else printf("%s=%s*%s\n", 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!\n");
		exit(0);
	}
	/*
	初始化词法分析
	*/
	initMorphology();
	/*
	初始化语法分析表
	*/
	initGrammar();
	/*
	将输出写文件
	*/
	freopen("out.txt", "w", stdout);
	/*
	词法分析
	*/
	char ch;
	printf("词法分析:\n");
	while (!feof(fp))
	{
		ch = fgetc(fp);
		if (ch == '\n')
			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("\n语法分析:\n");
	grammarAnalysis();
	if (ok){//用于判断是否有文法错误
		printf("\n语义分析:\n");
		noendNumToflag();
		newGrammarTree();
		semanticsAnalysis();
	}
	fclose(stdout);
	return 0;
}
posted on 2016-01-11 11:21  france  阅读(549)  评论(0编辑  收藏  举报