java词法分析器实验报告.docx

上传人:b****4 文档编号:3908008 上传时间:2022-11-26 格式:DOCX 页数:20 大小:49.38KB
下载 相关 举报
java词法分析器实验报告.docx_第1页
第1页 / 共20页
java词法分析器实验报告.docx_第2页
第2页 / 共20页
java词法分析器实验报告.docx_第3页
第3页 / 共20页
java词法分析器实验报告.docx_第4页
第4页 / 共20页
java词法分析器实验报告.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

java词法分析器实验报告.docx

《java词法分析器实验报告.docx》由会员分享,可在线阅读,更多相关《java词法分析器实验报告.docx(20页珍藏版)》请在冰豆网上搜索。

java词法分析器实验报告.docx

java词法分析器实验报告

Java词法分析器实验报告

--07111101

--奥特曼

一.词法分析器功能概述:

1.使用DFA实现词法分析器的设计;

2.实现对Java源程序中注释和空格(空行)的过滤;

3.利用两对半缓冲区从文件中逐一读取单词;

4.词法分析结果属性字流存放在独立文件(c:

\words.txt)中;

5.统计源程序所有单词数以、错误单词数、单词所在的行数;

6.具有报告词法错误和出错位置(源程序行号)的功能;

二.源程序设计实现:

//程序大部分参照网络,自己做了小部分改动

#include

#include

#include

#include

#include

#include"const.h"

usingnamespacestd;

charrbuf[RBUFSIZE];//读文件缓冲区

intrp;//读文件缓冲区指针

charch;//当前扫描到的字符

inttype;//单词的类型

charsbuf[SBUFSIZE];//单词字符串缓冲区

intsp;//单词字符串缓冲区指针

ifstreaminFile;//输入文件

ofstreamoutFile;//输出文件

voidclear_rbuf()//清空读文件缓冲区

