词法分析
#include #include #include using namespace std; #define MAXN 20000 int syn,p,sum,kk,m,n,row; double dsum,pos; char index[800],len;//记录指数形式的浮点数 char r[6][10]={\"function\ char token[MAXN],s[MAXN]; char ch; bool is_letter(char c) { return c>='a' && c<='z' || c>='A' && c<='Z'; } bool is_digtial(char c) { return c>='0' && c<='9'; } bool is_dot(char c) { return c==',' || c==';'; } void identifier()//标示符的判断 { m=0; while(ch>='a' && ch<='z' || ch>='0' && ch<='9') { token[m++]=ch; ch=s[++p]; } token[m]='\\0'; ch=s[--p]; syn=10; for(n=0;n<6;n++) if(strcmp(token,r[n])==0) { syn=n+1; break; } } void digit(bool positive)//数字的判断 { len=sum=0; ch=s[p]; while(ch>='0' && ch<='9') { sum=sum*10+ch-'0'; ch=s[++p]; } if(ch=='.') { dsum=sum; ch=s[++p]; pos=0.1; while(ch>='0' && ch<='9') { dsum=dsum+(ch-'0')*pos; pos=pos*0.1; ch=s[++p]; } if(ch=='e') { index[len++]=ch; ch=s[++p]; if(ch=='-' || ch=='+') { index[len++]=ch; ch=s[++p]; } if(!(ch>='0' && ch<='9')) { syn=-1; } else { while(ch>='0' && ch<='9') { index[len++]=ch; ch=s[++p]; } } } if(syn==-1 || (ch>='a' && ch<='z') || ch=='.') { syn=-1;//对数字开头的标识符进行判错。 while(ch>='0' && ch<='9' || ch>='a' ch=s[++p];//找到下一次要判断的开头 ch=s[--p]; } else && ch<='z' ch=='.') || { ch=s[--p]; syn=12; if(!positive) dsum*=-1.0; } } else { if(ch>='a' && ch<='z') { syn=-1;//对数字开头的标识符进行判错。 while(ch>='0' && ch<='9' || ch>='a' && ch<='z') ch=s[++p];//找到下一次要判断的开头 ch=s[--p]; } else { ch=s[--p]; syn=11; if(!positive) sum*=-1; } } } bool check_behind_digit() { int i=p+1; while(s[i]!='\\0') { if(s[i]>='0' && s[i]<='9') return true; else if(s[i]!=' ' && s[i]!='\' && s[i]!='\\n') return false; i++; } return false; } bool check_pre_prog() { int i=p-1; while(i>=0) { if(s[i]!=' ' && s[i]!='\' && s[i]!='\\n') { if(s[i]>='0' && s[i]<='9' || s[i]>='a' && s[i]<='z') return false; else return true; } i--; } return true; } void pot() { while(1) { ch=s[++p]; if(ch=='\\n') row++; if(!(ch==' ' || ch=='\' || ch=='\\n')) break; } } void scaner() { memset(token,0,sizeof(token)); pot(); //cout< if(is_letter(ch)) { syn=10; identifier(); } else if(is_digtial(ch)) { syn=11; digit(true); } else { if(ch=='<') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=22; token[len++]=s[p+1]; p++; } else syn=20; } else if(ch=='>') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=24; token[len++]=s[p+1]; p++; } else syn=23; } else if(ch=='=') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=25; token[len++]=s[p+1]; p++; } else syn=18; } else if(ch=='!') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=22; token[len++]=s[p+1]; p++; } else syn=-1; } else if(ch=='+') { if(check_behind_digit() && check_pre_prog()) { ++p; pot(); digit(true); syn=12; } else { syn=13; token[0]=ch; } } else if(ch=='-') { if(check_behind_digit() && check_pre_prog()) { ++p; pot(); digit(false); syn=12; } else { syn=13; token[0]=ch; } } else if(ch=='*') syn=15,strcpy(token,\"*\"); else if(ch=='/') syn=16,strcpy(token,\"/\"); else if(ch==';') syn=26,strcpy(token,\";\"); else if(ch=='(') syn=27,strcpy(token,\"(\"); else if(ch==')') syn=28,strcpy(token,\")\"); else if(ch=='#') syn=0,strcpy(token,\"#\"); } //cout< int main() { int i,j; p=0; row=1; cout<<\"请选择输入方式,按0表示键盘输入,按1表示文件输入\"< if(i) freopen(\"1.txt\ else printf(\"\\nPlease input the string:\\n\"); do{ scanf(\"%c\ s[++p]=ch; }while(ch!='#'); s[0]='#'; cout< printf(\"种别码单词符号\\n\"); do{ scaner(); switch(syn) { case 11:printf(\"(%-3d ,%d)\\n\ case 12: { printf(\"\\n(%d,%lf\ if(len) { for(i=0;i } printf(\")\\n\"); break;//实数输出 } case -1:printf(\"(第%d行,error!)\\n\ default:printf(\"(%-3d ,%s)\\n\ } }while(syn!=0); //printf(\"词法分析成功!请按任意键结束\\n\"); return 0; } /* function a=9; x=2*4; b=a+x; endfunc # x=a+b*c; endfunc # function x=a+b*c; # function a=(a+b)/c; x=(x+y)*(a+b)+c+d*(a+c)+(a+f)+(d-g); endfunc # function a=(a+b)/c; x=(x+y)*(a+b)+c+d*(a+c)+(a+f)+(d-g); b=(a*c+4)*9; endfunc # */ 语法分析 #include #include #include #include using namespace std; #define MAXN 20000 int syn,p,sum,kk,m,n,row,error; double dsum,pos; char index[800],len;//记录指数形式的浮点数 char r[6][10]={\"function\ char token[MAXN],s[MAXN]; char ch; bool is_letter(char c) { return c>='a' && c<='z' || c>='A' && c<='Z'; } bool is_digtial(char c) { return c>='0' && c<='9'; } bool is_dot(char c) { return c==',' || c==';'; } void identifier()//标示符的判断 { m=0; while(ch>='a' && ch<='z' || ch>='0' && ch<='9') { token[m++]=ch; ch=s[++p]; } token[m]='\\0'; ch=s[--p]; syn=10; for(n=0;n<6;n++) if(strcmp(token,r[n])==0) { syn=n+1; break; } } void digit(bool positive)//数字的判断 { len=sum=0; ch=s[p]; while(ch>='0' && ch<='9') { sum=sum*10+ch-'0'; ch=s[++p]; } if(ch=='.') { dsum=sum; syn=12; ch=s[++p]; pos=0.1; while(ch>='0' && ch<='9') { dsum=dsum+(ch-'0')*pos; pos=pos*0.1; ch=s[++p]; } if(ch=='e') { index[len++]=ch; ch=s[++p]; if(ch=='-' || ch=='+') { index[len++]=ch; ch=s[++p]; } if(!(ch>='0' && ch<='9')) { //cout<<\"Looooooooooook\"< } else { while(ch>='0' && ch<='9') { index[len++]=ch; ch=s[++p]; } } } if(syn==-1 || (ch>='a' && ch<='z') || ch=='.') { syn=-1;//对数字开头的标识符进行判错。 while(ch>='0' && ch<='9' || ch>='a' && ch<='z' || ch=='.') ch=s[++p];//找到下一次要判断的开头 ch=s[--p]; } else { ch=s[--p]; syn=12; if(!positive) dsum*=-1.0; } } else { if(ch>='a' && ch<='z') { syn=-1;//对数字开头的标识符进行判错。 while(ch>='0' && ch<='9' || ch>='a' && ch<='z') ch=s[++p];//找到下一次要判断的开头 ch=s[--p]; } else { ch=s[--p]; syn=11; if(!positive) sum*=-1; } } } void To_double() { int i; printf(\"(%d,%lf\ if(len) { for(i=0;i } printf(\")\\n\"); } bool check_behind_digit() { int i=p+1; while(s[i]!='\\0') { if(s[i]>='0' && s[i]<='9') return true; else if(s[i]!=' ' && s[i]!='\' && s[i]!='\\n') return false; i++; } return false; } bool check_pre_prog() { int i=p-1; while(i>=0) { if(s[i]!=' ' && s[i]!='\' && s[i]!='\\n') { if(s[i]>='0' && s[i]<='9' || s[i]>='a' && s[i]<='z') return false; else return true; } i--; } return true; } void pot() { while(1) { ch=s[++p]; if(ch=='\\n') row++; if(!(ch==' ' || ch=='\' || ch=='\\n')) break; } } void scaner() { memset(token,0,sizeof(token)); pot(); if(is_letter(ch)) { syn=10; identifier(); } else if(is_digtial(ch)) { digit(true); } else { if(ch=='<') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=22; token[len++]=s[p+1]; p++; } else syn=20; token[len]=0; } else if(ch=='>') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=24; token[len++]=s[p+1]; p++; } else syn=23; token[len]=0; } else if(ch=='=') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=25; token[len++]=s[p+1]; p++; } else syn=18; token[len]=0; } else if(ch=='!') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=22; token[len++]=s[p+1]; p++; } else syn=-1; } else if(ch=='+') { if(check_behind_digit() && check_pre_prog()) { pot(); digit(true); } else { syn=13; token[0]=ch; } } else if(ch=='-') { if(check_behind_digit() && check_pre_prog()) { pot(); digit(false); } else { syn=13; token[0]=ch; } } else if(ch=='*') syn=15,strcpy(token,\"*\"); else if(ch=='/') syn=16,strcpy(token,\"/\"); else if(ch==';') syn=26,strcpy(token,\";\"); else if(ch=='(') syn=27,strcpy(token,\"(\"); else if(ch==')') syn=28,strcpy(token,\")\"); else if(ch=='#') syn=0,strcpy(token,\"#\"); } //cout< void factor()//因子分析函数 { void expression(); if(syn==10 || syn==11 || syn==12)//变量或是数字常量 scaner(); else//是否是表达式 { if(syn==27)//'(' { scaner(); expression(); if(syn==28)// ')' scaner(); else { printf(\"error! need another ')'\");// 表示缺少了')' kk=1; } } else { //cout< printf(\"error! expression error!\"); } } } void term()//项分析函数 { factor(); while(syn==15 || syn==16)// '*' or '/' { scaner(); factor(); } } void expression()//表达式分析函数 { term(); while(syn==13 || syn==14)// '+' or '-' { scaner(); term(); } } void statement()//语句 { if(syn==10)//表示变量 { scaner(); if(syn==18)//表示赋值语句 { scaner(); expression();//赋值表达式 } else { printf(\"error! evaluate tag error\\n\"); kk=1; } } } void yucu()//语句串分析 { statement();//调用语句分析函数 while(syn==26)//以;为语句结束的表示进行解析 { scaner();//读出 statement();//句式分析 } } void lrparser()//词法分析主要函数 { if(syn==1)//找到函数入口关键字function { scaner(); yucu(); if(syn==6) { printf(\"Success!\\n\"); kk=1; } } else { cout<<\"error ! 不能找到第一个函数入口关键子function\"< } if(kk!=1) { //cout< if(syn==0) return; } void Lrparser() { if(error) { cout<<\"语义分析:Failed\"< } cout<<\"语义分析:\"; p=0; scaner(); lrparser(); } int parse()//词法分析 { error=0; p=0; printf(\"种别码单词符号\\n\"); do{ scaner(); switch(syn) { case 11:printf(\"(%-3d ,%d)\\n\ case 12:To_double();break;//实数输出 case -1:printf(\"(第%d行,error!)\\n\ default:printf(\"(%-3d ,%s)\\n\ } }while(syn!=0); printf(\"词法分析完成!共有%d errors\\n\ return error; } void INPUT() { int i,j; p=0; row=1; cout<<\"请选择输入方式,按0表示键盘输入,按1表示文件输入\"< cout<<\"请选择文件输出,按3表示文件输出,安4表示标准输出\"< if(i==1) freopen(\"1.txt\ if(j==3) freopen(\"2.txt\ else printf(\"\\nPlease input the string:\\n\"); do{ scanf(\"%c\ s[++p]=ch; }while(ch!='#'); } int main() { INPUT(); parse(); Lrparser(); return 0; } /* function a=9; x=2*4; b=a+x; a=0.13413e-1234; c=+0.24e+13; endfunc # x=a+b*c; endfunc # function x=a+b*c; # function a=(a+b)/c; x=(x+y)*(a+b)+c+d*(a+c)+(a+f)+(d-g); endfunc # function a=(a+b)/c; x=(x+y)*(a+b)+c+d*(a+c)+(a+f)+(d-g); b=(a*c+4)*9; endfunc # */ 语义分析 #include #include #include #include #include #include using namespace std; #define MAXN 20000 const double eps=1e-7; struct Q{ char res[100]; char ag1[100]; char op[12]; char ag2[100]; }q[300];//保存最后的结果三地址指令格式 int count=0,error;//记录结果集的条数 int syn,p,sum,kk,m,n,row,k,len; double dsum,pos; char index[800];//记录指数形式的浮点数 char r[6][10]={\"function\ char token[MAXN],s[MAXN]; char ch; bool is_letter(char c) { return c>='a' && c<='z' || c>='A' && c<='Z'; } bool is_digtial(char c) { return c>='0' && c<='9'; } bool is_dot(char c) { return c==',' || c==';'; } void identifier()//标示符的判断 { m=0; while(ch>='a' && ch<='z' || ch>='0' && ch<='9') { token[m++]=ch; ch=s[++p]; } token[m]='\\0'; ch=s[--p]; syn=10; for(n=0;n<6;n++) if(strcmp(token,r[n])==0) { syn=n+1; break; } } void digit(bool positive)//数字的判断 { len=sum=0; ch=s[p]; while(ch>='0' && ch<='9') { sum=sum*10+ch-'0'; ch=s[++p]; } if(ch=='.') { dsum=sum; syn=12; ch=s[++p]; pos=0.1; while(ch>='0' && ch<='9') { dsum=dsum+(ch-'0')*pos; pos=pos*0.1; ch=s[++p]; } if(ch=='e') { index[len++]=ch; ch=s[++p]; if(ch=='-' || ch=='+') { index[len++]=ch; ch=s[++p]; } if(!(ch>='0' && ch<='9')) { //cout<<\"Looooooooooook\"< } else { while(ch>='0' && ch<='9') { index[len++]=ch; ch=s[++p]; } } } if(syn==-1 || (ch>='a' && ch<='z') || ch=='.') { syn=-1;//对数字开头的标识符进行判错。 while(ch>='0' && ch<='9' || ch>='a' ch=s[++p];//找到下一次要判断的开头 ch=s[--p]; } else { ch=s[--p]; && ch<='z' ch=='.') || syn=12; if(!positive) dsum*=-1.0; } } else { if(ch>='a' && ch<='z') { syn=-1;//对数字开头的标识符进行判错。 while(ch>='0' && ch<='9' || ch>='a' && ch<='z') ch=s[++p];//找到下一次要判断的开头 ch=s[--p]; } else { ch=s[--p]; syn=11; if(!positive) sum*=-1; } } } void To_double() { int i; printf(\"(%d,%lf\ if(len) { for(i=0;i } printf(\")\\n\"); } bool check_behind_digit() { int i=p+1; while(s[i]!='\\0') { if(s[i]>='0' && s[i]<='9') return true; else if(s[i]!=' ' && s[i]!='\' && s[i]!='\\n') return false; i++; } return false; } bool check_pre_prog() { int i=p-1; while(i>=0) { if(s[i]!=' ' && s[i]!='\' && s[i]!='\\n') { if(s[i]>='0' && s[i]<='9' || s[i]>='a' && s[i]<='z') return false; else return true; } i--; } return true; } void pot() { while(1) { ch=s[++p]; if(ch=='\\n') row++; if(!(ch==' ' || ch=='\' || ch=='\\n')) break; } } void scaner() { memset(token,0,sizeof(token)); pot(); if(is_letter(ch)) { syn=10; identifier(); } else if(is_digtial(ch)) { digit(true); } else { if(ch=='<') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=22; token[len++]=s[p+1]; p++; } else syn=20; token[len]=0; } else if(ch=='>') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=24; token[len++]=s[p+1]; p++; } else syn=23; token[len]=0; } else if(ch=='=') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=25; token[len++]=s[p+1]; p++; } else syn=18; token[len]=0; } else if(ch=='!') { len=0,token[len++]=ch; if(s[p+1]=='=') { syn=22; token[len++]=s[p+1]; p++; } else syn=-1; } else if(ch=='+') { if(check_behind_digit() && check_pre_prog()) { pot(); digit(true); } else { syn=13; token[0]=ch; } } else if(ch=='-') { if(check_behind_digit() && check_pre_prog()) { pot(); digit(false); } else { syn=13; token[0]=ch; } } else if(ch=='*') syn=15,strcpy(token,\"*\"); else if(ch=='/') syn=16,strcpy(token,\"/\"); else if(ch==';') syn=26,strcpy(token,\";\"); else if(ch=='(') syn=27,strcpy(token,\"(\"); else if(ch==')') syn=28,strcpy(token,\")\"); else if(ch=='#') syn=0,strcpy(token,\"#\"); } //cout< void parse()//词法分析 { error=0; p=0; printf(\"种别码单词符号\\n\"); do{ scaner(); switch(syn) { case 11:printf(\"(%-3d ,%d)\\n\ case 12:To_double();break;//实数输出 case -1:printf(\"(第%d行,error!)\\n\ default:printf(\"(%-3d ,%s)\\n\ } }while(syn!=0); cout<<\"共发现\"< void INPUT() { int i,j; p=0; row=1; /*cout<<\"请选择输入方式,按0表示键盘输入,按1表示文件输入\"< cout<<\"请选择文件输出,按3表示文件输出,安4表示标准输出\"< if(i==1) freopen(\"1.txt\ if(j==3) freopen(\"2.txt\ else printf(\"\\nPlease input the string:\\n\");*/ do{ scanf(\"%c\ s[++p]=ch; }while(ch!='#'); } bool equalzero(double a) { return fabs(a-0.0)<=eps?true:false; } void swap(char &a,char &b) { char t=b; b=a,a=t; } void DOUBLE_change() { int i; int Len=0; int DD=int(dsum); dsum-=DD; for(i=0;DD;i++) { token[i]=DD%10+'0'; DD/=10; } Len=i; for(i=0;i token[Len++]='.'; do{ dsum*=10; i=int(dsum); dsum-=i; token[Len++]=i+'0'; }while(!equalzero(dsum)); token[Len]=0; index[len]=0; strcat(token,index); cout< char *expression(); void emit(char *res,char *ag1,char *op,char *ag2) { strcpy(q[count].res,res); strcpy(q[count].ag1,ag1); strcpy(q[count].op,op); strcpy(q[count++].ag2,ag2); }//保存结果集函数 char *newtemp()//中间变量ti { char *pp; char m[100]; pp=(char*)malloc(100); k++; itoa(k,m,10);//k 表示第几个变量t的下标 strcpy(pp+1,m); pp[0]='t'; return pp; } char *factor() { char *fplace; fplace=new char(100); strcpy(fplace,\"\"); if(syn==10)//变量token { strcpy(fplace,token); scaner(); } else if(syn==11)//整形常量 { itoa(sum,fplace,10); scaner(); } else if(syn==12)//实数 { DOUBLE_change(); //cout< scaner(); } else if(syn==27)//表示遇到了'(' { scaner(); fplace=expression();//括号里面的一定是表达式 if(syn==28)//遇到了下一个')' scaner(); else { cout<<\"\\n')' error\"< } } else { printf(\"\\n'(' error\"); kk=1; } return fplace; } char *term() { char *tp,*ep2,*eplace,*tt; tp=new char(100); ep2=new char(100); eplace=new char(100); tt=new char(100); strcpy(eplace,factor()); while(syn==15 || syn==16)//表示{ if(syn==15) { tt[0]='*'; tt[1]=0; } else if(syn==16) { * or / tt[0]='/'; tt[1]=0; } scaner(); strcpy(ep2,factor()); strcpy(tp,newtemp()); emit(tp,eplace,tt,ep2); strcpy(eplace,tp); } return eplace; } char *expression() { char *tp,*ep2,*eplace,*tt; tp=new char(100); ep2=new char(100); eplace=new char(100); tt=new char(100); strcpy(eplace,term()); while(syn==13 || syn==14)//表示+ - { if(syn==13) { tt[0]='+'; tt[1]=0; } else if(syn==14) { tt[0]='-'; tt[1]=0; } scaner(); strcpy(ep2,term()); strcpy(tp,newtemp()); emit(tp,eplace,tt,ep2); strcpy(eplace,tp); } return eplace; } int statement() { char tt[100],eplace[100]; int schain=0; if(syn==10)//变量标示符 { strcpy(tt,token); scaner(); if(syn==18) { scaner(); strcpy(eplace,expression()); emit(tt,eplace,\"\ schain=0; } else { printf(\"\\n缺少赋值号\\n\"); kk=1; } } return schain; } int yucu()//主要的语法分析函数 { int schain=0; schain=statement(); while(syn==26) { scaner(); schain=statement(); } return schain; } int lrparser() { int schain=0; kk=0; p=0; scaner(); if(syn==1) { scaner(); schain=yucu(); if(syn==6)//遇到了endfunc { scaner(); if(syn==0 && kk==0) printf(\"\\n语法,语义分析成功\"); } else { if(kk!=1) { /*cout< kk=1; } } } else { printf(\"\\n缺function\\n\"); kk=1; } return schain; } void LRPARSER() { if(error) return; cout<<\"请按任意键,进行语义分析\"< lrparser(); if(kk!=0) { printf(\"语法分析失败,程序终止!\\n\"); return ; } printf(\"\\n三地址指令如下:\\n\"); for(int i=0;i int main() { INPUT(); parse(); LRPARSER(); return 0; } /* function a=2+3*4; x=(a+b+e+g)/(c+d); endfunc # function a=2.0+4.0*5.0; b=+2.024343e-24*+134.3145e+11++34143.341e+1; endfunc # function a=9; x=2*4; b=a+x; a=0.13413e-1234; c=+0.24e+13; endfunc # function a=2+3*4; x=(a+b+c)/(c+D); x=3h; endfunc # function x=a+b+c+d*(e+f)*(g+h)/c/d/e/f+d; y=1+2*3*4*(a+b+c+d+e+f+z)/r/q-y-(t-0)/a*u; y=1+2*3*4*(a+b+c+d+e+f+z)/r/q-y-(t-0)/a*u; y=1+2*3*4*(a+b+c+d+e+f+z)/r/q-y-(t-0)/a*u; y=1+2*3*4*(a+b+c+d+e+f+z)/r/q-y-(t-0)/a*u; endfunc # function if(x>0) then y=12; endfunc # */ 因篇幅问题不能全部显示,请点此查看更多更全内容p=0;printf(\"\\n缺endfunc\\n\");
}