词法分析实验报告
实验一、词法分析实验
专业 商业软件工程
姓名 黄施策
学号 201506110228
一、 实验目的
编制一个词法分析程序。
二、 实验内容和要求
输入:源程序字符串
输出:二元组(种码,单词符号本身)。
三、 实验方法、步骤及结果测试
- 1. 源程序名:词法分析.c
可执行程序名:词法分析.exe
- 2. 原理分析及流程图
主要总体设计问题。
(包括存储结构,主要算法,关键函数的实现等)
- 3. 主要程序段及其解释:
实现主要功能的程序段,重要的是程序的注释解释。
1 #include<stdio.h> 2 3 #include<string.h> 4 5 #define N 100 6 7 void priint(char str[],int i,int semp[]); 8 9 void pristring(char str[],int i,int semp[]); 10 11 void prichar(char str[],int i,int semp[]); 12 13 void main() 14 15 { 16 17 int i; 18 19 int temp; 20 21 char str[N]; 22 23 int semp[N]={0}; /*此数组用来标记str字符串里每个成员是否已进行分析,已分析为1,否则为0*/ 24 25 printf("输入您需要进行词法分析的源程序:"); 26 27 gets(str); 28 29 temp=strlen(str); /*temp所储存的是输入的字符串的长度*/ 30 31 for(i=0;i<temp;i++) 32 33 { /*利用ASCII码对字符进行分类并进入各自对应的函数*/ 34 35 if((semp[i]==0)&&(str[i-1]<48||str[i-1]>57)&&(str[i]>=48&&str[i]<=57)){ 36 37 priint(str,i,semp);}/*数字*/ 38 39 if((semp[i]!=1)&&((str[i]>=65&&str[i]<=90)||(str[i]>=97&&str[i]<=122))){ 40 41 pristring(str,i,semp);}/*字母*/ 42 43 if((semp[i]!=1)&&((str[i]>=32&&str[i]<=47)||(str[i]>=58&&str[i]<=64)||(str[i]>=91&&str[i]<=96)||(str[i]>=123&&str[i]<=126))){ 44 45 prichar(str,i,semp);}/*符号*/ 46 47 } 48 49 } 50 51 52 53 void priint(char str[],int i,int semp[]) 54 55 { 56 57 char strtemp[N]={'\0'}; 58 59 int j,k; 60 61 for(j=0;j<N;j++) 62 63 { 64 65 if(str[i]<48||str[i]>57) break; 66 67 strtemp[j]=str[i]; 68 69 semp[i]=1; 70 71 i++; 72 73 } 74 75 printf("<11,"); 76 77 k=0; 78 79 do{ 80 81 printf("%c",strtemp[k]); 82 83 k++; 84 85 }while(strtemp[k]!='\0'); 86 87 printf(">\n"); 88 89 strnset(strtemp,'\0',N);/*将字符串strtemp的前N个字符都设为指定字符'\0'*/ 90 91 } 92 93 94 95 void pristring(char str[],int i,int semp[]) 96 97 { 98 99 int j=0; 100 101 int k; 102 103 char gechar[N]; 104 105 char *tempp[10]={"begin","if","then","while","do","end"}; /*二维字符数组*/ 106 107 do{ 108 109 gechar[j]=str[i]; 110 111 semp[i]=1; 112 113 i++; 114 115 j++; 116 117 }while((semp[i]!=1)&&((str[i]>=65&&str[i]<=90)||(str[i]>=97&&str[i]<=122))); 118 119 if(strcmp(gechar,tempp[0])==0) {printf("<1,begin>");} /*strcmp功能:对两字符进行比较,相同返回0,不同则为其他数*/ 120 121 else if(strcmp(gechar,tempp[1])==0) {printf("<2,if>");} 122 123 else if(strcmp(gechar,tempp[2])==0) {printf("<3,then>");} 124 125 else if(strcmp(gechar,tempp[3])==0) {printf("<4,while>");} 126 127 else if(strcmp(gechar,tempp[4])==0) {printf("<5,do>");} 128 129 else if(strcmp(gechar,tempp[5])==0) {printf("<6,end>");} 130 131 else { 132 133 printf("<10,"); 134 135 for(k=0;k<j;k++) 136 137 { 138 139 printf("%c",gechar[k]); 140 141 } 142 143 printf(">\n"); 144 145 } 146 147 strnset(gechar,'\0',N); 148 149 } 150 151 152 153 void prichar(char str[],int i,int semp[]) 154 155 { 156 157 char gchar=str[i]; 158 159 switch(gchar) 160 161 { 162 163 case '+':printf("<13,%c>\n",gchar);semp[i]=1;break; 164 165 case '-':printf("<14,%c>\n",gchar);semp[i]=1;break; 166 167 case '*':printf("<15,%c>\n",gchar);semp[i]=1;break; 168 169 case '/':printf("<16,%c>\n",gchar);semp[i]=1;break; 170 171 case ':': 172 173 if(str[i+1]!='='){ 174 175 printf("<17,%c>\n",gchar); 176 177 semp[i]=1; 178 179 } 180 181 else if(str[i+1]=='='){ 182 183 printf("<18,%c%c>\n",gchar,str[i+1]); 184 185 semp[i]=1; 186 187 semp[i+1]=1; 188 189 } 190 191 break; 192 193 case '<': 194 195 if((str[i+1]!='=')&&(str[i+1]!='>')){ 196 197 printf("<20,%c>\n",gchar); 198 199 semp[i]=1; 200 201 } 202 203 else if(str[i+1]=='='){ 204 205 printf("<21,%c%c>\n",gchar,str[i+1]); 206 207 semp[i]=1; 208 209 semp[i+1]=1; 210 211 } 212 213 else if(str[i+1]=='>'){ 214 215 printf("<22,%c%c>\n",gchar,str[i+1]); 216 217 semp[i]=1; 218 219 semp[i+1]=1; 220 221 } 222 223 break; 224 225 case '>': 226 227 if(str[i+1]!='='){ 228 229 printf("<23,%c>\n",gchar); 230 231 semp[i]=1; 232 233 } 234 235 else if(str[i+1]=='='){ 236 237 printf("<24,%c%c>\n",gchar,str[i+1]); 238 239 semp[i]=1; 240 241 semp[i+1]=1; 242 243 } 244 245 break; 246 247 case '=': 248 249 if((str[i-1]!='<')&&(str[i-1]!=':')&&(str[i-1]!='>')){ 250 251 printf("<25,%c>\n",gchar); 252 253 semp[i]=1; 254 255 } 256 257 break; 258 259 case ';':printf("<26,%c>\n",gchar);semp[i]=1;break; 260 261 case '(':printf("<27,%c>\n",gchar);semp[i]=1;break; 262 263 case ')':printf("<28,%c>\n",gchar);semp[i]=1;break; 264 265 case '#':printf("<0,%c>\n",gchar);semp[i]=1;break; 266 267 default:printf("<非法字符,%c>\n",gchar);semp[i]=1; break; /*对种码表里没有的符号都默认为非法字符*/ 268 269 } 270 271 }
- 4. 运行结果及分析
四、 实验总结
词法分析文法不熟练,还需多加练习,巩固提高。