logo资料库

词法分析和语法分析报告.doc

第1页 / 共34页
第2页 / 共34页
第3页 / 共34页
第4页 / 共34页
第5页 / 共34页
第6页 / 共34页
第7页 / 共34页
第8页 / 共34页
资料共34页,剩余部分请下载后查看
编译原理词法分析和语法分析报告+代码(C 语言版)[1] 词法分析 一、实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实 验要求 2.1 待分析的简单的词法 (1)关键字: begin if then while do end 所有的关键字都是小写。 (2)运算符和界符 : = + - * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit* (4)空格有空白、制表符和换行符组成。空格一般用来分隔 ID、SUM、运算符、 界符和关键字,词法分析阶段通常被忽略。 2.2 各种单词符号对应的种别码: 表 2.1 各种单词符号对应的种别码 单词符号 种别码 单词符号 种别码 bgin 1 : 17 If 2 := 18 Then 3 < 20 wile 4 <> 21
do 5 <= 22 end 6 > 23 lettet(letter|digit)* 10 >= 24 dight dight* 11 = 25 + 13 ; 26 — 14 ( 27 * 15 ) 28 / 16 # 0 2.3 词法分析程序的功能: 输入:所给文法的源程序字符串。 输出:二元组(syn,token 或 sum)构成的序列。 其中:syn 为单词种别码; token 为存放的单词自身字符串; sum 为整型常数。 例如:对源程序 begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过 词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)„„ 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号, 其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 3.1 主程序示意图: 主程序示意图如图 3-1 所示。其中初始包括以下两个方面: ? 关键字表的初 值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表), 当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键 字,否则为一般标识符。关键字表为一个字符串数组,其描述如下:
Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,}; 置初值 调用扫描子程序 输出单词二元组 否 输入串结束 是 结束 图 3-1 (2)程序中需要用到的主要变量为 syn,token 和 sum 3.2 扫描子程序的算法思想: 首先设置 3 个变量:?token 用来存放构成单词符号的字符串;?sum 用来整型单 词;?syn 用来存放单词符号的种别码。扫描子程序主要部分流程如图 3-2 所示。 变量初始化 忽略空格 是 是 是否文件结束, 返回 否 字母 数字 其他 拼字符串 运算符、 符号 界符等符号 拼数 否 是否关键字, 对不同符号给报错 是
出相应的 syn 值 syn=10 syn 为对应关键字的 syn=11 单词种别码 11 返回 图 3-2 四、词法分析程序的 C 语言程序源代码: #include #include char prog[80],token[8],ch; int syn,p,m,n,sum; char *rwtab[6]={"begin","if","then","while","do","end"}; scaner(); main() {p=0; printf("\n please input a string(end with '#'):/n"); do{ scanf("%c",&ch); prog[p++]=ch; }while(ch!='#'); p=0; do{ scaner(); switch(syn) {case 11:printf("( %-10d%5d )\n",sum,syn); break; case -1:printf("you have input a wrong string\n"); getch();
exit(0); default: printf("( %-10s%5d )\n",token,syn); break; } }while(syn!=0); getch(); } scaner() { sum=0; for(m=0;m<8;m++)token[m++]=NULL; ch=prog[p++]; m=0; while((ch==' ')||(ch=='\n'))ch=prog[p++]; if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))) { while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&& (ch<='9'))) {token[m++]=ch; ch=prog[p++]; } p--; syn=10; for(n=0;n<6;n++) if(strcmp(token,rwtab[n])==0) { syn=n+1;
break; } } else if((ch>='0')&&(ch<='9')) { while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0'; ch=prog[p++]; } p--; syn=11; } else switch(ch) { case '<':token[m++]=ch; ch=prog[p++]; if(ch=='=') { syn=22; token[m++]=ch; } else { syn=20; p--; } break; case '>':token[m++]=ch;
ch=prog[p++]; if(ch=='=') { syn=24; token[m++]=ch; } else { syn=23; p--; } break; case '+': token[m++]=ch; ch=prog[p++]; if(ch=='+') { syn=17; token[m++]=ch; } else { syn=13; p--; } break; case '-':token[m++]=ch; ch=prog[p++]; if(ch=='-')
{ syn=29; token[m++]=ch; } else { syn=14; p--; } break; case '!':ch=prog[p++]; if(ch=='=') { syn=21; token[m++]=ch; } else { syn=31; p--; } break; case '=':token[m++]=ch; ch=prog[p++]; if(ch=='=') { syn=25; token[m++]=ch; }
分享到:
收藏