当前位置:文档之家› 编译原理词法分析器实验报告

编译原理词法分析器实验报告

北华航天工业学院《编译原理》课程实验报告课程实验题目:词法分析器实验作者所在系部:计算机科学与工程系作者所在专业:计算机科学与技术作者所在班级:B08512作者学号:18作者姓名:李桂丁指导教师姓名:李建义完成时间:2010年3月26日一、实验目的了解词法分析程序的两种设计方法:1.根据状态转换图直接编程的方式;2.利用DFA 编写通用的词法分析程序。

二、实验内容及要求1.根据状态转换图直接编程编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。

在此,词法分析程序作为单独的一遍,如下图所示。

具体任务有:(1)组织源程序的输入(2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件(3)删除注释、空格和无用符号(4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。

将错误信息输出到屏幕上。

(5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。

标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。

常量表结构:常量名,常量值2.能对任何S语言源程序进行分析在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。

3.能检查并处理某些词法分析错误词法分析程序能给出的错误信息包括:总的出错个数,每个错误所在的行号,错误的编号及错误信息。

4. 本实验要求处理以下两种错误(编号分别为1,2):1:非法字符:单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。

2:源程序文件结束而注释未结束。

注释格式为:/* …… */三、实验程序设计说明1.实验方案设计2.程序源代码#include<stdio.h>#include<stdlib.h>#include<string>#include<iostream>using namespace std;stringkeywords[20]={"include","void","main","int","char","float","double","if","else","then","break","c ontinue","for","do","while","printf","scanf","begin","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("a.txt","r"))==NULL){printf("Open error!");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(",error digital!) ");}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(",unuseful things!) ");}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("(/* error!!\n)");return st+1;}} printf(" (");for(int i=0;i<n;i++)printf("%c",tabuf[i]);printf(",unuseful things!) ");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(" (!,wrong thing!) ");break;case '&': st++;if(aa[st]=='&'){st++;printf(" (&&,-) ");}else printf(" (&,worng word!) ");break;case '|': st++;if(aa[st]=='|'){st++;printf(" (||,-) ");}else printf(" (|,worng word!) ");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,worng thing) ",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<<" This is id card!! "<<endl;for(int i=0;i<pp;i++)cout<<i<<" "<<id[i]<<endl;cout<<" This is nu card!! "<<endl;for(int j=0;j<qq;j++)cout<<j<<" "<<nu[j]<<endl;}void main(){initscanner();scanner();print();}3.程序的执行结果图 1 程序输入文件内容图 2 输出结果4.实验程序的优点和特色本程序特色:出错处理能力强,任何非法字符输入,将会报错。

相关主题