C语言词法分析器_内容说明注释完整_可运行代码.doc
1. 实验目的及要求 本次实验通过用 C 语言 设计、编制、调试一个词法分析子程序,识别单词,实现一个 C 语言词法分析器,经过此过程可以加深对编译器解析单词流的过程的了解。 运行环境运行环境 硬件windows xp 软件visual c6.0 2. 实验步骤 1.查询资料,了解词法分析器的工作过程与原理。 2.分析题目,整理出基本设计思路。 3.实践编码,将设计思想转换用 c 语言编码实现,编译运行。 4.测试功能,多次设置包含不同字符,关键字的待解析文件,仔细察看运行结果,检测该分 析器的分析结果是否正确。 通过最终的测试发现问题, 逐渐完善代码中设置的分析对象与关 键字表,拓宽分析范围提高分析能力。 3. 实验内容 本实验中将 c 语言单词符号分成了四类关键字 key(特别的将 main 说明为主函数) 、 普通标示符、常数和界符。将关键字初始化在一个字符型指针数组*key中,将界符分别由 程序中的 case 列出。在词法分析过程中,关键字表和case 列出的界符的内容是固定不变的 (由程序中的初始化确定) ,因此,从源文件字符串中识别出现的关键字,界符只能从其中 选取。标识符、常数是在分析过程中不断形成的。 对于一个具体源程序而言, 在扫描字符串时识别出一个单词, 若这个单词的类型是关键 字、普通标示符、常数或界符中之一,那么就将此单词以文字说明的形式输出每次调用词 法分析程序,它均能自动继续扫描下去,形成下一个单词,直到整个源程序全部扫描完毕, 从而形成相应的单词串。 输出形式例如void 关键字 流程图流程图 、程序、程序 流程图 开始 输入源文 件路径 路径是否有 效 是 初始化文件指针 否 将字符加入字符数 组Word 是空格,空白或换 行吗 是字母吗是数字吗否否是界符吗否 打开源文件 跳过该字符 是 是 文件结束 否 将字符加入字符数 组Word 否 将字符 加入字 符数组 Word 是 指向下一字符 识别指针内容 指向下一字符 是字母惑数字 吗 是 将word与关键 字表key进行匹 配 否 匹配 是 输出word 为关键字 输出word为 普通标示符 否 将字符加 入字符数 组Word 指向下一字符 输出word 为常数 识别指针内容 回退 是数字吗 是 否 输出word 为界符 指向下一字符 结束是 输出Word 内容为不 可识别 将字符 加入字 符数组 Word 程序 include include include include 定义关键字 char *Key10“main“,“void“,“int“,“char“,“printf“,“scanf“,“else“,“if“,“return“; char Word20,ch; 存储识别出的单词流 int IsAlphachar c 判断是否为字母 ifcacA return 1; else return 0; int IsNumchar c 判断是否为数字 ifc0 else return 0; int IsKeychar *Word 识别关键字函数 int m,i; fori0;i9;i ifmstrcmpWord,Keyi0 ifi0 return 2; return 1; return 0; void scannerFILE *fp 扫描函数 char Word200 int i,c; chfgetcfp; 获取字符,指针 fp 并自动指向下一个字符 ifIsAlphach 判断该字符是否是字母 Word0ch; chfgetcfp; i1; whileIsNumchIsAlphach 判断该字符是否是字母或数字 Wordich; i; chfgetcfp; Wordi00 代表字符结束空格 fseekfp,-1,1; 回退一个字符 cIsKeyWord; 判断是否是关键字 ifc0 printf“st普通标识符nn“,Word;不是关键字 else ifc2 printf“st主函数nn“,Word; else printf“st关键字nn“,Word; 输出关键字 else 开始判断的字符不是字母 ifIsNumch 判断是否是数字 Word0ch; chfgetcfp; i1; whileIsNumch Wordich; i; chfgetcfp; Wordi0 快快快快快快快快可 回退 printf“st无符号实数nn“,Word; else 开始判断的字符不是字母也不是数字 Word0ch; switchch case case case case case case case, case“ caseprintf“st界符nn“,Word; break; casechfgetcfp; Word1ch; ifch printf“st运算符nn“,Word;运算符“” else ifch printf“st运算符nn“,Word; 判断结果为“” else fseekfp,-1,1; printf“st运算符nn“,Word; 判断结果为“” break; case-chfgetcfp; Word1ch; ifch printf“st运算符nn“,Word; else ifch- printf“st运算符nn“,Word; 判断结果为“” else fseekfp,-1,1; printf“st运算符nn“,Word; 判断结果为“-” break; case* case/ case casechfgetcfp; ifch printf“st运算符nn“,Word; else fseekfp,-1,1; printf“st运算符nn“,Word; break; casechfgetcfp; Word1ch; ifch printf“st运算符nn“,Word; 判断结果为运算符 “” else ifch printf“st运算符nn“,Word; 判断结果为“” else fseekfp,-1,1; printf“st运算符nn“,Word; 判断结果为“chfgetcfp; Word1ch; ifch printf“st运算符nn“,Word; else fseekfp,-1,1; printf“st运算符nn“,Word; break; casechfgetcfp; Word1ch; ifchprintf“st运算符nn“,Word; ifIsAlphach printf“st类型标识符nn“,Word; else fseekfp,-1,1; printf“st取余运算符nn“,Word; break; defaultprintf“无法识别字符nn“; break; main char in_fn30; 文件路径 FILE *fp; printf“n 请输入源文件名(包括路径和后缀名)“; while1 getsin_fn; scanf“s“,in_fn; iffpin_fn,“r“NULL break; 读取文件内容,并返回文件指针,该 指针指向文件的第一个字符 else printf“文件路径错误请重新输入“; printf“n* 词法分析结果如下 *n“; do chfgetcfp; ifch break; 文件以结尾,作为扫描结束条件 else ifch chtchn 忽略空格,空白,和换行 else fseekfp,-1,1; 回退一个字节开始识别单词流 scannerfp; whilech; return0; 4.实验结果 解析源文件 void main int a3; ab; printf“d“,a; return; 解析结果 5.实验总结分析 通过本次实验,让再次浏览了有关 c 语言的一些基本知识,特别是对文件,字符串进行 基本操作的方法。C 语言中没有 string 类型,因此本实验中的对字符串提取与识别均借助 include及字符型数组来实现。 让我练习对字符串函数应用的同时也提高了自己 的逻辑思维能力。 在本次实验中,我纠正了一个一直以来的概念错误main 不是关键字,它定义为程序 的入口,是主函数在本实验中,虽然我把 main 初始化在关键字表 (字符指针类型数组)*Key10中,当与该数组中字符串进行比较时,若与 main 匹配成功, 则返回 2,若为其他关键字则返回 1,以此来把 main 从关键字中区别出来。 在本实验中的关键字表只初始化了几个常用的关键字, 还可继续扩充 (只需扩大数组, 向其中补充要添加的关键字) 。 如果要对本程序中未识别的 c 语言中的一些其他的字符进行扩充(目前处理为不可识别字 符) ,可在程序代码中继续添加 case 选项,分别对相应要识别的特殊字符加以描述