编译原理简单语法分析
2018-03-04 22:34
323 查看
一、实验目的:
了解掌握算符优先分析的基本方法、内容;
学会科学思考并解决问题,提高程序设计能力。
二、实验内容与要求:
用算符优先分析方法设计一个分析解释程序,对输入的赋值语句、输出语句、清除语句进行词法分析、语法分析、表达式求值并存储于指定变量中;若存在错误,提示错误相关信息。
三、文法表示:
S→v=E|E?|clear
E→E+T|E-T|T
T→T*F|T/F|F
F→ (E)|v|c
四、设计思路:
(1) 设计存储数据结构char *VN=0,*VT=0;//非终结符和终结符数组char firstvt
,lastvt
,table
;typedef struct //符号对(P,a){ char Vn; char Vt;} VN_VT;typedef struct //栈{ VN_VT *top; VN_VT*bollow; int size;}stack;
(2) 根据文法求FIRSTVT集和LASTVT集
(3) 构造算符优先分析表
(4) 构造总控程序
五、程序代码:#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<stack>#include<map>#include<set>#include<algorithm>#include<string>#include<cstdlib>#include<cctype>#defineMAX507#define_CRT_SECURE_NO_WARNINGScodeusingnamespacestd; classWF{public: stringleft; vector<string>right; WF(conststring&str) { left=str; } voidinsert(charstr[]) { right.push_back(str); } voidprint() { printf("%s->%s",left.c_str(),right[0].c_str()); for(inti=1;i<right.size();i++) printf("|%s",right[i].c_str()); puts(""); }}; charrelation[MAX][MAX];vector<char>VT;vector<WF>VN_set;map<string,int>VN_dic;set<char>first[MAX];set<char>last[MAX];intused[MAX];intvis[MAX]; voiddfs(intx){ if(vis[x])return; vis[x]=1; string&left=VN_set[x].left; for(inti=0;i<VN_set[x].right.size();i++) { string&str=VN_set[x].right[i]; if(isupper(str[0])) { inty=VN_dic[str.substr(0,1)]-1; if(str.length()>1&&!isupper(str[1])) first[x].insert(str[1]); dfs(y); set<char>::iteratorit=first[y].begin(); for(;it!=first[y].end();it++) first[x].insert(*it); } else first[x].insert(str[0]); }} voidmake_first(){ memset(vis,0,sizeof(vis)); for(inti=0;i<VN_set.size();i++) if(vis[i])continue; elsedfs(i);#defineDEBUG#ifdefDEBUG puts("------------FIRSTVT集-------------------"); for(inti=0;i<VN_set.size();i++) { printf("%s : ",VN_set[i].left.c_str()); set<char>::iteratorit=first[i].begin(); for(;it!=first[i].end();it++) printf("%c ",*it); puts(""); }#endif} voiddfs1(intx){ if(vis[x])return; vis[x]=1; string&left=VN_set[x].left; for(inti=0;i<VN_set[x].right.size();i++) { string&str=VN_set[x].right[i]; intn=str.length()-1; if(isupper(str[n])) { inty=VN_dic[str.substr(n,1)]-1; if(str.length()>1&&!isupper(str[n-1])) last[x].insert(str[1]); dfs1(y); set<char>::iteratorit=last[y].begin(); for(;it!=last[y].end();it++) last[x].insert(*it); } else last[x].insert(str[n]); }} voidmake_last(){ memset(vis,0,sizeof(vis)); for(inti=0;i<VN_set.size();i++) if(vis[i])continue; elsedfs1(i);#defineDEBUG#ifdefDEBUG puts("--------------LASTVT集---------------------"); for(inti=0;i<VN_set.size();i++) { printf("%s : ",VN_set[i].left.c_str()); set<char>::iteratorit=last[i].begin(); for(;it!=last[i].end();it++) printf("%c ",*it); puts(""); }#endif} voidmake_table(){ for(inti=0;i<MAX;i++) for(intj=0;j<MAX;j++) relation[i][j]=' '; for(inti=0;i<VN_set.size();i++) for(intj=0;j<VN_set[i].right.size();j++) { string&str=VN_set[i].right[j]; for(intk=0;k<str.length()-1;k++) { if(!isupper(str[k])&&!isupper(str[k+1])) relation[str[k]][str[k+1]]='='; if(!isupper(str[k])&&isupper(str[k+1])) { intx=VN_dic[str.substr(k+1,1)]-1; set<char>::iteratorit=first[x].begin(); for(;it!=first[x].end();it++) relation[str[k]][*it]='<'; } if(isupper(str[k])&&!isupper(str[k+1])) { intx=VN_dic[str.substr(k,1)]-1; set<char>::iteratorit=last[x].begin(); for(;it!=last[x].end();it++) relation[*it][str[k+1]]='>'; } if(k>str.length()-2)continue; if(!isupper(str[k])&&!isupper(str[k+2])&&isupper(str[k+1])) relation[str[k]][str[k+2]]='='; } }#defineDEBUG#ifdefDEBUG for(inti=0;i<VT.size()*5;i++) printf("-"); printf("算符优先关系表"); for(inti=0;i<VT.size()*5;i++) printf("-"); puts(""); printf("|%8s|",""); for(inti=0;i<VT.size();i++) printf("%5c%5s",VT[i],"|"); puts(""); for(inti=0;i<(VT.size()+1)*10;i++) printf("-"); puts(""); for(inti=0;i<VT.size();i++) { printf("|%4c%5s",VT[i],"|"); for(intj=0;j<VT.size();j++) printf("%5c%5s",relation[VT[i]][VT[j]],"|"); puts(""); for(inti=0;i<(VT.size()+1)*10;i++) printf("-"); puts(""); }#endif} intmain(){ intn; chars[MAX]; while(~scanf("%d",&n)) { memset(used,0,sizeof(used)); for(inti=0;i<n;i++) { scanf("%s",s); intlen=strlen(s),j; for(j=0;j<len;j++) if(s[j]=='-') break; s[j]=0; if(!VN_dic[s]) { VN_set.push_back(WF(s)); VN_dic[s]=VN_set.size(); } intx=VN_dic[s]-1; VN_set[x].insert(s+j+2); for(intk=0;k<j;k++) if(!isupper(s[k])) { if(used[s[k]])continue; used[s[k]]=1; VT.push_back(s[k]); } for(intk=j+2;k<len;k++) if(!isupper(s[k])) { if(used[s[k]])continue; VT.push_back(s[k]); used[s[k]]=VT.size(); } }#defineDEBUG#ifdefDEBUG puts("************VT集*******************"); for(inti=0;i<VT.size();i++) printf("%c ",VT[i]); puts(""); puts("*************产生式*****************"); for(inti=0;i<VN_set.size();i++) VN_set[i].print(); puts("************************************");#endif make_first(); make_last(); make_table(); }
}
了解掌握算符优先分析的基本方法、内容;
学会科学思考并解决问题,提高程序设计能力。
二、实验内容与要求:
用算符优先分析方法设计一个分析解释程序,对输入的赋值语句、输出语句、清除语句进行词法分析、语法分析、表达式求值并存储于指定变量中;若存在错误,提示错误相关信息。
三、文法表示:
S→v=E|E?|clear
E→E+T|E-T|T
T→T*F|T/F|F
F→ (E)|v|c
四、设计思路:
(1) 设计存储数据结构char *VN=0,*VT=0;//非终结符和终结符数组char firstvt
,lastvt
,table
;typedef struct //符号对(P,a){ char Vn; char Vt;} VN_VT;typedef struct //栈{ VN_VT *top; VN_VT*bollow; int size;}stack;
(2) 根据文法求FIRSTVT集和LASTVT集
(3) 构造算符优先分析表
(4) 构造总控程序
五、程序代码:#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<stack>#include<map>#include<set>#include<algorithm>#include<string>#include<cstdlib>#include<cctype>#defineMAX507#define_CRT_SECURE_NO_WARNINGScodeusingnamespacestd; classWF{public: stringleft; vector<string>right; WF(conststring&str) { left=str; } voidinsert(charstr[]) { right.push_back(str); } voidprint() { printf("%s->%s",left.c_str(),right[0].c_str()); for(inti=1;i<right.size();i++) printf("|%s",right[i].c_str()); puts(""); }}; charrelation[MAX][MAX];vector<char>VT;vector<WF>VN_set;map<string,int>VN_dic;set<char>first[MAX];set<char>last[MAX];intused[MAX];intvis[MAX]; voiddfs(intx){ if(vis[x])return; vis[x]=1; string&left=VN_set[x].left; for(inti=0;i<VN_set[x].right.size();i++) { string&str=VN_set[x].right[i]; if(isupper(str[0])) { inty=VN_dic[str.substr(0,1)]-1; if(str.length()>1&&!isupper(str[1])) first[x].insert(str[1]); dfs(y); set<char>::iteratorit=first[y].begin(); for(;it!=first[y].end();it++) first[x].insert(*it); } else first[x].insert(str[0]); }} voidmake_first(){ memset(vis,0,sizeof(vis)); for(inti=0;i<VN_set.size();i++) if(vis[i])continue; elsedfs(i);#defineDEBUG#ifdefDEBUG puts("------------FIRSTVT集-------------------"); for(inti=0;i<VN_set.size();i++) { printf("%s : ",VN_set[i].left.c_str()); set<char>::iteratorit=first[i].begin(); for(;it!=first[i].end();it++) printf("%c ",*it); puts(""); }#endif} voiddfs1(intx){ if(vis[x])return; vis[x]=1; string&left=VN_set[x].left; for(inti=0;i<VN_set[x].right.size();i++) { string&str=VN_set[x].right[i]; intn=str.length()-1; if(isupper(str[n])) { inty=VN_dic[str.substr(n,1)]-1; if(str.length()>1&&!isupper(str[n-1])) last[x].insert(str[1]); dfs1(y); set<char>::iteratorit=last[y].begin(); for(;it!=last[y].end();it++) last[x].insert(*it); } else last[x].insert(str[n]); }} voidmake_last(){ memset(vis,0,sizeof(vis)); for(inti=0;i<VN_set.size();i++) if(vis[i])continue; elsedfs1(i);#defineDEBUG#ifdefDEBUG puts("--------------LASTVT集---------------------"); for(inti=0;i<VN_set.size();i++) { printf("%s : ",VN_set[i].left.c_str()); set<char>::iteratorit=last[i].begin(); for(;it!=last[i].end();it++) printf("%c ",*it); puts(""); }#endif} voidmake_table(){ for(inti=0;i<MAX;i++) for(intj=0;j<MAX;j++) relation[i][j]=' '; for(inti=0;i<VN_set.size();i++) for(intj=0;j<VN_set[i].right.size();j++) { string&str=VN_set[i].right[j]; for(intk=0;k<str.length()-1;k++) { if(!isupper(str[k])&&!isupper(str[k+1])) relation[str[k]][str[k+1]]='='; if(!isupper(str[k])&&isupper(str[k+1])) { intx=VN_dic[str.substr(k+1,1)]-1; set<char>::iteratorit=first[x].begin(); for(;it!=first[x].end();it++) relation[str[k]][*it]='<'; } if(isupper(str[k])&&!isupper(str[k+1])) { intx=VN_dic[str.substr(k,1)]-1; set<char>::iteratorit=last[x].begin(); for(;it!=last[x].end();it++) relation[*it][str[k+1]]='>'; } if(k>str.length()-2)continue; if(!isupper(str[k])&&!isupper(str[k+2])&&isupper(str[k+1])) relation[str[k]][str[k+2]]='='; } }#defineDEBUG#ifdefDEBUG for(inti=0;i<VT.size()*5;i++) printf("-"); printf("算符优先关系表"); for(inti=0;i<VT.size()*5;i++) printf("-"); puts(""); printf("|%8s|",""); for(inti=0;i<VT.size();i++) printf("%5c%5s",VT[i],"|"); puts(""); for(inti=0;i<(VT.size()+1)*10;i++) printf("-"); puts(""); for(inti=0;i<VT.size();i++) { printf("|%4c%5s",VT[i],"|"); for(intj=0;j<VT.size();j++) printf("%5c%5s",relation[VT[i]][VT[j]],"|"); puts(""); for(inti=0;i<(VT.size()+1)*10;i++) printf("-"); puts(""); }#endif} intmain(){ intn; chars[MAX]; while(~scanf("%d",&n)) { memset(used,0,sizeof(used)); for(inti=0;i<n;i++) { scanf("%s",s); intlen=strlen(s),j; for(j=0;j<len;j++) if(s[j]=='-') break; s[j]=0; if(!VN_dic[s]) { VN_set.push_back(WF(s)); VN_dic[s]=VN_set.size(); } intx=VN_dic[s]-1; VN_set[x].insert(s+j+2); for(intk=0;k<j;k++) if(!isupper(s[k])) { if(used[s[k]])continue; used[s[k]]=1; VT.push_back(s[k]); } for(intk=j+2;k<len;k++) if(!isupper(s[k])) { if(used[s[k]])continue; VT.push_back(s[k]); used[s[k]]=VT.size(); } }#defineDEBUG#ifdefDEBUG puts("************VT集*******************"); for(inti=0;i<VT.size();i++) printf("%c ",VT[i]); puts(""); puts("*************产生式*****************"); for(inti=0;i<VN_set.size();i++) VN_set[i].print(); puts("************************************");#endif make_first(); make_last(); make_table(); }
}
相关文章推荐
- 编译原理-简单的语法分析示例
- 编译原理 实验3 递归下降语法分析程序设计
- 编译原理——语法分析程序的设计
- 编译原理语法分析LR1
- 编译原理之词法分析、语法分析、语义分析
- 编译原理之词法分析和语法分析
- 编译原理_常量定义语句语法分析
- 编译原理词/语法分析
- 编译原理语法分析(文本输入)源程序
- 设计有穷自动机DFA实现C++简单程序的词法分析、扫描(编译原理实验) 推荐
- 编译原理_常量定义语句语法分析
- 语法分析_编译原理
- 编译原理结构框架5自底向上的语法分析
- 关于Basic程序解释器及编译原理的简单化(1)---Basic器的语法分析及主要代码
- 跟vczh看实例学编译原理——三:Tinymoe与无歧义语法分析
- 编译原理之算符优先分析语法程序
- 一个简单的编译原理词法语法语义分析程序
- 编译原理--递归下降语法分析源代码(C Language)
- 编译原理-词法分析-语法分析-语义分析生成中间代码-python版
- 编译原理简单词法分析