编译原理 词法分析.docx

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

编译原理 词法分析.docx

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

编译原理 词法分析.docx

编译原理词法分析

实验报告

学院(系)名称:

计算机与通信工程学院

姓名

建坤

学号

专业

计算机科学与技术

班级

2010级2班

实验项目

实验一:

词法分析

课程名称

编译原理

课程代码

0668056

实验时间

2013年3月22日第5~8节

2013年3月26日第1、2节

实验地点

软件实验室7-215

批改意见

成绩

 

教师签字:

实验内容:

实现标准C语言词法分析器

实验目的:

1.掌握程序设计语言词法分析的设计方法;

2.掌握DFA的设计与使用方法;

3.掌握正规式到有限自动机的构造方法;

实验要求:

1.单词种别编码要求

基本字、运算符、界符:

一符一种;

标识符:

统一为一种;

常量:

按类型编码;

2.词法分析工作过程中建立符号表、常量表,并以文本文件形式输出;

3.词法分析的最后结果以文本文件形式输出;

4.完成对所设计词法分析器的功能测试,并给出测试数据和实验结果;

5.为增加程序可读性,请在程序中进行适当注释说明;

6.整理上机步骤,总结经验和体会;

7.认真完成并按时提交实验报告。

【实验过程记录(源程序、测试用例、测试结果及心得体会等)】

符号对照:

种类

标识

正则表达式

关键字

KEY

[_A-Za-z][0-9_A-Za-z]

标识符

ID

[_A-Za-z][0-9_A-Za-z]

整型常量

INT

[0-9]+

浮点常量

FLOAT

[0-9](\.[0-9]+)?

(E[+-]?

[0-9]+)?

界符

DELIM

[,;\[\]\{\}\(\)]

运算符

OPT

[!

%\^&\*\+\-<>?

/]|&&|<=|>=|==|\|\|

字符常量

CHAR

^\'$\'

字符串常量

STR

^\"$\"

源程序:

#include

#include

#include

#include

#include

#defineKEY0

#defineID1

#defineINT2

#defineFLOAT3

#defineCHAR4

#defineSTR5

#defineDELIM6

#defineOPT7

char*TYPE[]={"KEY","ID","INT","FLOAT","CHAR","STR","DELIM","OPT"};

charfilename[256];//要处理的文件名

longlength;//文件长度

char*key[]={"auto","break","case","char","const","continue",

"default","do","double","else","enum","extern",

"float","for","goto","if","int","long",

"register","return","short","signed","sizeof","static",

"struct","switch","typedef","union","unsigned","void",

"volatile","while",NULL};

constintKEYCOUNT=32;

char*source;//源码的内存缓冲区

longpos=0;//指向源码的指针

longline=1;//行号

longcolumn=0;//列号

chartoken[1024];//临时存放标识符

voiderror(constchar*error,...){

va_listarglist;

va_start(arglist,error);

vfprintf(stderr,error,arglist);

va_end(arglist);

exit(EXIT_FAILURE);

}

voidwarning(constchar*error,...){

va_listarglist;

va_start(arglist,error);

vfprintf(stderr,error,arglist);

va_end(arglist);

}

//判断是否为分隔符,是的话返回1,否则返回0

intisdelim(constcharch){

switch(ch){

case'(':

case')':

case'[':

case']':

case'{':

case'}':

case',':

case';':

case':

':

return1;

}

return0;

}

intisoperator(constcharch){

switch(ch){

case'+':

case'-':

case'*':

case'/':

case'<':

case'>':

case'?

':

case'=':

case'&':

case'!

':

case'~':

case'%':

case'|':

case'^':

case'.':

return1;

}

return0;

}

intiskey(constchar*str){

for(inti=0;i

if(strcmp(key[i],str)==0)

returni+1;

}

return0;

}

//读入源码的一个字符

charreadSource(){

if(pos

charch=source[pos++];

if(ch=='\n'){

line++;

column=0;

}

else

column++;

returnch;

}

else{

error("未预料的EOF\n");

return0;

}

}

//回退源码指针

