编译原理词法分析

来源:互联网 发布:淘宝中介处理 编辑:程序博客网 时间:2024/05/01 12:25
/*编译原理实验一:词法分析练习作者:lqf时间:2013-9-28 */#include <stdio.h>#include <conio.h>#include <string.h>#define TOKENMAX 100#define PROGMAX 1000 #define K_ESC   27void analytics();      //词法分析void scanner();        //输入扫描bool isLetter(char ch);//判断字符是否为字母 bool isDigit(char ch);//判断字符是否为数字bool concat(char token[],char ch);//将ch连接在token后面 int reserve(char token[]);//对token中字符串查关键字表,若是关键字返回其编码,否则返回标识符种别码10double ezhishu(int x,double e);//求以e为底的指数bool isZheng11();//11正规式判断,判断是否是(+|-)d+(.d+)(ed+)的科学计数//全局变量char prog[PROGMAX],token[TOKENMAX];char ch;int syn,ptrp,ptrt;//ptrp是缓冲区prog的指针//ptrt是token的指针double sum;char *rwtab[6]={"begin","if","then","while","do","end"};int main(){int key=0;do{fflush(stdin);//清空输入流analytics();printf("\n按Esc退出,其他键继续...\n");if(!kbhit()){key=getch();}}while(key!=K_ESC);return 0; } //输入字符串并进行词法分析,返回二元组 void analytics(){ptrp=0;printf("请输入字符串,以#结尾:\n");do{ch=getchar();prog[ptrp++]=ch;}while(ch!='#');ptrp=0;do{scanner();switch(syn){case 1:printf("(%2d,%8s)\n",syn,token);break;case 2:printf("(%2d,%8s)\n",syn,token);break;case 3:printf("(%2d,%8s)\n",syn,token);break;case 4:printf("(%2d,%8s)\n",syn,token);break;case 5:printf("(%2d,%8s)\n",syn,token);break;case 6:printf("(%2d,%8s)\n",syn,token);break;case 10:printf("(%2d,%8s)\n",syn,token);break;case 11:printf("(%2d,%lg)\n",syn,sum);break;case 13:printf("(%2d,%8s)\n",syn,token);break;case 14:printf("(%2d,%8s)\n",syn,token);break;case 15:printf("(%2d,%8s)\n",syn,token);break;case 16:printf("(%2d,%8s)\n",syn,token);break;case 17:printf("(%2d,%8s)\n",syn,token);break;case 18:printf("(%2d,%8s)\n",syn,token);break;case 20:printf("(%2d,%8s)\n",syn,token);break;case 21:printf("(%2d,%8s)\n",syn,token);break;case 22:printf("(%2d,%8s)\n",syn,token);break;case 23:printf("(%2d,%8s)\n",syn,token);break;case 24:printf("(%2d,%8s)\n",syn,token);break;case 25:printf("(%2d,%8s)\n",syn,token);break;case 26:printf("(%2d,%8s)\n",syn,token);break;case 27:printf("(%2d,%8s)\n",syn,token);break;case 28:printf("(%2d,%8s)\n",syn,token);break;case 0:break;//#case -1:printf("输入有误!");break;default:printf("(%2d,%8s)\n",syn,token);}}while(syn!=0 && syn!=-1);}void scanner(){int n;for(n=0;n<TOKENMAX;n++) token[n]=NULL;ch=prog[ptrp++];n=0;while((ch==32 || ch==10) && n++<PROGMAX)ch=prog[ptrp++];if(isLetter(ch)){//文法10int temp=ptrp;while(isDigit(ch) || isLetter(ch)){concat(token,ch);ch=prog[ptrp++];}ptrp--;for (n=0;n<6;n++){         if(strcmp(token,rwtab[n])==0)           {                switch(n){              case 0:syn=1;return;case 1:syn=2;return;case 2:syn=3;return;case 3:syn=4;return;case 4:syn=5;return;    case 5:syn=6;return;}   }       }if(temp<=ptrp){syn=10;return;}     }   else{if(isDigit(ch)){  int temp=ptrp;if(isZheng11()){syn=11;return;}ptrp=temp;}switch(ch){case '<':ptrt=0;token[ptrt++]=ch;ch=prog[ptrp++];if (ch=='>'){  syn=21;    token[ptrt++]=ch;}else if (ch=='='){  syn=22;    token[ptrt++]=ch;    }else{ syn=20;ptrp--;}break;case '>':ptrt=0;token[ptrt++]=ch;ch=prog[ptrp++];if (ch=='='){  syn=24;    token[ptrt++]=ch;}else{ syn=23;ptrp--;}break;case '+':ptrt=0;token[ptrt++]=ch;ch=prog[ptrp++];if(isDigit(ch)){if(isZheng11()){syn=11;return;}}else{syn=13; token[0]='+';ptrp--; return;}case '-':ptrt=0;token[ptrt++]=ch;ch=prog[ptrp++];if(isDigit(ch)){if(isZheng11()){syn=11;sum-=2*sum;return;}}else{syn=14; token[0]='-';ptrp--; return;}case '*':syn=15; token[0]=ch; return;case '/':syn=16; token[0]=ch; return;case ':':ptrt=0;token[ptrt++]=ch;ch=prog[ptrp++];if (ch=='='){  syn=18;    token[ptrt++]=ch;}else{ syn=17;ptrp--;}return;case '(':syn=27; token[0]=ch; return;case ';':syn=26; token[0]=ch; return;case '=':syn=25; token[0]=ch; return;case ')':syn=28; token[0]=ch; return;case '#':syn=0;  token[0]=ch; return;default:     syn= -1;  token[0]=ch;return ;}   } }bool isLetter(char ch){return ((ch >64 && ch <91) || (ch >96 && ch <123));}bool isDigit(char ch){return (ch >47 && ch <58);}bool concat(char token[],char ch){int i=0;while(i< TOKENMAX){if(token[i] == NULL){token[i]=ch;return true;}i++;}return false;}bool isZheng11(){int temp1=ptrp;int temp2=ptrp;sum=0;while(isDigit(ch)){sum=sum*10+ch-'0';ch=prog[ptrp++];}temp1=--ptrp;if(ch=='.'){//xiaoshuch=prog[++temp1];double dot=0.1;while(isDigit(ch)){sum=(ch-'0')*dot+sum;ch=prog[++temp1];dot*=0.1;}if(ch=='e'){//kexuech=prog[++temp1];temp2=temp1;int tempsum=0;if(isDigit(ch)){while(isDigit(ch)){tempsum=10*tempsum+ch-'0';//sum=sum*ezhishu((ch-'0'),10);ch=prog[++temp1];}if(temp2<temp1){sum=sum*ezhishu(tempsum,10);ptrp=temp1;return true;}ch='e';}else if(ch=='+'){ch=prog[++temp1];temp2=temp1;int tempsum=0;while(isDigit(ch)){tempsum=tempsum*10+ch-'0';//sum=sum*ezhishu(ch-'0',10);ch=prog[++temp1];}if(temp2<temp1){sum=sum*ezhishu(tempsum,10);ptrp=temp1;return true;}ch='+';}else if(ch=='-'){ch=prog[++temp1];temp2=temp1;int tempsum=0;while(isDigit(ch)){tempsum=tempsum*10+ch-'0';//sum=sum*ezhishu(ch-'0',0.1);ch=prog[++temp1];}if(temp2<temp1){sum=sum*ezhishu(tempsum,0.1);ptrp=temp1;return true;}ch='-';}else{}ptrp=temp2-1;}else if(temp1>=ptrp){ptrp=temp1;return true;}else{}}else if(ch=='e'){//kexue jishuch=prog[++temp1];temp2=temp1;int tempsum=0;if(isDigit(ch)){while(isDigit(ch)){tempsum=10*tempsum+ch-'0';//sum=sum*ezhishu((ch-'0'),10);ch=prog[++temp1];}if(temp2<temp1){sum=sum*ezhishu(tempsum,10);ptrp=temp1;return true;}ch='e';}else if(ch=='+'){ch=prog[++temp1];temp2=temp1;int tempsum=0;while(isDigit(ch)){tempsum=tempsum*10+ch-'0';//sum=sum*ezhishu(ch-'0',10);ch=prog[++temp1];}if(temp2<temp1){sum=ezhishu(tempsum,10)*sum;ptrp=temp1;return true;}ch='+';}else if(ch=='-'){ch=prog[++temp1];temp2=temp1;while(isDigit(ch)){sum=sum*ezhishu(ch-'0',0.1);ch=prog[++temp1];}if(temp2<temp1){ptrp=temp1;return true;}ch=temp1-2;ch='-';}else{}ch='e';}else{//zhengshu}return true;}double ezhishu(int x,double e){double sum=1;for(;x-->0;sum*=e);return sum;}

编译原理课后练习,词法分析的题目。要求分析一个科学计数的正规式,实在不会化简,就直接写了
原创粉丝点击