编译实践

来源:互联网 发布:软件加注册码工具 编辑:程序博客网 时间:2024/05/17 01:46

每次由不同组员编写 未整合故无关联
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    endend.

词法分析 _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放入listStr2 *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表示accint 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表示accgt[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 numbervoid 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;        }    }}//移入或规约时产生的pushvoid 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;}//规约时状态栈产生的popvoid popstack(int i){    int j = Number[i];    while (j--)    {        stackHead = stackHead->next;    }    stackHead->last = NULL;}//规约时符号栈产生的popvoid 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的haveFvoid 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的haveFStack *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;}
0 0
原创粉丝点击