《编译原理》实验报告班级:计C104姓名:李云霄学号:108490实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。
二、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。
输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。
输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
三、实现方法与环境1、首先设计识别各类单词的状态转换图。
描述无符号常数的确定、最小化状态转换图如图1所示。
其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。
图1 文法G[<无符号数>]的状态转换图其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。
在一个程序设计语言中,一般都含有若干类单词符号,为此可首先为每类单词建立一张状态转换图,然后将这些状态转换图合并成一张统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。
四则运算算术符号的识别很简单,直接在状态图的0状态分别引出相应标记的矢根据描述语言中各类单词的文法状态转换图或状态矩阵,利用某种语言(C语言或JAVA语言)直接编写词法分析程序。
3、词法分析程序测试用于测试扫描器的实例源文件中应有词法正确的,也应有错误的字符串,对于输入的测试用例的源程序文件,以对照的形式将扫描器的分析结果信息在输出文件中表示出来。
四、实验源程序#include"stdafx.h"#include<stdio.h>#include<string>char test[100],comp[100];char ch;int num,p;void scan();void main(){p=0;printf("Please input string and Use '#' as an finish operator :\n");do{scanf_s("%c",&ch);test[++p]=ch;}while(ch!='#');p=0;ch=test[++p];while(ch=='\n' || ch==' ')ch=test[++p];while(m){switch(ch){case '0':scan();break;case '1':scan();break;case '2':scan();break;case '3':scan();break;case '4':scan();break;case '5':scan();break;case '6':scan();break;case '7':scan();break;case '8':scan();break;case '9':scan();break;case '+':num=2;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;case '-':num=3;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;case '*':num=4;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;case '/':num=5;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;case '(':num=6;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;case ')':num=7;printf("\n(类别码:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;case '#':m=0;break;default :num=0;printf("\n(非法符号:%d,值:%c)",num,ch);comp[m++]=ch;ch=test[++p];break;}}}void scan(){int m=0;while(ch>='0'&&ch<='9'){comp[m++]=ch;ch=test[++p];if(ch=='E'|| ch=='e'){comp[m++]=ch;ch=test[++p];comp[m++]=ch;ch=test[++p];}if(ch=='.'){comp[m++]=ch;ch=test[++p];}}num=1;printf("\n(类别码:%d,值:%s)",num,comp);for (int n=m;n>=0;n--)comp[n]='\0';}五、实验过程六、实验结果七、实验心得实验一很艰难:我一眼就能看出来的事,破电脑愣是读不出来总结:程序来自网络,截图绝对原创。
实验二语法分析程序实现一、实验目的与要求通过设计、编制、调试典型的SLR(1)语法分析程序,实现对实验一所得词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
二、实验内容选择对各种常见高级程序设计语言都较为通用的语法结构无符号数的算术四则运算作为分析对象,给出其文法描述(注意应与所采用的语法分析方法比较贴近),设计并实现一个完整的语法分析程序。
输入:由实验一输出的单词类别串,如1,3,1。
输出:对于所输入的源程序,如果输入符号串是给定文法定义的合法句子,则输出“RIGHT”,并且给出每一步归约的过程;如果不是句子,即输入串有错误,则输出“ERROR”,并且显示已经归约出的各个文法符号,以及必要的出错说明信息。
三、实现方法与环境1、首先根据算术四则运算的语法定义,构造SLR(1)分析表。
无符号数的算术四则运算的语法可表示为:E->E+T| E-T|TT->T*F| T/F|FF->(E)|i2、语法分析程序编写设置输入缓冲区、状态栈、符号栈,并根据SLR(1)分析表利用某种语言(C语言或JAVA语言)直接编写移进、归约、接受子程序,编写语法分析程序。
3、语法分析程序测试用于测试的实例源文件中应有语法正确的,也应有语法错误的符号串,以对照的形式将分析结果信息在输出文件中表示出来。
四、实验源程序#include"StdAfx.h"#include<iostream>#include<string.h>#define MAX 150 //词洙法ぁ分?析?表括的?最?大洙容╕量?#define MAXBUF 255 //缓o冲?区?的?最?大洙缓o冲?量?void term();void lrparser();void statement();void yucu();void expression();void factor();char prog[MAXBUF],token[MAX];char ch;int syn,p,m,n,sum,kk;char * rwtab[6]={"begin","if","then","while","do","end"};///////////////////////////////////////////////////////////*词洙法ぁ扫Α描â程ì序î:阰*/void scaner(){for(m=0;m<MAX;m++)token[m]=NULL;m=0;sum=0;ch=prog[p++];while(ch==' ')ch=prog[p++];if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')){while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0')) {token[m++]=ch;}token[m++]='\0';ch=prog[--p];syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0) {syn=n+1; //给?出?syn值μbreak;}}elseif((ch<='9'&&ch>='0')){sum=0;while((ch<='9'&&ch>='0')){sum=sum*10+ch-'0';ch=prog[p++];}ch=prog[--p];syn=11;}elseswitch(ch)case'<':m=0;token[m++]=ch; ch=prog[p++];if(ch=='>'){syn=21;token[m++]=ch;}elseif(ch=='='){syn=22;token[m++]=ch; }else{syn=20;ch=prog[--p]; }break;case'>':token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24;token[m++]=ch;}else{syn=23;}break;case':':token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18;token[m++]=ch;}else{syn=17;ch=prog[--p];}break;case'+':syn=13;token[0]=ch;break;case'-':syn=14;token[0]=ch;break;case'*':syn=15;token[0]=ch;break;case'/':syn=16;token[0]=ch;break;case':=':syn=18;token[0]=ch;break;case'<>':syn=21;token[0]=ch;break;case'<=':syn=22;token[0]=ch;break;case'>=':syn=24;token[0]=ch;break;case'=':syn=25;token[0]=ch;break;case';':syn=26;token[0]=ch;break;case'(':syn=27;token[0]=ch;break;case')':syn=28;token[0]=ch;break;case'#':syn=0;token[0]=ch;break;default:syn=-1;break;}}/////////////////////////////////////////////////////// void statement(){if (syn==10){scaner(); //读á下?一?个?单蹋词洙符?号?if (syn==18){scaner(); //读á下?一?个?单蹋词洙符?号? expression(); //调獭用?expression函ˉ数簓}else{printf("error!");kk=1;}}else{printf("error!");kk=1;}return;}//////////////////////////////////////////////////////// void expression(){term();while(syn==13 || syn==14){scaner();term();}return;}/////////////////////////////////////////////////////// void term(){factor();while(syn==15 || syn==16){scaner();factor();}return;}////////////////////////////////////////////////////// void lrparser(){if (syn==1) //begin{scaner();yucu();if (syn==6) //end{scaner();if (syn==0 && kk==0) printf("success \n");}else{if(kk!=1) printf("error,lose 'end' ! \n");kk=1;}}else{printf("error,lose 'begin' ! \n");kk=1;}return;}/////////////////////////////////////////////////////void yucu(){statement();while(syn==26) //;{scaner();statement();}return;}/////////////////////////////////////////////////////void factor(){if(syn==10 || syn==11) scaner(); //为a标括识?符?或î整?常£数簓时骸,?读á下?一?个?单蹋词洙符?号?else if(syn==27){scaner();expression();if(syn==28) scaner();else {printf(" ')' 错洙误ï\n"); kk=1;}}else { printf("表括达?式?错洙误ï\n"); kk=1;}return;}////////////////////////////////////////////////////void main(){p=0;printf("********************语?法ぁ分?析?程ì序î***************\n"); printf("请?输?入?源′程ì序î:\n");do{ scanf_s("%c",&ch);prog[p++]=ch;}while(ch!='#');p=0;scaner();lrparser();printf("语?法ぁ分?析?结á束?!?\n");}五、实验过程六、实验结果(1)输入字符串begin x:=2*y end #其结果如下图所示:(2)输入的字符串少了begin,则会有提示信息:(3)输入的字符串的括号不全,也会有提示信息:七、实验心得实验二,改错的截图只截了几个,改错越改越多,一度改到128个错误,还好,改完了总结:能做出结果来,全靠同学帮助,再加上运气实验三语义分析程序实现一、实验目的与要求通过设计、编制、调试一个简单的语义处理分析程序,实现对实验一和实验二所得单词和语句的语义信息简单处里,进一步掌握语义处理的内容和简单方法。