商软二班 201506110170 何强
一、实验目的
通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,检查语法错误,进一步掌握常用的语法分析方法。
二、实验内容和要求
该程序要实现的是一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。
(1)关键字:
begin if then while do end 所有的关键字都是小写。
(2)运算符和界符
= + - * / < <= <> > >= = ; ( ) #
要把上面关键字和运算符转化种别码,下面为符号和种别码的对照表
三、实验方法、步骤及结果测试
代码:
#include <stdio.h> #include <string.h> char prog[80],token[8],ch; int syn,p,m,n,sum; char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner(void); main() { p=0; printf(" please input a string(end with '#'): "); do{ scanf("%c",&ch); prog[p++]=ch; }while(ch!='#'); p=0; do{ scaner(); switch(syn) { case 11: printf("( %-10d%5d ) ",sum,syn); break; case -1: printf("you have input a wrong string "); return 0; break; default: printf("( %-10s%5d ) ",token,syn); break; } }while(syn!=0); } void scaner(void) { sum=0; for(m=0;m<8;m++) token[m++]= NULL; ch=prog[p++]; m=0; while((ch==' ')||(ch==' ')) ch=prog[p++]; if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))) { while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) { token[m++]=ch; ch=prog[p++]; } p--; syn=10; for(n=0;n<6;n++) if(strcmp(token,rwtab[n])==0) { syn=n+1; break; } } else if((ch>='0')&&(ch<='9')) { while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0'; ch=prog[p++]; } p--; syn=11; } else { switch(ch) { case '<': token[m++]=ch; ch=prog[p++]; if(ch=='=') { syn=22; token[m++]=ch; } else { syn=20; p--; } break; case '>': token[m++]=ch; ch=prog[p++]; if(ch=='=') { syn=24; token[m++]=ch; } else { syn=23; p--; } break; case '+': token[m++]=ch; ch=prog[p++]; if(ch=='+') { syn=17; token[m++]=ch; } else { syn=13; p--; } break; case '-': token[m++]=ch; ch=prog[p++]; if(ch=='-') { syn=29; token[m++]=ch; } else { syn=14; p--; } break; case '!': ch=prog[p++]; if(ch=='=') { syn=21; token[m++]=ch; } else { syn=31; p--; } break; case '=': token[m++]=ch; ch=prog[p++]; if(ch=='=') { syn=25; token[m++]=ch; } else { syn=18; p--; } break; case '*': syn=15; token[m++]=ch; break; case '/': syn=16; token[m++]=ch; break; case '(': syn=27; token[m++]=ch; break; case ')': syn=28; token[m++]=ch; break; case ';': syn=26; token[m++]=ch; break; case '"': syn=30; token[m++]=ch; break; case '#': syn=0; token[m++]=ch; break; case ':': syn=17; token[m++]=ch; break; default: syn=-1; break; } } token[m++]=' '; }
运行结果及分析
因为
beign在对照表中对应的种别码为1,所以输出1;
以此类推,根据符号和种别码对照表,设置与符号和字符相对应的种别码。
#为终结符。
四、实验总结
通过与同学的交流,掌握了主要方法后发现其原理十分简单 ,但还是有点问题不能解决,例如end的种别码为6,单独输出没有问题,但和其他字符连着输出就会输出其他数字