当前位置:文档之家› 南航金城学院编译原理课程设计杨阳教的

南航金城学院编译原理课程设计杨阳教的

产生式主程序:Program-> main () {DefList; StmtList}定义变量:DefList-> Def; DefListDefList-> DefDef-> Type IDListType-> intType-> floatIDList-> id, IDListIDList-> id定义语句:StmtList-> Stmt; StmtListStmtList-> Stmt;赋值语句:Stmt-> id:=E条件分支语句Stmt-> if (BE) {StmtList} else {StmtList}算数表达式:(1) 自上而下分析法(2) 自下而上分析法E-> TE’E-> TE’-> +TE’E-> E+TE’-> εT-> FT-> FT’T-> T*FT’-> *FT’F-> (E)T’-> εF-> idF-> (E) F-> numF-> id F-> floatnumF-> intnumF-> floatnum布尔表达式:BE-> id < idBE-> id > idBE-> id = idBE-> id < intnumBE-> id > intnumBE-> id = intnum课程设计要实现的内容:(1)设计词法分析器设计各单词的状态转换图,并为不同的单词设计种别码。

功能包括:a. 能够拼出语言中的各个关键字、运算符和界符;b. 能够识别出标识符和不同类型的常量;c. 能对输入的一段文本程序输出其词法成分的各种别编码和属性值(对关键字,输出其种别编码,属性值为空;对常量,输出其种别编码和常量的值;对变量,输出其种别编码和变量名)。

(2)语法分析要求用递归下降分析法、LL(1)分析法或SLR(1)分析法,对词法分析的结果进行语法分析。

(实现对标识符表的插入和查找,见(3))若语法正确,则输出一棵语法树。

若语法错误,则报错。

(3)设计标识符表,并实现一定的语义分析(可选)标识符表应至少包括名字栏和数据类型栏。

在语法分析中:对在声明语句中出现的关于标识符的声明,如果该名字在符号表中不存在,则将其加入到符号表中,并将数据类型填入。

若名字已经存在被声明过,则报错。

对一般语句中出现的标识符,可以查找标识符表,若标识符不在表中,则报错。

验收要求1、有标识符表的构造说明文档(可选)2、有种别编码表的说明文档3、有词法分析的DFA图4、若使用了递归下降分析法需要有根据产生式构造的first/follow集、若使用了LL(1)分析法需要有预测分析表,若使用了SLR(1)分析法需要有SLR(1)分析表5、有可执行的源程序,能输出词法分析的结果、语法分析的语法树(和标识符表)源程序:#include <iostream>#include<string>using namespace std;#include<stdio.h>#include<stdlib.h>#include<sstream>int i,j,k,flag,number,status,m=0,n=0,d,dian;//d为在计算小数时除以0.1的次数/*status which is use to judge the string is keywords or not!*/char ch;float number1;char words[10] = {" "};char program[500];int flags[500]; //存储输入句子string cnt[500];//标识符int temp=0; //数组下标int is_right=1; //判断输出信息char num[500];//-----------------------词法分析-----------------------------int Scan(char program[]){char *keywords[9] = {"int","char","float","if","else","do","while","printf","main"}; //关键字number=0;status=0;j=0;ch=program[i++];//遍历while(ch==' '||ch=='\n') //跳过空字符(无效输入)ch=program[i++];if ((ch >= 'a') && (ch <= 'z' )) //字母{while ((ch >= 'a') && (ch <= 'z' )){words[j++]=ch;ch=program[i++];}i--;words[j++] = '\0';for (k = 0; k < 9; k++)if (strcmp (words,keywords[k]) == 0) //判断是否为关键字switch(k){case 0:{flag = 1;status = 1;break;}case 1:{flag = 2;status = 1;break;}case 2:{flag = 3;status = 1;break;}case 3:{flag = 4;status = 1;break;}case 4:{flag = 5;status = 1;break;}case 5:{flag = 6;status = 1;break;}case 6:{flag = 7;status = 1;break;}case 7:{flag = 8;status = 1;break;}case 8:{flag = 9;status = 1;break;}}if (status == 0){flag = 100; //标识符()}}else if ((ch >= '0') && (ch <= '9')||ch=='.') //数字(){dian=1;number = 0;number1=0;d=0;if(ch!='.'){while ((ch >= '0' ) && (ch <= '9' )){number = number*10+(ch-'0');ch = program[i++];}}//当ch=‘。