{

inti;

for(i=0;i

rbuf[i]='\0';

rp=0;

}

voidclear_sbuf()//清空单词字符缓冲区

{

inti;

for(i=0;i

sbuf[i]='\0';

sp=0;

}

voidget_ch()//从读文件缓冲区得到下一个字符

{

ch=rbuf[rp];

rp++;

}

voidput_ch(charch)//向字符缓冲区追加一个字符

{

sbuf[sp]=ch;

sp++;

}

voidget_type(char*msg)//得到单词类型

{

inti;

for(i=0;i

{

if(!

strcmp(msg,ATTR_MAP[i].keyword))

{

type=ATTR_MAP[i].type;

return;

}

}

return;

}

intdigit(intbase)//判断字符是否属于base进制并转换

{

charc=ch;

intresult;

if(c>='0'&&c<='7')

result=(int)(c-'0');

elseif(c>='8'&&c<='9')

{

if(base>8)

result=(int)(c-'0');

else

result=-1;

}

elseif(c>='a'&&c<='f')

{

if(base>10)

result=(int)(c-'a'+10);

else

result=-1;

}

elseif(c>='A'&&c<='F')

{

if(base>10)

result=(int)(c-'A'+10);

else

result=-1;

}

else

result=-1;

returnresult;

}

voidscan_fraction()//扫描指数

{

while(digit(10)>=0)

{

put_ch(ch);

get_ch();

}

if(ch=='e'||ch=='E')

{

put_ch(ch);

get_ch();

if(ch=='+'||ch=='-')

{

put_ch(ch);

get_ch();

}

while(digit(10)>=0)

{

put_ch(ch);

get_ch();

}

return;

}

return;

}

voidscan_suffix()//扫描浮点数后缀

{

scan_fraction();

if(ch=='f'||ch=='F'||ch=='d'||ch=='D')

{

put_ch(ch);

get_ch();

}

type=T_FLOAT;

return;

}

boolis_spectial(char&ch)//判断字符是否是特殊字符

{

if(ch=='!

'||ch=='%'||ch=='&'||ch=='*'||ch=='?

'||ch=='+'||ch=='-'||ch==':

'||ch=='<'||ch=='='||ch=='>'||ch=='^'||ch=='|'||ch=='~')

returntrue;

else

returnfalse;

}

voidscan_operator()//扫描运算符

{

while(is_spectial(ch))

{

put_ch(ch);

get_ch();

}

get_type(sbuf);

if(type==0)

type=T_ERROR;

return;

}

voidscan_number(intradix)//扫描8、10、16进制数值

{

while(digit(radix)>=0)

{

put_ch(ch);

get_ch();

}

if(radix!

=10&&ch=='.')

{

put_ch(ch);

get_ch();

type=T_ERROR;

}

elseif(radix==10&&ch=='.')

{

put_ch('.');

get_ch();

if(digit(10)>=0)

scan_suffix();

}

elseif(radix==10&&(ch=='e'||ch=='E'||ch=='f'||ch=='F'||ch=='d'||ch=='D'))

scan_suffix();

elseif(ch=='l'||ch=='L')

{

put_ch(ch);

get_ch();

type=T_INT;

}

elsetype=T_INT;

return;

}

voidskip_comment()//跳过注释内容

{

while(ch!

='\0')

{

switch(ch)

{

case'*':

get_ch();

if(ch=='/')

{

get_ch();

return;

}

break;

default:

get_ch();

break;

}

}

}

boolis_idchar(char&ch)//判断字符是否标识符首字符

{

return

((ch>='0'&&ch<='9')||(ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||ch=='$'||ch=='_');

}

voidscan_ident()//搜索关键字、标识符

{

boolid_or_key=true;

booltem=true;//是否仍是标识符或关键字

while(ch!

=C_TAB&&ch!

=C_FF&&ch!

=C_CR&&ch!

=C_LF&&ch!

='\0')

{

if(is_idchar(ch))

{

put_ch(ch);

get_ch();

if(is_idchar(ch))

continue;

else

get_type(sbuf);

if(type!

=0)

return;

else

{

type=T_IDENTIFIER;

return;

}

}

}

}

voidscan_char()//转义字符搜索字符

{

intoct=0;

inthex=0;

if(ch=='\\')

{

get_ch();

if(ch=='\\')

put_ch('\\');get_ch();

if(ch=='\'')

put_ch('\'');get_ch();

if(ch=='\"')

put_ch('\"');get_ch();

if(ch=='b')

put_ch('\b');get_ch();

if(ch=='t')

put_ch('\t');get_ch();

if(ch=='n')

put_ch('\n');get_ch();

if(ch=='f')

put_ch('\f');get_ch();

if(ch=='r')

put_ch('\r');get_ch();

if('0'<=ch&&ch<='7')

{

oct=digit(8);

get_ch();

if('0'<=ch&&ch<='7')

{

oct=oct*8+digit(8);

get_ch();

if('0'<=ch&&ch<='7')

{

oct=oct*8+digit(8);

get_ch();

}

}

put_ch((char)oct);

}

if(ch=='u')

{

get_ch();

if(('0'<=ch&&ch<='9')||('a'<=ch&&ch<='f')||('A'<=ch&&ch<='F'))

{

hex=hex*16+digit(16);

get_ch();

if(('0'<=ch&&ch<='9')||('a'<=ch&&ch<='f')||('A'<=ch&&ch<='F'))

{

hex=hex*16+digit(16);

get_ch();

if(('0'<=ch&&ch<='9')||('a'<=ch&&ch<='f')||('A'<=ch&&ch<='F'))

{

hex=hex*16+digit(16);

get_ch();

if(('0'<=ch&&ch<='9')||('a'<=ch&&ch<='f')||('A'<=ch&&ch<='F'))

{

hex=hex*16+digit(16);

get_ch();

}

}

}

}

put_ch((char)hex);

}

}

else

{

put_ch(ch);

get_ch();

}

}

voidget_word()//获取下一个单词及属性

{

clear_sbuf();

type=0;

while(ch!

='\0')

{

if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||ch=='$'||ch=='_')//关键字、标识符

{

scan_ident();

return;

}

elseif(ch=='\'')//字符

{

get_ch();

if(ch=='\'')

{

type=T_ERROR;

strcpy(sbuf,"''");

get_ch();

}

else

{

scan_char();

if(ch=='\'')

{

type=T_CHAR;

get_ch();

}

elsetype=T_ERROR;

}

return;

}

elseif(ch=='\"')//字符串

{

get_ch();

if(ch=='\"')

{

type=T_ERROR;

strcpy(sbuf,"\"\"");

get_ch();

}

else

{

do

{

scan_char();

}

while(ch!

='\"'&&ch!

=C_TAB&&ch!

=C_FF&&ch!

=C_CR&&ch!

=C_LF);

if(ch=='\"')

{

type=T_STRING;

get_ch();

}

elsetype=T_ERROR;

}

return;

}

elseif(ch=='.')//.开头数字

{

put_ch(ch);

get_ch();

if(digit(10)>=0)

scan_suffix();

elsetype=T_BOUND;

return;

}

elseif(ch=='0')//0开头数字

{

put_ch('0');

get_ch();

if(ch=='x'||ch=='X')

{

put_ch(ch);

get_ch();

if(digit(16)>=0&&ch!

='0')

scan_number(16);

}

elseif(digit(8)>=0&&ch!

='0')

scan_number(8);

elseif(ch=='.')

{

put_ch('.');

get_ch();

if(digit(10)>=0)

scan_suffix();

}

elseif(ch=='')

{

get_ch();

type=T_INT;

}

elsetype=T_ERROR;

return;

}

elseif('1'<=ch&&ch<='9')//1-9开头数字

{

scan_number(10);

return;

}

elseif((ch=='(')||(ch==')')||(ch=='[')||(ch==']'))//9个界限符中的8个

{

put_ch(ch);

get_ch();

type=T_BOUND;

return;

}

elseif(ch==',')

{

put_ch(ch);

get_ch();

type=T_COMMA;

return;

}

elseif((ch=='{')||(ch=='}'))

{

put_ch(ch);

get_ch();

type=T_BRACKET;

return;

}

elseif(ch==';')

{

put_ch(ch);

get_ch();

type=T_SEMICOLON;

return;

}

elseif(ch=='/')//注释、'/'运算符、'/='运算符

{

get_ch();

if(ch=='/')

{

while(ch!

=C_CR&&ch!

=C_LF&&ch!

='\0')

get_ch();

break;

}

elseif(ch=='*')

{

get_ch();

skip_comment();

}

elseif(ch=='=')

{

strcpy(sbuf,"/=");

type=T_ASSIGN;

get_ch();

}

else

{

strcpy(sbuf,"/");

type=T_MULDIV;

}

return;

}

elseif(is_spectial(ch))//特殊字符

{

scan_operator();

return;

}

elseget_ch();//间隔符

}

}

voidreadfile(char*fn_in)//将源文件读入缓冲区

{

rp=0;

inFile.open(fn_in);

if(!

inFile.is_open())

return;

while(inFile.get(rbuf[rp]))

rp++;

inFile.close();

rp=0;

}

voidwritefile()//向输出文件写字符

{

sp=0;

outFile<<"(0x"<

outFile<<"[";

while(sbuf[sp]!

='\0')

{

outFile<

sp++;

}

outFile<<"]";

outFile<

sp=0;

}

intmain(intargc,char*argv[])

{

charfn_in[NAMESIZE];

charfn_out[NAMESIZE];

cout<<"InputthenameofJavasourcefile:

";

cin>>fn_in;

readfile(fn_in);

cout<<"Inputnameoftestingresultfile:

";

cin>>fn_out;

outFile.open(fn_out);

get_ch();

while(ch!

='\0')

{

get_word();

if(strlen(sbuf)!

=0)

writefile();

}

outFile.close();

cout<<"Theanalysishasbeencompleted!

"<

system("pause");

return0;

}

三.程序执行流程

a.首先从Java文件中读取半个缓冲区的字符串读入预处理缓冲区中,将缓冲区中的注释、空行、空格全部处理,最后预处理缓冲区里面只剩下单词、一个空格、换行;

b.将预处理缓冲区里面的的数据分两次读入两对半缓冲区ScanBuffer中,送入词法分析器wordScanner进行逐个单词分析,由wordScanner调用相应的转换函数进行单词属性的分析。

四.心得体会

不知经历了几个不眠之夜,前后一共花了将近两星期时间Java词法分析器终于横空出世。

回想这两个礼拜的艰苦历程,一开始真不知道如何下手,真是块烫手的芋头,徘徊挣扎了两天,最后横下一条心:

拼了!

从预处理缓冲区开始着手,一个模块就花了一天时间,BUG仍旧阴魂不散,郁闷之中,只能另辟蹊径,直入主题,先实现分析一类单词的功能,标识符。

char*keyWordOrIdentifierOrBool(char*word),首先想到的是这么多字母还有数字怎么处理,总不能一个个switch…case吧,于是我想到把所有字母和数字先用函数dealChar()处理一下,把所有字母统一归为’a’,数字归为’8’,这样就好办多了,期间又花了将近两天时间,改了又改,测了又测,终于喜见眉梢“哇咔咔。

接下来就是依葫芦画瓢了,相继攻克了其它各个功能,花了三天时间,差不多是时候了,最后压轴的是数字的处理,我处理的比较简单。

最后的调试阶段是比较揪心的,程序各个功能的实现基本正常,最要命的还是那个预处理缓冲区,我是一串串读入的,所以处理起来比挨个读入的要困难得多,悔不该当初用fgets,不过路已经选择了就没有退路了,定于2010-5-28日这个黑色星期五与魔鬼决战,泡信息楼一天终于将其勉强降服,杀青时间为2010-5-28日19:

30分,凯歌在耳旁奏响。

再回首,往事如梦,虽然整个程序仍有BUG作怪,只因本人编程水平有限,但构成生命的细胞元—单词,完全是由本人经过深思熟虑挨个敲出来的,算对的起祖国、对得起老师、对得起父母,对得起我的电脑!

 

五.DFA略图

数字|字母|下划线|$

字母|$|_其它

运算符

运算符其它

 

界限符

 

=’”’

 

!

=’\’’

‘\’’

 

数字|.|e|f|L

数字其它

 

Other

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

当前位置:首页 > 初中教育 > 理化生

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1