编译实践
来源:互联网 发布:软件加注册码工具 编辑:程序博客网 时间: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
- 编译实践
- CVM编译实践笔记
- CVM编译实践笔记
- CVM编译实践笔记
- Linux内核编译实践
- 实践编译 Firefox Fennec
- autotool编译实践
- 编译安装tomcat实践
- [实践]CEGUI-0.87编译
- busybox静态编译及动态编译实践
- 每日编译的入门实践
- Ant ------java编译Application 实践
- Platform Builder实践之编译
- Platform Builder实践之编译
- Linux2.6 内核编译实践
- Platform Builder实践之编译
- 编译原理及实践1
- 海思SDK编译实践 -- hi3716cv200es1
- jquery以及js中那些好用的函数
- Wix Toolset总结
- 关于getch()的一点小知识
- 山顶点的提取
- Redis的三种启动方式
- 编译实践
- App架构设计经验谈:接口的设计
- MAC地址和IP地址
- 在centos6.3用yum安装redis
- <二> Qt更新sqlite3插件
- 开源免费哈希值校验工具Quickhash V2.6.5
- APP上架被拒原因—持续更新
- IOS---Sqlite的详细使用方法
- eclipse运行程序显示the user operation is waiting for "building workspace" to complete