编译原理 实验一 词法分析
实验一 词法分析
【实验目的】
(1)熟悉词法分析器的基本功能和设计方法;
(2)掌握状态转换图及其实现;
(3)掌握编写简单的词法分析器方法。
【实验内容】
对一个简单语言的子集编制一个一遍扫描的词法分析程序。
【实验要求】
(1)待分析的简单语言的词法
1) 关键字 begin if then while do end
2) 运算符和界符 := + - * / < <= <> > >= = ; ( ) #
3) 其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义:
ID=letter(letter|digit)*
NUM=digitdigit*
4) 空格由空白、制表符和换行符组成。空格一般用来分隔 ID、NUM、运算符、界符和 关键字,词法分析阶段通常被忽略。
(2)各种单词符号对应的种别编码
(3)词法分析程序的功能
输入:所给文法的源程序字符串
输出:二元组(syn,token 或 sum)构成的序列。
syn 为单词种别码;
token 为存放的单词自身字符串;
sum 为整形常数。
【实验代码】
1 #include<iostream> 2 #include<string.h> 3 #include<conio.h> 4 #include<ctype.h> 5 using namespace std; 6 int sum,syn,p,m,n; 7 char ch,chs[8],s[100]; 8 char *tab[6]={"begin","if","then","while","do","end"}; 9 10 int scanner(){ 11 for(n=0;n<8;n++) chs[n]='\0'; 12 m=0; 13 n=0; 14 ch=s[p++]; 15 while(ch==' ') ch=s[p++]; 16 if(isalpha(ch)){ 17 while(isalpha(ch)||isdigit(ch)){ 18 //isalpha(ch)函数:判断字符ch是否为英文字母,小写字母为2,大写字母为1,若不是字母0 19 //isdigit(ch)函数:判断字符ch是否为数字,是返回1,不是返回0 20 chs[m++]=ch; 21 ch=s[p++]; 22 } 23 syn=10; 24 for(n=0;n<6;n++) 25 if(strcmp(chs,tab[n])==0) syn=n+1; 26 p--; 27 }else if(isdigit(ch)){ 28 sum=0; 29 while(isdigit(ch)){ 30 sum=sum*10+(ch-'0'); 31 ch=s[p++]; 32 } 33 syn=11; 34 p--; 35 }else if(ch==':'){ 36 syn=17; 37 chs[m++]=ch; 38 ch=s[p++]; 39 if(ch=='='){ syn=18;chs[m]=ch;p++;} 40 p--; 41 }else if(ch=='<'){ 42 syn=20; 43 chs[m++]=ch; 44 ch=s[p++]; 45 if(ch=='>') { syn=21;chs[m]=ch;p++;} 46 if(ch=='=') { syn=22;chs[m]=ch;p++;} 47 p--; 48 }else if(ch=='>'){ 49 syn=23; 50 chs[m++]=ch; 51 ch=s[p++]; 52 if(ch=='=') { syn=24;chs[m]=ch;p++;} 53 p--; 54 }else switch(ch){ 55 case '+':syn=13;chs[m]=ch;break; 56 case '-':syn=14;chs[m]=ch;break; 57 case '*':syn=15;chs[m]=ch;break; 58 case '/':syn=16;chs[m]=ch;break; 59 case '=':syn=25;chs[m]=ch;break; 60 case ';':syn=26;chs[m]=ch;break; 61 case '(':syn=27;chs[m]=ch;break; 62 case ')':syn=28;chs[m]=ch;break; 63 case '#':syn=0;chs[m]=ch;break; 64 default:syn=-1; 65 } 66 return 0; 67 } 68 int main(){ 69 p=0; 70 cout<<"Please input code and end with character '#':"<<endl; 71 do{ 72 //cin>>ch;不识别空格 73 ch=getchar(); 74 s[p++]=ch; 75 }while(ch!='#'); 76 p=0; 77 do{ 78 scanner(); 79 switch(syn){ 80 case 11:cout<<'('<<syn<<','<<sum<<')'<<endl;break; 81 case -1:cout<<'('<<syn<<','<<"error"<<')'<<endl;break; 82 default:cout<<'('<<syn<<','<<chs<<')'<<endl; 83 } 84 }while(syn!=0); 85 //getch():是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车,所在头文件是conio.h。 86 return 0; 87 }
【实验结果】