编译原理报告 (6)
- 格式:doc
- 大小:675.50 KB
- 文档页数:12
1.词法分析 1.1实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 1.2 实验要求 1.待分析的简单语言的词法 (1)关键字:begin if then while do end 所有的关键字都是小写 (2)运算符和界符::= + - * 、 < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义: ID=letter(letter|digit)* NUM=digit digit* (4)空格由空白、制表符和换行符组成。空格一般用来分隔ID,NUM、运算符、界符、和关键字,词法分析阶段通常被忽略。 2.各种单词符号对应的种别码
表1 各种单词符号对应的种别码
单词符号 种别码 begin 1 if 2 then 3 while 4 do 5 end 6 letter(letter|digit)* 10 digit digit* 11 + 13 - 14 * 15 / 16
单词符号 种别码 : 17 := 18 < 20 <> 21 <= 22 > 23 >= 24 = 25 ; 26 ( 27 ) 28 # 0 3.词法分析程序的功能 输入:所给文法的源程序字符串 输出:二元组(syn,token或sum)构成的序列。 其中syn为单词的种别码;token为存放的单词自身字符串;sum为整型常量。 例如 :源程序 begin x:=9;if x>0 then x:=2*x+1/3;end# 的源文件,经词法分析后输出序列如下: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)...
1.3 语法分析的程序设计思想 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描的单词符号的第一个字种类,拼出相应的单词符号。 1.主程序示意图 主程序示意图如图1所示。其中初值包括如下两个方面。 (1)关键字表的初值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(成为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: char * rwtab[6]={“begin”,”if”,”then”,”while”,”do”,”end”}; (2)程序中需要用到的主要变量为syn,token和sum. 2.扫描子程序的算法思想 首先设置3个变量,1. token用来构成单词符号的字符串;2. sum用来存放整形单词 3.syn用来存放单词符号的种别码。扫描子程序的主要流程部分如图2所示。
置初值
输出单词二元组输出串结束?结束
调用扫描子程序否是 图1 词法分析主程序示意图 变量初始化
忽略空格是否文件结束?拼数syn=11返回返回
对不同符号给出相应的syn值报错
拼字符串
是否为关键字?
syn为对应关键字的单词种别码
Syn=10
其他符号运算符、
界符等符号
否数字字母
否是
图2.词法分析程序流程 1.4函数与使用说明 char input[255];/*输入缓冲区*/ char token[255]="";/*单词缓冲区*/ int p_input;/*输入缓冲区指针*/ int p_token; /*单词缓冲区指针*/ char ch;/*当前读入字符*/ /*可扩充的关键数组*/ char * rwtab[]={"begin","if","then","while","do","end",_KEY_WORD_END}; typedef struct /*单词二元组的结构,可以根据需要继续扩充*/ { int typenum; char * word; }WORD; WORD * scaner();/*词法扫描函数,获得一个单词*/ char m_getch();/*需要用到的自编函数从缓冲区读取的一个字符到ch中*/ void getbc();/*去掉空白符号*/ void concat();/*拼接单词*/ int letter();/*判断是否是字母*/ int digit();/*判读是否为数字*/ int reserve();/*检索关键字表格*/ void retract();/*回退一个字符*/
1.5实验与体会 本实验首先要求输入源程序存入到输入缓冲区中。然后不断地读取源程序。根据构成规则,标识符必须是以字母开头的,即 ID=letter(letter|digit)*。 则在scaner函数的匹配规则中,当其判断是否为标识符,会首先判断读入的第一个字符,如果其为字母,则继续判断直至把该字符串读取完毕,直至读取的字符不为字母或数字,则读取完毕,然后对其与单词符号进行匹配,确定其为关键字还是标识符。匹配结束,退回一个字符。这样每次再进行匹配时都需要读入一个新字符,起点相同。若是第一次读入的是数字,则下次匹配的只能是数字,当读入的不是数字时,退回一个字符,确定读入的字符串为数字。然后重新匹配。其他的会根据事先约定好的算符进行匹配。在这里仅有词法的分析,机械性的匹配,所以当出现“123abc234”时,匹配的字符串为两个,“123”和“abc234”。
1.6程序执行结果
图3运行结果 图4运行结果 2.语法分析 2.1实验目的 编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
2.2实验要求 利用C语言编制的递归下降分析程序,并对简单语言进行语法分析。 1.待分析的简单语言的语法 用扩充的BNF表示如下: (1)::=beginend (2)::={;} (3)::= (4)::=ID:= (5)::={+|-} (6)::={*|/} (7)::=ID|NUM|() 2.实验要求说明 输入单词串,以“#”结束,如果文法正确的句子,则输出成功的信息,打印“success”,否则输出“error”。 例如: 输入 begin a:=9;x:=2*3;b:=a+x end # 输出 success 输入 x:=a+b*c end # 输出 error
2.3语法分析程序的算法思想 (1)主程序示意图如图3所示。 (2)递归下降分析示意图如图4所示。 (3)语句串分析过程示意图如图5所示。 (4)Statement语句分析函数流程图如图6、图7、图8、图9所示。 置初值调用scaner读下一个单词符号调用IrParser结束 图5 语法分析主程序示意图
是否begin?调用scaner调用语句串分析函数
调用end?
Syn=0&&kk=0?调用scaner
打印分析成功出错处理
否是
否是
否是 图6 递归下降分析程序示意图 调用statement函数是否:?调用scaner调用statement函数出错处理否是 图7 语句串分析示意图
是否标识符?调用scaner
是否:+?调用scaner调用expression出错处理
否是
否是
图8 statement语句分析示意图 调用term函数是否+,-?调用scaner调用term函数出错处理
否是
图9 expression表达式分析函数示意图 调用factor函数
是否*,/调用scaner调用factor出错处理
否
是
图10 term分析函数示意图 是否标识符?是否整常数?
是否(?调用scaner调用expression
是否)?调用scaner出错处理
调用scaner
否否 图11 factor分析过程示意图 2.4函数与使用说明 语法分析是在语义分析的基础上做的,故在词法分析里介绍的函数这里不再重复介绍,仅对新出现的函数做结束 int Irparser(); /*本函数开始对语句串的分析,其先判断以一个输入的是否为“begin”关键字,若是的话调用yucu()函数*/ int Irparser(){ if(oneword->typenum==1){ oneword=scaner(); yucu(); if(oneword->typenum==6){ oneword=scaner(); if(oneword->typenum==1000&&(kk==0)) printf("success");
}else{if(kk!=1) printf("缺'end'错误;");kk=1;} }else{ printf("输出'begin'错误");kk=1; } return 0; }