java词法分析器实验报告.docx_第1页
java词法分析器实验报告.docx_第2页
java词法分析器实验报告.docx_第3页
java词法分析器实验报告.docx_第4页
java词法分析器实验报告.docx_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java 词法分析器实验报告-07111101-奥特曼一词法分析器功能概述:1. 使用DFA实现词法分析器的设计;2. 实现对Java源程序中注释和空格(空行)的过滤;3. 利用两对半缓冲区从文件中逐一读取单词;4. 词法分析结果属性字流存放在独立文件(c:words.txt)中;5. 统计源程序所有单词数以、错误单词数、单词所在的行数;6. 具有报告词法错误和出错位置(源程序行号)的功能;二源程序设计实现: /程序大部分参照网络,自己做了小部分改动#include #include #include #include #include #include const.husing namespace std;char rbufRBUFSIZE; /读文件缓冲区int rp; /读文件缓冲区指针char ch; /当前扫描到的字符int type; /单词的类型char sbufSBUFSIZE; /单词字符串缓冲区int sp; /单词字符串缓冲区指针ifstream inFile; /输入文件ofstream outFile; /输出文件void clear_rbuf()/清空读文件缓冲区int i;for(i=0;iRBUFSIZE;i+)rbufi=0;rp=0;void clear_sbuf()/清空单词字符缓冲区int i;for(i=0;iSBUFSIZE;i+)sbufi=0;sp=0;void get_ch()/从读文件缓冲区得到下一个字符 ch=rbufrp;rp+;void put_ch(char ch)/向字符缓冲区追加一个字符 sbufsp=ch;sp+;void get_type(char * msg)/得到单词类型int i; for(i=0;i=0&c=8&c 8) result=(int)(c-0); else result = -1; else if(c=a&c10) result=(int)(c-a+10); else result=-1; else if (c=A&c10) result=(int)(c-A+10); else result=-1; else result=-1; return result;void scan_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;void scan_suffix() /扫描浮点数后缀 scan_fraction(); if(ch=f|ch=F|ch=d|ch=D) put_ch(ch); get_ch();type=T_FLOAT;return;bool is_spectial(char &ch)/判断字符是否是特殊字符if(ch=!|ch=%|ch=&|ch=*|ch=?|ch=+|ch=-|ch=:|ch=|ch=|ch=|ch=)return true;elsereturn false;void scan_operator()/扫描运算符 while (is_spectial(ch) put_ch(ch); get_ch(); get_type(sbuf);if(type=0)type=T_ERROR;return;void scan_number(int radix)/扫描8、10、16进制数值 while(digit(radix)=0) put_ch(ch); get_ch(); if(radix!=10&ch=.) put_ch(ch); get_ch(); type=T_ERROR; else if(radix=10&ch=.)put_ch(.);get_ch();if(digit(10)=0)scan_suffix();else if(radix=10&(ch=e|ch=E|ch=f|ch=F|ch=d|ch=D)scan_suffix();else if(ch = l | ch = L)put_ch(ch);get_ch(); type=T_INT;else type=T_INT;return;void skip_comment()/跳过注释内容 while(ch!=0) switch(ch) case *: get_ch(); if (ch=/) get_ch(); return; break; default: get_ch(); break; bool is_idchar(char &ch)/判断字符是否标识符首字符return(ch=0&ch=A&ch=a&ch=z)|ch=$|ch=_);void scan_ident()/搜索关键字、标识符bool id_or_key = true;bool tem=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;elseget_type(sbuf);if(type!=0)return;else type=T_IDENTIFIER;return; void scan_char()/转义字符搜索字符 int oct = 0; int hex = 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=A&ch=a&ch=0) scan_suffix(); else type=T_BOUND; return; else if(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); else if(digit(8)=0&ch!=0)scan_number(8); else if(ch=.) put_ch(.);get_ch(); if(digit(10)=0) scan_suffix(); else if(ch= ) get_ch();type=T_INT;else type=T_ERROR;return;else if(1=ch&ch=9)/1-9开头数字 scan_number(10); return;else if(ch=()|(ch=)|(ch=)|(ch=)/9个界限符中的8个put_ch(ch); get_ch(); type = T_BOUND; return;else if(ch=,) put_ch(ch); get_ch(); type = T_COMMA; return;else if(ch=)|(ch=) put_ch(ch); get_ch(); type = T_BRACKET; return;else if(ch=;) put_ch(ch); get_ch(); type = T_SEMICOLON; return; else if(ch=/)/注释、/运算符、 /=运算符 get_ch(); if(ch=/) while(ch!=C_CR&ch!=C_LF&ch!=0) get_ch(); break; else if(ch=*) get_ch(); skip_comment(); else if(ch=) strcpy(sbuf, /=); type=T_ASSIGN; get_ch(); else strcpy(sbuf, /); type=T_MULDIV; return;else if(is_spectial(ch)/特殊字符scan_operator();return;else get_ch();/间隔符void readfile(char * fn_in)/将源文件读入缓冲区rp = 0;inFile.open(fn_in); if (!inFile.is_open() return; while(inFile.get(rbufrp) rp+; inFile.close();rp = 0;void writefile()/向输出文件写字符sp = 0; outFile (0x hex type ) ; outFile ;while(sbufsp!=0) outFile sbufsp;sp+; outFile ; outFile endl;sp = 0;int main(int argc, char * argv) char fn_inNAMESIZE; char fn_outNAMESIZE;cout fn_in;readfile(fn_in);cout fn_out;outFile.open(fn_out);get_ch();while(ch!=0) get_word();if(strlen(sbuf)!=0)writefile();outFile.close();cout The analysis has been completed! endl;system(pause); return 0;三.程序执行流程 a.首先从Java文件中读取半个缓冲区的字符串读入预处理缓冲区中,将缓冲区中的注释、空行、空格全部处理,最后预处理缓冲区里面只剩下单词、一个空格、换行; b.将预处理缓冲区里面的的数据分两次读入两对半缓冲区ScanBuffer中,送入词法分析器wordScanner进行逐个单词分析,由wordScanner调用相应的转换函数进行单词属性的分析。四.心得体会 不知经历了几个不眠之夜,前后一共花了将近两星期时间Java词法分析器终于横空出世。回想这两个礼拜的艰苦历程,一开始真不知道如何下手,真是块烫手的芋头,徘徊挣扎了两天,最后横下一条心:拼了! 从预处理缓冲区开始着手,一个模块就花了一天时间,BUG仍旧阴魂不散,郁闷之中,只能另辟蹊径,直入主题,先实现分析一类单词的功能,标识符。char *keyWordOrIdentifierOrBool( char *word ),首先想到的是这么多字母还有数字怎么处理,总不能一个个switchcase吧,于是我想到把所有字母和数字先用函数dealChar()处理一下,把所有字母统一归为a,数字归为8,这样就好办多了,期间又花了将近两天时间,改了又改,测了又测,终于喜见眉梢“哇咔咔。!”。接下来就是依葫芦画瓢了,相继攻克了其它各个功能,花了三天时间,差不多是时候了,最后压轴的是数字的处理,我处理的比较简单。最后的调试阶段是比较揪心的,程序各个功能的实现基本正常,最要命的还是那个预处理缓冲区,我是一串串读入的,所以处理起来比挨个读入的要困难得多,悔不该当初用fgets,不过路已

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论