’时,就是小数.if(ch=='.'){dian=0;ch=program[i++];while((ch>='0')&&(ch<='9')){d++;number1=number1*10+(ch-'0');ch=program[i++];}}if(dian==1){flag = 200;}else{flag=201;}i--;}else switch (ch) //运算符和标点符号{case '=':{if (ch == '=')words[j++] = ch;words[j] = '\0';ch = program[i++];if (ch == '='){words[j++] = ch;words[j] = '\0';flag = 401;}else{i--;flag = 402;}break;}case'>':{if (ch == '>')words[j++] = ch;words[j] = '\0';ch = program[i++];if (ch == '='){words[j++] = ch;words[j] = '\0';flag = 403;}else{i--;flag = 404;}break;}case'<':{if (ch == '<') words[j++] = ch; words[j] = '\0';ch = program[i++]; if (ch == '='){words[j++] = ch; words[j] = '\0'; flag = 405;}else{i--;flag = 406;}break;}case'!':{if (ch == '!') words[j++] = ch; words[j] = '\0';ch = program[i++]; if (ch == '='){words[j++] = ch; words[j] = '\0'; flag = 407;}else{i--;flag = 408;}break;}case'+':{if (ch == '+') words[j++] = ch; words[j] = '\0';ch = program[i++]; if (ch == '='){words[j++] = ch; words[j] = '\0'; flag = 409;}else if (ch == '+') {words[j++] = ch; words[j] = '\0'; flag = 410;}else{i--;flag = 411;}break;}case'-':{if (ch == '-') words[j++] = ch; words[j] = '\0';ch = program[i++]; if (ch == '='){words[j++] = ch; words[j] = '\0'; flag = 412;}else if( ch == '-') {words[j++] = ch; words[j] = '\0'; flag = 413;}else{i--;flag = 414;}break;}case'*':{if (ch == '*') words[j++] = ch; words[j] = '\0';ch = program[i++]; if (ch == '='){words[j++] = ch; words[j] = '\0'; flag = 415;}else{i--;flag = 416;}break;}case'/':{if (ch == '/') words[j++] = ch; words[j] = '\0';ch = program[i++]; if (ch == '='){words[j++] = ch; words[j] = '\0'; flag = 417;}else{i--;flag = 418;}break;}case'^':{words[j] = ch; words[j+1] = '\0'; flag = 419;break;}case';':{words[j] = ch; words[j+1] = '\0'; flag = 501; break;}case'(':{words[j] = ch; words[j+1] = '\0'; flag = 502; break;}case')':{words[j] = ch; words[j+1] = '\0'; flag = 503; break;}case'[':{words[j] = ch; words[j+1] = '\0'; flag = 504; break;}case']':{words[j] = ch; words[j+1] = '\0'; flag = 505; break;}case'{':{words[j] = ch; words[j+1] = '\0'; flag = 506; break;}case'}':{words[j] = ch; words[j+1] = '\0'; flag = 507; break;}case':':{words[j] = ch; words[j+1] = '\0'; flag = 508; break;}case'"':{words[j] = ch; words[j+1] = '\0'; flag = 509; break;}case'%':{if (ch == '%') words[j++] = ch; words[j] = '\0';ch = program[i++]; if (ch == '='){words[j++] = ch; words[j] = '\0'; flag = 510;}else{i--;flag = 511;}break;}case',':{words[j] = ch; words[j+1] = '\0';break;}case'#':{words[j] = ch;words[j+1] = '\0';flag = 513;break;}case'@':{words[j] = ch;words[j+1] = '\0';flag = 514;break;}case' '://空格{words[j] ='_';words[j+1] = '\0';flag = 515;break;}case'$':{words[j] = '#';words[j+1] = '\0';flag = 0;break;}default:{flag = -1;break;}}return flag;}//------------------语法分析(递归下降)--------------------------- void E();void E1();void T1();void F();void E(){cout<<"S->TE' "<<endl;T();E1();}void E1(){if(flags[temp]==411){cout<<"S'->+E"<<endl;temp++;T();E1();}}void T(){cout<<"T->FT'"<<endl;F();T1();}void T1(){if(flags[temp]==416){cout<<"T'->*F"<<endl;temp++;F();T1();}}void F(){if(flags[temp]==100||flags[temp]==200||flags[temp]==201){cout<<"F->"<<cnt[temp]<<endl;temp++;}else if(flags[temp]==502){cout<<"F->("<<endl;temp++;E();if(flags[temp]==503){cout<<"F->)"<<endl;temp++;if(flags[temp]==0||flags[temp]==501){is_right=1;temp++;}}else is_right=0;}else is_right =0;}void main(){int i=0,num=0;cout<<"请输入测试程序或者表达式,以$结束"<<endl;do{ch =getchar();program[i++] = ch;}while(ch != '$');i = 0;cout<<"词法分析:"<<endl;do{flag = Scan(program);//词法分析if (flag == 200){cout<<"("<<flag<<","<<number<<")"<<endl;flags[num]=flag;stringstream stream;stream<<number;stream>>cnt[num];stream.clear();num++;}else if(flag==201){for(i=d;i>0;i--){number1=number1*0.1;}number1=number1+number;cout<<"("<<flag<<","<<number1<<")"<<endl; flags[num]=flag;stringstream stream;stream<<number;stream>>cnt[num];stream.clear();num++;}else if (flag == -1){cout<<"error!"<<endl;}else{cout<<"("<<flag<<","<<words<<")"<<endl;if(flag!=515){flags[num]=flag;cnt[num]=words;num++;}}}while (flag != 0);flags[num]=0;is_right=1;cout<<"语法分析:"<<endl;E();if(is_right){cout<<"分析成功"<<endl;}else{cout<<"分析失败"<<endl;}system("pause");}。

相关主题