能识别浮点数的简单词法分析程序(C语言实现)
此词法分析程序能够识别基本字、标识符、有符号整数、有符号浮点数、运算符和界符)。
仅作交流,希望能抛砖引玉,获得更为简洁有效的词法分析程序。
输入:所给文法的源程序字符串。(字符串以“#”号结束)
输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。
例如:控制台输入beginx:=9: if x>9 then x:=2*x+1/3;end #,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……
例如:控制台输入zzz123+-1234.56e-123+1+-2#,经过词法分析后输出:
(10,zzz123)(13,+)(11,-1.23456e-120)(11,1)(13,+)(11,-2)(0,#)
实现截图:
源代码:
#include<stdio.h> #include<string.h> #include<math.h> char prog[80]; //存放所有输入字符 char token[8]; //存放词组 char ch; //单个字符 int syn,p,m,n; //syn:种别编码 double sum; int count; int isSignal; //是否带正负号(0不带,1负号,2正号) int isDecimal; //是否是小数 double decimal; //小数 int isExp; //是否是指数 int index; //指数幂 int isNegative; //是否带负号 double temp; int temp2; int repeat; void scanner(); char *rwtab[6]={"begin","if","then","while","do","end"}; void main() { p=0; count=0; isDecimal=0; index=0; repeat=0; printf("\n Please input string:\n"); do{ ch=getchar(); prog[p++]=ch; }while(ch!='#'); //输入以#号键结束 p=0; do{ scanner(); //扫描,单词 switch(syn) { case 11: if(isDecimal==0) { //加了1个强制类型转换 printf("(%2d,%8d)\n",syn,(int)sum); break; } else if(isExp==1) { printf("(%2d,%10.5e)\n",syn,sum); isExp=0; isDecimal=0; break; } else if(isDecimal==1) { printf("(%2d,%8.4f)\n",syn,sum); isDecimal=0; break; } case -1: printf("input error\n"); break; default: printf("(%2d,%8s)\n",syn,token); } }while(syn!=0); getch(); } void scanner() { sum=0; decimal=0; m=0; for(n=0;n<8;n++) token[n]=NULL; ch=prog[p++]; //从prog中读出一个字符到ch中 while(ch==' ') //跳过空字符(无效输入) ch=prog[p++]; if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))) //ch是字母字符 { while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||((ch>='0')&&(ch<='9'))) { token[m++]=ch; //ch=>token ch=prog[p++]; //读下一个字符 } token[m++]='\0'; p--; //回退一格 syn=10; //标识符 //如果是"begin","if","then","while","do","end"标识符中的一个 for(n=0;n<6;n++) if(strcmp(token,rwtab[n])==0) { syn=n+1; break; } } else if((ch>='0')&&(ch<='9')) { IsNum: if(isSignal==1) { //token[m++]='-'; } while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0'; //ch中数字本身是当做字符存放的 ch=prog[p++]; } if(ch=='.') { isDecimal=1; ch=prog[p++]; count=0; //之前忘了清零,123.123+123.123#两个浮点数就无法识别 while((ch>='0')&&(ch<='9')) { //pow(x,y)计算x的y次幂 temp=(ch-'0')*pow(0.1,++count); decimal=decimal+temp; //AddToDec(); ch=prog[p++]; } sum=sum+decimal; } if(ch=='e'||ch=='E') { isExp=1; ch=prog[p++]; if(ch=='-') { isNegative=1; ch=prog[p++]; } while((ch>='0')&&(ch<='9')) { //指数 index=index*10+ch-'0'; ch=prog[p++]; } //10的幂 //123e3代表123*10(3) //sum=sum*pow(10,index);是错误的 if(isNegative) sum=sum*pow(0.1,index); else sum=sum*pow(10,index); } if(isSignal==1) { sum=-sum; isSignal=0; } p--; syn=11; } else switch(ch) { case '<': m=0; token[m++]=ch; ch=prog[p++]; if(ch=='>') { syn=21; //<>对应21 token[m++]=ch; } else if(ch=='=') { syn=22; token[m++]=ch; } else { syn=20; p--; } break; case '>': m=0; token[m++]=ch; ch=prog[p++]; if(ch=='=') { syn=24; token[m++]=ch; } else { syn=23; p--; } break; case ':': m=0; token[m++]=ch; ch=prog[p++]; if(ch=='=') { syn=18; token[m++]=ch; } else { syn=17; p--; } break; case '+': temp2=prog[p]; token[m++]=ch; if((temp2>='0')&&(temp2<='9')&&(repeat==1)) { isSignal=2; //isSignal正数 ch=prog[p++]; repeat=0; goto IsNum; } if(((temp2=='+')||(temp2=='-'))&&(repeat==0)) //如果重复出现符号,才将后边的+,-视为正负号 { repeat=1; //ch=prog[p++]; } syn=13; break; case '-': temp2=prog[p]; token[m++]=ch; if((temp2>='0')&&(temp2<='9')&&(repeat==1)) { isSignal=1; ch=prog[p++]; //读“-”下一个字符 repeat=0; goto IsNum; //转到数字的识别 } if(((temp2=='+')||(temp2=='-'))&&(repeat==0)) //如果重复出现符号,才将后边的+,-视为正负号 { repeat=1; //预言会重复 //ch=prog[p++]; //读下一个字符 } syn=14; break; case '*': temp2=prog[p]; token[m++]=ch; if(temp2=='+') { isSignal=2; repeat=1; } else if(temp2=='-') { isSignal=1; repeat=1; } syn=24; break; case '/': syn=16; token[m++]=ch; break; case '=': syn=25; token[m++]=ch; break; case ';': syn=26; token[m++]=ch; break; case '(': temp2=prog[p]; token[m++]=ch; if(temp2=='+') { isSignal=2; repeat=1; } else if(temp2=='-') { isSignal=1; repeat=1; } syn=27; break; case ')': syn=28; token[m++]=ch; break; case'#': syn=0; token[m++]=ch; break; default: syn=-1; } }