北邮 编译原理 词法分析.docx

上传人:b****2 文档编号:2105407 上传时间:2023-05-02 格式:DOCX 页数:27 大小:91.75KB
下载 相关 举报
北邮 编译原理 词法分析.docx_第1页
第1页 / 共27页
北邮 编译原理 词法分析.docx_第2页
第2页 / 共27页
北邮 编译原理 词法分析.docx_第3页
第3页 / 共27页
北邮 编译原理 词法分析.docx_第4页
第4页 / 共27页
北邮 编译原理 词法分析.docx_第5页
第5页 / 共27页
北邮 编译原理 词法分析.docx_第6页
第6页 / 共27页
北邮 编译原理 词法分析.docx_第7页
第7页 / 共27页
北邮 编译原理 词法分析.docx_第8页
第8页 / 共27页
北邮 编译原理 词法分析.docx_第9页
第9页 / 共27页
北邮 编译原理 词法分析.docx_第10页
第10页 / 共27页
北邮 编译原理 词法分析.docx_第11页
第11页 / 共27页
北邮 编译原理 词法分析.docx_第12页
第12页 / 共27页
北邮 编译原理 词法分析.docx_第13页
第13页 / 共27页
北邮 编译原理 词法分析.docx_第14页
第14页 / 共27页
北邮 编译原理 词法分析.docx_第15页
第15页 / 共27页
北邮 编译原理 词法分析.docx_第16页
第16页 / 共27页
北邮 编译原理 词法分析.docx_第17页
第17页 / 共27页
北邮 编译原理 词法分析.docx_第18页
第18页 / 共27页
北邮 编译原理 词法分析.docx_第19页
第19页 / 共27页
北邮 编译原理 词法分析.docx_第20页
第20页 / 共27页
亲,该文档总共27页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

北邮 编译原理 词法分析.docx

《北邮 编译原理 词法分析.docx》由会员分享,可在线阅读,更多相关《北邮 编译原理 词法分析.docx(27页珍藏版)》请在冰点文库上搜索。

北邮 编译原理 词法分析.docx

北邮编译原理词法分析

实验报告

编译原理与技术

ytinrete

程序设计1

题目:

词法分析程序的设计与实现。

实验内容:

设计并实现C语言的词法分析程序,要求如下。

