编译原理词法分析五种类别识别程序含实现代码cpp
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一词法分析
一、实验目的和要求
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
二、实验过程
(1)程序思路
这里以开始定义的C语言子集的源程序作为词法分析程序的输入数据。在词法分析中,自文件头开始扫描源程序字符,一旦发现符合“单词”定义的源程序字符串时,将它翻译成固定长度的单词内部表示,并查填适当的信息表。经过词法分析后,源程序字符串(源程序的外部表示)被翻译成具有等长信息的单词串(源程序的内部表示),并产生两个表格:常数表和标识符表,它们分别包含了源程序中的所有常数和所有标识符。
0.定义部分:定义常量、变量、数据结构。
1.初始化:从文件将源程序全部输入到字符缓冲区中。
2.取单词前:去掉多余空白。
3.取单词后:去掉多余空白。
4.取单词:利用实验一的成果读出单词的每一个字符,组成单词,分析类型。
循环取字符,直到遇到“#”字符就停止扫描。
5.显示结果。
(2)程序实现部分代码
char *table[7]={" ","main","int","if","then","else","return"}; //定义关键字
char *table1[5]={"++",">=","<=","!=","=="}; //定义运算符符号
int lookup(char *TOKEN) //关键字匹配函数,查询所述程序中的关键字
{
int m,i;
for(i=0;i<=6;i++)
{
if((m=strcmp(TOKEN,table[i]))==0)
return 1;
}
return 0;
}
int lookup1(char *TOKEN) //判断>= <= != ==,方法与lookup()相似
int lookup2(int i,char *TOKEN) //判断数字加字母的情况
{
int j;
for(j=1;j
{
if(TOKEN[j]>='a'||TOKEN[j]>='A')
return 1;
}
return 0;
}
bool zimu(char ch) //bool类型函数,判断是否为字母
{
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')
return true;
else
return false;
}
bool shuzi(char ch) //判断是否为数字,方法与zimu()类似
bool fuhao(char ch) //判断双字符
{
if(ch=='+'||ch=='>'||ch=='<'||ch=='!'||ch=='=')
return true;
else
return false;
}
void out(int c,char *TOKEN) //输出函数形式为(c,“TOKEN”)
{
printf("( %d,“%s”)\n",c,TOKEN);
}
void scanner(FILE *fp) //扫描函数
{
char TOKEN[20]={'\0'};
int i;
ch=fgetc(fp); //获取字符,指针fp并自动指向下一个字符if(zimu(ch)) //判断该字符是否是字母
{
TOKEN[0]=ch;
ch=fgetc(fp); //fgetc(fp)从数据流中读取一个字符
i=1;
while(shuzi(ch)|| zimu(ch)) //判断该字符是否是字母或数字
{
TOKEN[i]=ch;
ch=fgetc(fp);
i++;
}
fseek(fp,-1,1);
if(lookup(TOKEN)) //判断是关键字还是普通的标识符
out(1,TOKEN);
else
out(2,TOKEN);
}
else if(shuzi(ch))
{
TOKEN[0]=ch;
ch=fgetc(fp); //fgetc(fp)从数据流中区下一个字符
i=1;
while(shuzi(ch)||zimu(ch)) //判断该字符是否是字母或数字
{ TOKEN[i]=ch;
ch=fgetc(fp);
i++; }
fseek(fp,-1,1);
if(lookup2(i,TOKEN)) //如果出现2a的情况下,判断为错误语法printf("(error,“%s”)\n",TOKEN);
else
out(3,TOKEN);
}
else if(fuhao(ch)) //符号函数,用来判断是否是双运算符
{
TOKEN[0]=ch;
ch=fgetc(fp);
i=1;
while(fuhao(ch))
{
TOKEN[i]=ch;
ch=fgetc(fp);
i++;
}
fseek(fp,-1,1);
//调用lookpu1()判断符号是否为table1[5]里的双运算符
if(lookup1(TOKEN))
out(4,TOKEN);
else
out(4,TOKEN);
}
//判断一般运算符,一般运算符有+、-、*、/、=等,这里以“+”为例
else if(ch=='+')
{
TOKEN[0]=ch;
out(4,TOKEN);
}
//判断分隔符,分隔符有,、;、{、}、[、]、(、)等,这里以“;”为例
else if(ch==';')
{
TOKEN[0]=ch;
out(5,TOKEN);
}
}
//main()函数在此省略
三、调试错误
在程序初步完成时,运行程序就出现了错误,文件读取错误,后来仔细分析了mian()函数的代码,也没有检查出来什么,别人的这种错误都是因为把文件名写成了123.txt.txt,我的并没有这种错误还是打不开,最后还是看了看前面的代码,发现在判断数字的函数那里我把并且符号&&写成了或者符号||,改正之后程序正常运行。除此还有像双运算符无法识别,那是因为我没有写有关的代码,最后补充了lookup2()还定义了table1[5],用来判断是否出现双运算符的情况,经过调试,双运算符也识别成功。