词法分析程序实验报告(共9页).docx
精选优质文档-倾情为你奉上词法分析程序实验报告一、 实验内容设计并实现C语言的词法分析程序,要求如下:1) 可以识别C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词。2) 可以统计并读取源程序中的注释。3) 可以统计源程序中的语句行数、单词个数和字符个数,并输出统计结果。其中回车换行不计入字符个数,空格不计算为单词。4) 检查源程序中存在的错误,并可以报告错误所在的行列位置。5) 发现源程序中存在错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。二、 程序特色1) 全部实现上述实验要求2) 标识符规则符合标准C语言要求,允许以下划线开头,并包含下划线3) 可识别C语言允许的所有无符号实数形式,包括整数和浮点数。其中浮点数可包含指数e或E,并遵循C语言允许省略整数部分(如.5表示0.5)或省略小数部分(如2.E2表示2.0*102)4) 可识别几乎C语言所有标点符号和运算符,共计50个5) 可正确识别字符和字符串中的转义字符,如和“abcd”均可识别为单词不完整,并指出错误的行和列6) 可识别C语言的两种注释,/和/*/,其中/*/按照C语言要求允许跨越多行三、 语言说明1) 标识符:以字母或下划线开头,后跟字母、数字或下划线组成的字符串2) 关键字:C语言所有32个关键字3) 无符号数:C语言所允许的所有十进制实数形式,包括整数和浮点数。其中浮点数包括C语言允许的省略整数部分(如.5表示0.5)和省略小数部分(如2.E2表示2.0*102)4) 算数运算符:+、+、-、-、*、/、%5) 赋值运算符:=、+=、-=、*=、/=、%=、&=、|=、=6) 关系运算符:<、<=、=、>=、>、!=7) 逻辑运算符:&&、|、!8) 位运算符:&、|、<<、>>9) 其他符号:->、.、#、(、)、?、:、,、;、10) 字符:以单引号开始,以单引号结束,不能跨越多行11) 字符串:以双引号开始,以双引号结束,不能跨越多行12) 注释:以/开始到行末,或者以/*开始,以*/结束,可以跨越多行四、 运行环境CodeBlocks-13.12 with GCC compiler from TDM-GCC (4.7.1, 32 bit)五、 输入形式命令行界面,指定C语言源文件作为输入六、 输出形式1) 所有标识符写入指定的符号表文件2) 分离出一个单词后,对识别出的记号以二元式的形式输出到用户指定文件,其形式为< 记号,属性 >记号属性记号属性IDkeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeykeynumarith-oparith-oparith-oparith-oparith-oparith-oparith-op符号表序号autodoubleintstructbreakelselongswitchcaseenumregistertypedefcharexternreturnunionconstfloatshortunsignedcontinueforsignedvoiddefaultgotosizeofvolatiledoifstaticwhile实数值+-*/%asgn-opasgn-opasgn-opasgn-opasgn-opasgn-opasgn-opasgn-opasgn-oprel-oprel-oprel-oprel-oprel-oprel-oplog-oplog-oplog-opbit-opbit-opbit-opbit-opbit-opbit-opothersothersothersothersothersothersothersothers others othersothers others others others charstringcomments=+=-=*=/=%=&=|=<<=>=>!=&&|!&|<<>>->.#()?:,;字符字面量字符串字面量-七、 主要数据结构vector<string> table; /字符串向量,临时存储符号表set<string> keywords; /字符串集合,存放所有关键字string buffer; /输入缓冲区,存放文件的一行string token; /字符串,存放当前单词string:iterator forward; /字符串buffer的迭代器,向前扫描字符八、 核心算法1) 识别无符号数的有限状态自动机s0s23starts1s4s5s6Errordigite/Edigitdigitothers.digitothersdigitdigitdigit+/-/* 由上图构造相应的无符号数识别子程序 */void get_digits() while(forward != buffer.end() && notEnd) switch(state) case 1: if(*forward = '.') state = 23; else if(*forward = 'E'|'e') state = 4; else if(isdigit(*forward) state = 1; else notEnd = fasle; break; case 23: if(*forward = 'E'|'e') state = 4; else if(isdigit(*forward) state =23; else notEnd = false; break; case 4: if(*forward = '+'|'-') state = 6; else if(isdigit(*forward) state = 5; else Error;notEnd = false; break; case 5: if(isdigit(*forward) state = 5; else notEnd = false; break; case 6: if(isdigit(*forward) state = 5; elseError;notEnd = false; break; default:break; 2) /* 读取一个字符后,如果是语言所定义的单词符号的开始字符,则转移到相应的识别识别过程,否则进入错误处理状态 */int main() init; open infile, outfile, tablefile; while (true) if (getline(infile, buffer, 'n') = true) +line; cnt_char += column; column = 0;forward = buffer.begin(); else cnt_char += column; write table to tablefile; close infile, outfile, tablefile; output to console; get_nbc; switch (C) case 'a'.'z','A'.'Z','_': token.append; while(digit | letter | '_') token.append; if(iskey) table_insert(); outfile << "key" else outfile << "ID" break; case '0'.'9': token.append; state = 1; get_digits(); state = 0; outfile << "num" break; case '+','-','*','%': token.append; +forward; if(*forward = '=') outfile << "asgn-op" else outfile << "arith-op" break; case '/': token.append; +forward; if(*forward = '=') outfile << "asgn-op" else if(*forward = '/') while(forward != buffer.end() read comments; outfile << "comments" else if(*forward = '*') if(get_comments() outfile << "comments" else close infile, outfile, tablefile; else outfile << "arith-op" break; case '&','|','': token.append; +forward; if(*forward = '=') outfile << "asgn-op" else if(*forward = *(forward-1) outfile << "log-op" else outfile << "bit-op" break; case '': token.append; +forward; outfile << "bit-op" break; case '<', '>': token.append; +forward; if(*forward = '=') token.append; outfile << "rel-op" else if(*forward = *(forward-1) token.append; outfile << "bit-op" else outfile << "rel-op" break; case '=': token.append; +forward; if(*forward = '=') outfile << "rel-op" else outfile << "asgn-op" break; case '!': token.append; +forward; if(*forward = '=') outfile << "rel-op" else outfile << "log-op" break; case '"': token.append; +forward; while(*forward != '"') token.append; +forward; if(*(forward-1) = '') token.append; +forward; if(forward = buffer.end() Error; else outfile << "string" break; case ''': token.append; +forward; while(*forward != ''') token.append; +forward; if(*(forward-1) = '') token.append; +forward; if(forward = buffer.end() Error; else outfile << "char" break; case '.': token.append; +forward; if(isdigit) get_digits(); outfile << "num" break; outfile << "others" break; case '#': case '': case '': case '': case '': case '(': case ')': case '?': case ':': case ',': case '': case '': token.append; +forward; outfile << "others" break; default: Error; 专心-专注-专业