voidback(){

if(pos==0){

error("errorinback():

posnowis0\n");

}

else

pos--;

}

longgetFileLength(FILE*fp){

longpos=ftell(fp);

longlength;

fseek(fp,0,SEEK_END);

length=ftell(fp);

fseek(fp,pos,SEEK_SET);

returnlength;

}

voidpreprocess(){

for(charch;ch=readSource();){

if(ch=='#'){

inti=0;

token[i++]=ch;

while((ch=readSource())!

='\n')

token[i++]=ch;

token[i]='\0';

if(token[0]=='#')

printf("%d\t%s\n",line,token);

}

else{

if(ch!

='\n')

back();

break;

}

}

}

voidgetOperator(charch){

token[0]=ch;

ch=readSource();

token[1]=ch;

token[2]='\0';

switch(token[0]){

case'<':

case'>':

if(token[0]==token[1]||token[1]=='=')

break;

case'|':

case'&':

case'+':

case'-':

case'=':

if(token[0]==token[1])

break;

case'!

':

if(token[1]=='=')

break;

default:

token[1]='\0';

back();

break;

}

printf("%ld\t%s\t%s\n",line,TYPE[OPT],token);

}

voidcomment(){

charch=readSource();

if(ch=='*'){

while

(1){

ch=readSource();

if(ch=='*'){

ch=readSource();

if(ch=='/')

break;

}

}

}

elseif(ch=='/'){

while

(1){

ch=readSource();

if(ch=='\n')

break;

}

}

else{

back();

getOperator('/');

}

}

voidgetChar(charch){

inti=0;

for(;(ch=readSource())!

='\'';i++){

token[i]=ch;

if(ch=='\\'){

ch=readSource();

token[++i]=ch;

}

}

token[i]='\0';

if(token[0]!

='\\'&&strlen(token)>1){

error("字符常量字符多余1个\n");

}

printf("%ld\t%s\t\'%s\'\n",line,TYPE[CHAR],token);

}

voidgetString(charch){

inti=0;

for(;(ch=readSource())!

='"';i++){

token[i]=ch;

if(ch=='\\'){

ch=readSource();

if(ch=='\n')

i--;

else

token[++i]=ch;

}

}

token[i]='\0';

printf("%ld\t%s\t\"%s\"\n",line,TYPE[STR],token);

}

voidgetIdentify(charch){

inti=1;

token[0]=ch;

for(;!

isspace(ch=readSource());i++){

if(isalpha(ch)||isdigit(ch)||ch=='_'){

token[i]=ch;

}

elseif(isoperator(ch)||isdelim(ch)||ch=='.'){

back();

break;

}

else{

error("非法标识符字符\n",filename,line,column);

}

}

token[i++]='\0';

if(iskey(token))

printf("%ld\t%s\t%s\n",line,TYPE[KEY],token);

else

printf("%ld\t%s\t%s\n",line,TYPE[ID],token);

}

voidgetNum(charch){

inti=0;

inthasDot=0;

inttype=0;//0isint1isfloat

intafterE=0;

if(ch=='.'){

hasDot=1;

type=1;

}

token[0]=ch;

for(i=1;i<256;i++){

ch=readSource();

if(token[0]=='.'&&i==1){

if(!

isdigit(ch)){

getOperator('.');

back();

return;

}

}

if(ch=='.'){

if(!

hasDot){

hasDot=1;

type=1;

}

else

error("数字中小数点多于1个\n");

}

elseif(ch=='E'||ch=='e'){

afterE=1;

type=1;

}

elseif(ch=='+'||ch=='-'){

if(afterE){

afterE=0;

}

else{

back();

break;

}

}

elseif(!

isdigit(ch)){

back();

break;

}

token[i]=ch;

}

token[i]='\0';

if(token[0]=='.'&&strlen(token)==1){

//error("未预料的符号.\n");

getOperator(ch);

return;

}

if(type==0){

printf("%ld\t%s\t%s\n",line,TYPE[INT],token);

}

elseif(type==1){

printf("%ld\t%s\t%s\n",line,TYPE[FLOAT],token);

}

}

 

//获得界符与运算符

voidgetDelim(charch){

printf("%ld\t%s\t%c\n",line,TYPE[DELIM],ch);

}

 

voidlexer(){

pos=0;

line=1;

column=0;

preprocess();

for(;pos

charch=readSource();

//printf("%ld%ld%c\n",line,column,ch);

if(isalpha(ch)||ch=='_'){

getIdentify(ch);

}

elseif(isdigit(ch)||ch=='.'){

getNum(ch);

}

elseif(isspace(ch)){

}

elseif(ch=='\''){

getChar(ch);

}

elseif(ch=='"'){

getString(ch);

}

elseif(ch=='/'){

comment();

}

elseif(isoperator(ch)){

getOperator(ch);

}

elseif(isdelim(ch)){

getDelim(ch);

}

else{

printf("%ld\tPRE\t%c\n",line,ch);

}

}

}

 

/*命令行参数

*lexerfilename

*/

intmain(intargc,char**argv){

if(argc!

=2){

error("Usage:

%sfilename\n",argv[0]);

}

strcpy(filename,argv[1]);

FILE*file;

if(NULL==(file=fopen(argv[1],"r"))){

error("Cannotopen%s.\n",filename);

}

longfileLength=getFileLength(file);

source=(char*)malloc(fileLength+1);

fseek(file,0,SEEK_SET);

inthasRead;

for(hasRead=0;!

feof(file);){

intcount=fread(source+hasRead,1,1024,file);

hasRead+=count;

}

source[hasRead]=0;

length=hasRead;

lexer();//调用词法处理器

fclose(file);

return0;

}

测试程序:

#include

intgetSum(intnum){

inti=0;

intsum=0;

while(i<=num){

sum+=i;

i++;

}

returnsum;

}

/*Thisfunctionistogettwonumandcalculatetheresum

*andprintthesumof12...to10

*/

intmain(){

intt=10;

floata=10E-5,b=5.2;

scanf("%f%f",&a,&b);

printf("a=%f,b=%f\n",a,b);

if(a==b)

printf("aisequaltob\n");

elseif(a

printf("a<=b\n");

else

printf("a>b\n");

//invokeafunction

printf("sum=%d\n",sum(t));

return0;

}

测试结果:

2#include

3KEYint

3IDgetSum

3DELIM(

3KEYint

3IDnum

3DELIM)

3DELIM{

4KEYint

4IDi

4OPT=

4INT0

4DELIM;

5KEYint

5IDsum

5OPT=

5INT0

5DELIM;

6KEYwhile

6DELIM(

6IDi

6OPT<=

6IDnum

6DELIM)

6DELIM{

7IDsum

7OPT+=

7IDi

7DELIM;

8IDi

8OPT++

8DELIM;

9DELIM}

10KEYreturn

10IDsum

10DELIM;

11DELIM}

17KEYint

17IDmain

17DELIM(

17DELIM)

17DELIM{

18KEYint

18IDt

18OPT=

18INT10

18DELIM;

19KEYfloat

19IDa

19OPT=

19FLOAT10E-5

19DELIM,

19IDb

19OPT=

19FLOAT5.2

19DELIM;

21IDscanf

21DELIM(

21STR"%f%f"

21DELIM,

21OPT&

21IDa

21DELIM,

21OPT&

21IDb

21DELIM)

21DELIM;

22IDprintf

22DELIM(

22STR"a=%f,b=%f\n"

22DELIM,

22IDa

22DELIM,

22IDb

22DELIM)

22DELIM;

23KEYif

23DELIM(

23IDa

23OPT==

23IDb

23DELIM)

24IDprintf

24DELIM(

24STR"aisequaltob\n"

24DELIM)

24DELIM;

25KEYelse

25KEYif

25DELIM(

25IDa

25OPT<

25IDb

25DELIM)

26IDprintf

26DELIM(

26STR"a<=b\n"

26DELIM)

26DELIM;

28KEYelse

28IDprintf

28DELIM(

28STR"a>b\n"

28DELIM)

28DELIM;

31IDprintf

31DELIM(

31STR"sum=%d\n"

31DELIM,

31IDsum

31DELIM(

31IDt

31DELIM)

31DELIM)

31DELIM;

32KEYreturn

32INT0

32DELIM;

33DELIM}

实验感想:

1.开始时的程序整体无框架,所有程序都写在了一个函数里,写到中间发现不宜维护,可读性差,后来就整体重新写了一遍,把不相关的功能剥离,提高模块性及可读性。

2.开始时注释处理在符号处理后面,后来发现处理不了注释,经过排查后发现把注释处理放到最前面就行了。

3.本程序添加了许多错误处理,使代码更加健壮。

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

当前位置:首页 > 自然科学 > 物理

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

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