(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。

(2)、可以识别并读取源程序中的注释。

(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果

(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。

(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。

实验要求:

方法1:

采用C/C++作为实现语言,手工编写词法分析程序。

方法2:

通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。

算法思路:

首先通过遍历,统计行号和字符数,并记录所有的注释。

其次,再次读取,利用一个字符数组作为buffer保存一行的数据,在对其中的数据进行处理,完成之后再读下一行,跳过注释。

对于整行数据的处理,依靠空格将其分成单个单词再具体处理。

对于查错问题实在是一个难题,只能根据一些规则判定有错并记录。

程序源代码:

//假设源程序存在相对路径下名为data.c

/*

Name:

词法分析程序

Author:

李睿

Date:

23/10/1300:

40

Description:

题目:

词法分析程序的设计与实现。

(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。

(2)、可以识别并读取源程序中的注释。

(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果

(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。

(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。

实验要求:

方法1:

采用C/C++作为实现语言,手工编写词法分析程序。

方法2:

通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。

*/

#include

#include

#include

#include

#include

usingnamespacestd;

constintMAX_INPUT_BUFFER=512;//默认输入缓存区

ifstreamfile;//打开文件

vectorkeyword;//预先记录关键字

vectorcomment;//存储注释

vectorid;//记录标示符

vectorpre;//预处理文件

intsum_char=0;//字符数

intsum_word=0;//单词数

intsum_line=0;//行数

intcurrent_line=0;//当前行数

boolin_comment=false;//标识此行是否在注释中

charbuffer[MAX_INPUT_BUFFER];//缓存区

intbig_bracket=0;//大括号

intsmall_bracket=0;//小括号

voidinit(void)//初始化关键字

{

keyword.clear();

keyword.push_back("auto");

keyword.push_back("break");

keyword.push_back("case");

keyword.push_back("char");

keyword.push_back("const");

keyword.push_back("continue");

keyword.push_back("default");

keyword.push_back("do");

keyword.push_back("double");

keyword.push_back("else");

keyword.push_back("enum");

keyword.push_back("extern");

keyword.push_back("float");

keyword.push_back("for");

keyword.push_back("goto");

keyword.push_back("if");

keyword.push_back("int");

keyword.push_back("long");

keyword.push_back("register");

keyword.push_back("return");

keyword.push_back("short");

keyword.push_back("signed");

keyword.push_back("static");

keyword.push_back("sizeof");

keyword.push_back("struct");

keyword.push_back("switch");

keyword.push_back("typedef");

keyword.push_back("union");

keyword.push_back("unsigned");

keyword.push_back("void");

keyword.push_back("volatile");

keyword.push_back("while");

}

voidsum(void)//计算字符数行数存注释

{

file.open("data.c");

intstate=0;//状态转换0:

正常1:

输入一个/2:

输入/*

chartemp;//暂存

stringtemp_comment;//暂存注释

file.seekg(0);//文件指针回到头

while(!

file.eof())//遍历全文

{

switch(state)

{

case0:

file.get(temp);

sum_char++;//增加字符

if('\n'==temp)

sum_line++;//增加行

if('/'==temp)

state=1;

break;

case1:

//前一个字符是/

file.get(temp);

sum_char++;//增加字符

if('/'==temp)//单行注释

{

temp_comment.clear();//清空注释缓存

while('\n'!

=temp)//输完整行

{

file.get(temp);

sum_char++;//增加字符

temp_comment.append(1,temp);//添加注释

}

sum_line++;//行增加

comment.push_back(temp_comment);//添加到注释记录表

state=0;//状态回归

}

else

if('*'==temp)//多行注释

{

temp_comment.clear();

state=2;

}

else//不是注释

{

if('\n'==temp)

sum_line++;//增加行

state=0;//状态回归

}

break;

case2:

file.get(temp);

sum_char++;//增加字符

if('*'==temp)

{

file.get(temp);//再取一个

sum_char++;//增加字符

if('/'==temp)//结束多行注释

{

comment.push_back(temp_comment);//存入注释表

state=0;

}

else//还在注释中

{

temp_comment.append(1,'*');

temp_comment.append(1,temp);

if('\n'==temp)

sum_line++;

}

}

else

{

if(file.eof())//当注释到尾时

{

if(!

temp_comment.empty())//不为空时存入最后一个注释

{

comment.push_back(temp_comment);

return;

}

}

if('\n'==temp)

sum_line++;

temp_comment.append(1,temp);

}

break;

default:

break;

}

}

}

voidword_analyse(void)

{

stringtemp_word;//暂存单词

char*p=buffer;//处理指针

while(in_comment)//处理多行注释问题

{

if('\0'==*p)

return;

if(('*'==*p)&&('/'==*(p+1)))

{

p+=2;

in_comment=false;

}

p++;

}

while('\0'!

=*p)//遍历整句

{

if(''==*p)//当是空格时后移

p++;

else

if(isalpha(*p)||'_'==*p)//以字母或下划线开头,关键字和标识符

{

temp_word.clear();

while(isalnum(*p)||'_'==*p)//记录关键字

{

temp_word.append(1,*p);

p++;

}//当为空格或别的符号时弹出

sum_word++;//单词+1

id.push_back(temp_word);//存入标示符

inti;

for(i=0;i

if(keyword.at(i)==temp_word)

break;

if(i

cout<

"<<"保留字:

"<

else

cout<

"<<"标示符:

"<

}

else

if(isdigit(*p))//无符号数

{

temp_word.clear();

while(isdigit(*p))

{

temp_word.append(1,*p);

p++;

}

if(isalpha(*p)||'_'==*p)//非法字符

{

while(''!

=*p&&'\0'!

=*p)

{

temp_word.append(1,*p);

p++;

}

sum_word++;

id.push_back(temp_word);

cout<

"<<"非法字符:

"<

cout<<"error:

在第"<

"<

}

else

{

if('.'==*p||'E'==*p||'e'==*p)//小数和指数形式

{

temp_word.append(1,*p);

p++;

while(isdigit(*p))

{

temp_word.append(1,*p);

p++;

}

}

sum_word++;

id.push_back(temp_word);

cout<

"<<"无符号数:

"<

}

}

else

if('#'==*p)//预处理文件特殊处理

{

while('\0'!

=*p)

{

temp_word.append(1,*p);

p++;

}

//p指向换行,完成直接退出

pre.push_back(temp_word);

}

else

if('"'==*p)//字符串

{

temp_word.clear();

p++;

while('"'!

=*p)

{

temp_word.append(1,*p);

p++;

}

p++;

sum_word++;

cout<

"<<"字符串:

"<

}

else

if('+'==*p)//处理符号

{

temp_word.clear();

if('='==*(p+1))//自加

{

temp_word="+=";

id.push_back(temp_word);

sum_word++;

cout<

"<<"自加号:

"<

p+=2;//推进

}

else

if('+'==*(p+1))//自加1

{

temp_word="++";

id.push_back(temp_word);

sum_word++;

cout<

"<<"自加1号:

"<

p+=2;//推进

}

else

if(isdigit(*(p+1)))//有符号数

{

temp_word="+";

for(intj=1;isdigit(*(p+j));j++)

temp_word.append(1,*(p+j));

id.push_back(temp_word);

sum_word++;

cout<

"<<"有符号数:

"<

p+=2;//推进

}

else

{

temp_word="+";

id.push_back(temp_word);

sum_word++;

cout<

"<<"加号:

"<

p+=2;//推进

}

}

else

if('-'==*p)//处理符号

{

temp_word.clear();

if('='==*(p+1))//自减

{

temp_word="-=";

id.push_back(temp_word);

sum_word++;

cout<

"<<"自减号:

"<

p+=2;//推进

}

else

if('-'==*(p+1))//自减1

{

temp_word="--";

id.push_back(temp_word);

sum_word++;

cout<

"<<"自减1号:

"<

p+=2;//推进

}

else

if(isdigit(*(p+1)))//有符号数

{

temp_word="-";

for(intj=1;isdigit(*(p+j));j++)

temp_word.append(1,*(p+j));

id.push_back(temp_word);

sum_word++;

cout<

"<<"有符号数:

"<

p+=2;//推进

}

else

{

temp_word="-";

id.push_back(temp_word);

sum_word++;

cout<

"<<"减号:

"<

p+=2;//推进

}

}

else

if('*'==*p)//处理符号

{

temp_word.clear();

if('='==*(p+1))//自乘

{

temp_word="*=";

id.push_back(temp_word);

sum_word++;

cout<

"<<"自乘号:

"<

p+=2;//推进

}

else

{

temp_word="*";

id.push_back(temp_word);

sum_word++;

cout<

"<<"乘号:

"<

p+=2;//推进

}

}

else

if('/'==*p)//处理符号

{

temp_word.clear();

if('='==*(p+1))//自除

{

temp_word="*=";

id.push_back(temp_word);

sum_word++;

cout<

"<<"自除号:

"<

p+=2;//推进

}

else

if('/'==*(p+1))//行注释

return;//直接跳出

else

if('*'==*(p+1))//多行注释

{

in_comment=true;

p+=2;

while('\0'!

=*p)//判断这行为止注释能不能结束

{

if(('*'==*p)&&('/')==*(p+1))

{

in_comment=false;

break;

}

p++;

}

}

else

{

temp_word="/";

id.push_back(temp_word);

sum_word++;

cout<

"<<"除号:

"<

p+=2;//推进

}

}

else

if('='==*p)//处理等号

{

temp_word.clear();

if('='==*(p+1))//比较

{

temp_word="==";

id.push_back(temp_word);

sum_word++;

cout<

"<<"比较号:

"<

p+=2;//推进

}

else

{

temp_word="=";

id.push_back(temp_word);

sum_word++;

cout<

"<<"赋值号:

"<

p+=2;//推进

}

}

else

if('>'==*p)

{

temp_word.clear();

if('='==*(p+1))

{

temp_word=">=";

id.push_back(temp_word);

sum_word++;

cout<

"<<"大于等于号:

"<

p+=2;//推进

}

else

{

temp_word=">";

id.push_back(temp_word);

sum_word++;

cout<

"<<"大于号:

"<

p+=2;//推进

}

}

else

if('<'==*p)

{

temp_word.clear();

if('='==*(p+1))

{

temp_word="<=";

id.push_back(temp_word);

sum_word++;

cout<

"<<"小于等于号:

"<

p+=2;//推进

}

else

{

temp_word="<";

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2