实验一、词法分析实验
商业软件工程专业 李梓维 201506110105
一、 实验目的
通过设计一个词法分析程序,对词法进行分析,加强对词法的理解,掌握对程序设计语言的分解和理解。
二、 实验内容和要求
在原程序中输入源代码
- 对字符串表示的源程序
- 从左到右进行扫描和分解
- 根据词法规则
- 识别出一个一个具有独立意义的单词符号
- 以供语法分析之用
- 发现词法错误,则返回出错信息
在源程序中,自动识别单词,把单词分为五种,并输出对应的单词种别码。
- 识别关键字:main if int for while do return break continue,该类的单词码为1.
- 识别标识符:表示各种名字,如变量名、数组名、函数名等,如char ch, int syn, token,sum,该类的单词码为2.
- 运算符:+、-、*、/、=、>、<、>=、<=、!=
- 分隔符:,、;、{、}、(、)
- 常数,如123,4587
各种单词符号对应的种别码:
输出形式:
- 二元式
– (单词种别,单词自身的值)
- 单词种别,表明单词的种类,语法分析需要的重要信息
– 整数码
- 关键字、运算符、界符:一符一码
- 标识符:10, 常数:11
- 单词自身的值
– 标识符token、常数sum
– 关键字、运算符、界符token
一、 实验方法、步骤及结果测试
1.源程序名:编译原理 实验报告 中源程序名 算法分析.c
可执行程序名:编译原理 实验报告.exe
2.原理分析及流程图
3.程序代码
1 #include<stdio.h> 2 #include<string.h> 3 void F(char c,char b); 4 void word(char a[]); 5 void number(char a[]); 6 int i; //定义全局变量i 7 int s=1; //用来记录是否存在非法字符 8 main(){ 9 char a[50]; 10 printf("请输入需要分析的字符串:"); 11 gets(a); 12 printf("您要分析的字符串为:"); 13 printf("%s",a); 14 printf("\n"); 15 for(i=0;(a[i]!='\0')&&(i<50)&&s==1;i++){ 16 if((a[i]>='a' && a[i]<='z')||(a[i]>='A' && a[i]<='Z')) 17 word(a); 18 else if(a[i]>='0' && a[i]<='9') 19 number(a); 20 else 21 F(a[i],a[i+1]); 22 } 23 printf("\n"); 24 } 25 26 void number(char a[]) //对数字字符进行扫描分析 27 { 28 char b[50]; 29 int m,k=0,t; 30 m=i; 31 while(a[m]>='0' && a[m]<='9') 32 { 33 b[k]=a[m]; //用数组b存放数组a中的数字 34 k++; 35 m++; 36 } 37 i=m-1; 38 printf("(11,"); 39 for(t=0;t<k;t++) 40 printf("%c",b[t]); 41 printf(")"); 42 printf("\n"); 43 } 44 45 void word(char a[]) //对字母字符进行扫描分析,并识别保留字 46 { 47 int k=0,m,flag=0,t; 48 char b[50]; 49 char *key[6]={"begin","if","then","while","do","end"}; 50 m=i; 51 while((a[m]>='a'&&a[m]<='z')||(a[m]>='A'&&a[m]<='Z')) //用数组b存放数组a中的字母 52 { 53 b[k]=a[m]; 54 k++; 55 m++; 56 b[k]='\0'; 57 } 58 i=m-1; 59 for(t=0;t<6;t++) 60 { 61 if(strcmp(b,key[t])==0) //将数组b与关键字进行比较 62 { 63 printf("(%d,%s)",t+1,key[t]); //输出关键字 64 flag=1; 65 printf("\n"); 66 } 67 } 68 if(flag==0) 69 { 70 printf("(10,%s)",b); //输出标识符 71 printf("\n"); 72 } 73 } 74 void F(char c,char b) //对特殊字符进行扫描分析 75 { 76 switch(c){ 77 case '+': 78 printf("(13,+)\n"); 79 break; 80 81 case '-': 82 printf("(14,-)\n"); 83 break; 84 85 case '*': 86 printf("(15,*)\n"); 87 break; 88 89 case '/': 90 printf("(16,/)\n"); 91 break; 92 93 case ':': 94 if(b=='=') 95 { 96 i++; 97 printf("(18,:=)\n"); 98 } 99 else 100 printf("(17,:)\n"); 101 break; 102 103 case ' ': 104 break; 105 106 case '<': 107 if(b=='>') 108 { 109 i++; 110 printf("(21,<>)\n"); 111 } 112 else if(b=='=') 113 { 114 i++; 115 printf("(22,<=)\n"); 116 } 117 else 118 printf("(20,<)\n"); 119 break; 120 121 case '>': 122 if(b=='=') 123 { 124 printf("(24,>=)\n"); 125 i++; 126 } 127 else 128 printf("(23,>)\n"); 129 break; 130 131 case '=': 132 printf("(25,=)\n"); 133 break; 134 135 case ';': 136 printf("(26,;)\n"); 137 break; 138 139 case '(': 140 printf("(27,()\n"); 141 break; 142 143 case ')': 144 printf("(28,))\n"); 145 break; 146 147 case '#': 148 printf("(0,#)\n"); 149 break; 150 151 152 default: 153 { 154 printf("\n存在字符 '%c',无法继续识别!\n",c); 155 s=0; //用s=0记录存在非法字符 156 break; 157 } 158 } 159 }
4.运行结果
二.实验总结
通过存储输入的字符串,用循环的方式逐个提取出来与种别码比较,然后进行输出。
本人觉得该实验难点在于如何让程序自动识别“ ”与“#”等特殊方式,以及循环的跳出条件,此实验使我对代码的理解更加的深刻。