当前位置:文档之家› S语言词法分析器设计

S语言词法分析器设计

实验1-3 S语言词法分析器设计一、实验名称:S语言词法分析器设计二、实验目的:通过手工编写简化C语言词法分析器,熟悉并深入理解编译程序词法分析器的工作原理。

三、实验容:1.根据保留字和特殊符号表能区分出源文件中的保留字、普通标识符和特殊符号,并能进行简单的错误处理。

2.设计词法分析器模块调用结构图和各模块流程图。

3.程序源代码。

4.程序的执行结果:输入文件,输出结果文件及屏幕信息。

四、实验中出现的问题及解决方法。

遇到问题及解决:1、关于注释//和除号/。

需要区分,在isanotation函数中。

2、关于遇到空格时回退,一开始没有懂,后来经过同学讲解,明白了如何回退的。

3、关于词法分析器的思想过程,经过老师再三讲解,已经大致明白,具体步骤,在最后体会部分中。

五、程序结构和代码程序结构:代码:#include<stdio.h>#include<stdlib.h>#include<string>#include<iostream>using namespace std;//关键字表stringkeywords[20]={"include","void","main","int","c har","float","double","if","else","then","break"," continue","for","do","while","printf","scanf","be gin","end","return"};char aa[99999]=" ";//关键字表初始为空string id[10000];int pp=0;//常数表string nu[10000];int qq=0;//初始化函数void initscanner(){int i=0;FILE *fp;if((fp=fopen("源程序.txt","r"))==NULL)//打开源程序文件{printf("没有找到此文件!");exit(0);}char ch=fgetc(fp);while(ch!=EOF){aa[i]=ch;i++;ch=fgetc(fp);}fclose(fp);}int decide1(char a) //判断是否是字母{if((a>='a'&&a<='z')||(a>='A'&&a<='Z')) return 1;else return 0;}int decide2(char a) //判断是否是数字{if(a>='0'&&a<='9')return 1;else return 0;}int isalpha(int st) //识别保留字和标识符{char wordbuf[20]=" ";int n=0;for( ; ; ){wordbuf[n]=aa[st];st++;n++; if((decide2(aa[st])==1)||(decide1(aa[st])==1)||( aa[st]=='_'))wordbuf[n]=aa[st];else break;}int flag=0;for(int k=0;k<20;k++){if(strcmp(keywords[k].c_str(),wordbuf)==0) flag=1;}if(flag==0){int flagg=-1;for(int t=0;t<pp;t++){if(strcmp(id[t].c_str(),wordbuf)==0){flagg=t;}}if(flagg!=-1) printf(" (id,%d) ",flagg);else{id[pp]=wordbuf;printf(" (id,%d) ",pp);pp++;}}else{printf(" (");for(int i=0;i<n;i++){printf("%c",wordbuf[i]);}printf(",-) ");}return st;}int isnumber(int st) //识别数字{char numbuf[20]=" ";int n=0;int k=0;int flag=0;for( ; ; ){numbuf[n]=aa[st];st++;n++;if(decide2(aa[st])==1){numbuf[n]=aa[st];}else if((k==0)&&(aa[st]=='.')){numbuf[n]=aa[st];k++;}else if(decide1(aa[st])==1){numbuf[n]=aa[st];flag=1;continue;}else break;}if(flag==0){int flagg=-1;for(int t=0;t<qq;t++)if(strcmp(nu[t].c_str(),numbuf)==0)flagg=t;if(flagg!=-1) printf(" (nu,%d) ",flagg); else{nu[qq]=numbuf;printf(" (nu,%d) ",qq);qq++;}}else{printf(" (");for(int i=0;i<n;i++) printf("%c",numbuf[i]); printf(",错误) ");} return st;}int isanotation(int st) //处理除号/和注释{char tabuf[9999]=" ";int n=0;st++;if(aa[st]=='/'){printf(" (//,-) ");st++;while(aa[st]!=10){tabuf[n]=aa[st];st++;n++;}printf(" (");for(int i=0;i<n;i++)printf("%c",tabuf[i]);printf(",注释容) ");}else if(aa[st]=='*'){printf(" (/*,-) ");st++;int stt=st+1;while(1){if(aa[st]=='*'&&aa[st+1]=='/') break; tabuf[n]=aa[st];st++;n++;if(aa[st+1]==NULL){printf("(/* 错误\n)");return st+1;}} printf(" (");for(int i=0;i<n;i++)printf("%c",tabuf[i]);printf(",注释容) ");printf(" (*/,-) ");st=st+2;}else if(aa[st]=='='){st++;printf(" (/*,-) ");}else printf(" (/,-) ");return st;}int isother(int st) //函数识别其他特殊字符{switch(aa[st]){case '=': st++;if(aa[st]=='='){st++;printf(" (rlop,==) ");}else printf(" (rlop,=) ");break;case '+': st++;if(aa[st]=='='){st++;printf(" (+=,-) ");}else if(aa[st]=='+'){st++;printf(" (++,-) ");}else printf(" (+,-) ");break;case '-': st++;if(aa[st]=='='){st++;printf(" (-=,-) ");}else if(aa[st]=='-'){st++;printf(" (--,-) "); }else printf(" (-,-) "); break;case '*': st++;if(aa[st]=='='){st++;printf(" (*=,-) ");}else printf(" (*,-) "); break;case '>': st++;if(aa[st]=='='){st++;printf(" (rlop,>=) ");}else printf(" (rlop,>) "); break;case '<': st++;if(aa[st]=='='){st++;printf(" (rlop,<=) ");}else printf(" (rlop,<) "); break;case '%': st++;if(aa[st]=='='){st++;printf(" (\%=,-) ");}else printf(" (\%,-) "); break;case '!': st++;if(aa[st]=='='){st++;printf(" (!=,-) ");}else printf(" (!,错误!) "); break;case '&': st++;if(aa[st]=='&'){st++;printf(" (&&,-) ");}else printf(" (&,错误) "); break;case '|': st++;if(aa[st]=='|'){st++;printf(" (||,-) ");}else printf(" (|,错误) "); break;case '{': st++;printf(" ({,-) "); break;case '}': st++;printf(" (},-) "); break;case '(': st++;printf(" ((,-) "); break;case ')': st++;printf(" (),-) "); break;case '[': st++;printf(" ([,-) "); break;case ']': st++;printf(" (],-) "); break;case ':': st++;printf(" (:,-) "); break;case '#': st++;printf(" (#,-) "); break;case ';': st++;printf(" (;,-) "); break;case '.': st++;printf(" (.,-) "); break;case ',': st++;printf(" (,,-) ");break;case ' ': st++;break;case ' ': st++;break;case 10: st++;printf("\n");break;case 34: st++;printf(" (\",-) ");break;case 39: st++;printf(" (',-) ");break;default: printf(" (%c,错误) ",aa[st]);st++;}return st;}int lexscan(int st) //根据读入的单词的第一个字符确定调用不同的单词识别函数{if(decide1(aa[st])==1)//如果是字母st=isalpha(st);else if(decide2(aa[st])==1)//如果是数字st=isnumber(st);else if(aa[st]=='/')//如果是标识符或关键字st=isanotation(st);else st=isother(st);//其他特殊字符return st;}void scanner() //若文件未结束,反复调用lexscan函数识别单词{int i=0;while(aa[i]!=NULL)i=lexscan(i);}void print(){cout<<endl;cout<<endl<<"关键字、标示符表如下:"<<endl;cout<<"======================== ====================="<<endl;for(int i=0;i<pp;i++)cout<<i<<" "<<id[i]<<endl;cout<<"======================== ====================="<<endl; cout<<endl;cout<<"常数表如下:"<<endl;cout<<"======================== ====================="<<endl; for(int j=0;j<qq;j++)cout<<j<<" "<<nu[j]<<endl;cout<<"======================== ====================="<<endl;}void main(){ cout<<"二元式流如下:"<<endl;cout<<"======================== ====================="<<endl; initscanner();scanner();print();}程序执行结果截图:源程序截图:。

相关主题