编译原理的一些练习题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编译原理的一些练习题相关的知识,希望对你有一定的参考价值。
这里收集了sicily的陈炬桦老师编译原理实验课程的题目,曝上代码以供参考。
(如果这里的代码对您的思路有些许启发的话,请您点击一下推荐,给予作者写作的鼓励,不胜感谢!)
1-词法分析
题目1000:
1 1000. 词法分析程序设计 2 总提交数量: 183 通过数量: 138 3 4 时间限制:1秒 内存限制:256兆 5 题目描述 6 设一语言的关键词、运算符、分界符的个数与单词如下: 7 struct { int number; string str[10]; } keywords={3,"int","main","return"} ; //关键词 8 struct { int number; string str[10]; } operators ={5,"+","*","=","+=","*="}; //运算符 9 struct { int number; string str[10]; } boundaries ={6,"(",")","{","}",",",";"} ; //分界符 10 struct { int number; string str[100];} identifieres={0}; //标识符 11 struct { int number; string str[100];} Unsigned_integer={0}; //无符号整数 12 以上类号分别为1~5,序号从0开始; 13 标识符是字母开头的字母数字串;常量为无符号整数; 14 用C++设计一程序实现词法分析。 15 16 输入格式 17 输入一程序,结束符用”#”; 18 19 输出格式 20 输出单词数对:<类号,序号>。 输出标识符表,用空格分隔; 输出无符号整数表,用空格分隔; 21 22 样例输入 23 将样例输入复制到剪贴板 24 main() 25 { int a=2,b=3; 26 return 2*b+a; 27 }# 28 样例输出 29 <1,1><3,0><3,1><3,2><1,0><4,0><2,2><5,0><3,4><4,1><2,2><5,1><3,5><1,2><5,0><2,1> 30 <4,1><2,0><4,0><3,5><3,3> 31 identifieres:a b 32 Unsigned_integer:2 3
AC代码:
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 struct { int number; string str[10]; } keywords={3,"int","main","return"} ; //关键词 6 struct { int number; string str[10]; } operators ={5,"+","*","=","+=","*="}; //运算符 7 struct { int number; string str[10]; } boundaries ={6,"(",")","{","}",",",";"} ; //分界符 8 struct { int number; string str[100];} identifieres={0}; //标识符 9 struct { int number; string str[100];} Unsigned_integer={0}; //无符号整数 10 11 char k=0; 12 string st=""; 13 int main(){ 14 int i; char ch; bool nochar=1; 15 16 do{ 17 if(nochar)cin.get(ch); 18 if(ch==‘(‘){st+="<3,0>";nochar=1;} 19 else if(ch==‘)‘){ st+="<3,1>";nochar=1; } 20 else if(ch==‘{‘){ st+="<3,2>";nochar=1; } 21 else if(ch==‘}‘){ st+="<3,3>";nochar=1; } 22 else if(ch==‘,‘){ st+="<3,4>";nochar=1; } 23 else if(ch==‘;‘){ st+="<3,5>";nochar=1; } 24 else if(ch==‘+‘){ 25 cin.get(ch); 26 if(ch==‘=‘){ 27 st+="<2,3>";nochar=1; 28 } 29 else{ 30 st+="<2,0>";nochar=1; 31 } 32 } 33 else if(ch==‘*‘){ 34 cin.get(ch); 35 if(ch==‘=‘){ 36 st+="<2,4>";nochar=1; 37 } 38 else{ 39 st+="<2,1>";nochar=1; 40 } 41 } 42 else if(ch==‘=‘){ 43 st+="<2,2>";nochar=1; 44 } 45 else if(‘0‘<=ch&&ch<=‘9‘){ 46 string nstring=""; nochar=0; 47 do{ 48 nstring+=ch; 49 cin.get(ch); 50 } while(‘0‘<=ch&&ch<=‘9‘); 51 for(k=0;k<Unsigned_integer.number&&Unsigned_integer.str[k]!=nstring;k++ ); 52 53 if(k==Unsigned_integer.number ){ 54 Unsigned_integer.str[k] = nstring; 55 st+="<5,";st+=char(‘0‘+k); st+=">"; 56 Unsigned_integer.number++; 57 } 58 else{ 59 st+="<5,";st+=char(‘0‘+k);st+=">"; 60 } 61 } 62 else if(‘a‘<=ch&&ch<=‘z‘||‘A‘<=ch&&ch<=‘Z‘){ 63 string nstring="";nochar=0; 64 do{ 65 nstring+=ch; 66 cin.get(ch); 67 } while(‘a‘<=ch&&ch<=‘z‘||‘A‘<=ch&&ch<=‘Z‘) ; //读入关键字或者标示符的东西 68 69 for(k=0;k<= keywords.number &&keywords.str[k]!=nstring;k++ ); 70 if(k<keywords.number ){ 71 //测得输入字符是关键字之一 72 st+="<1,"; st+=char(‘0‘+k);st+=">"; 73 } 74 else{ 75 //测得输入字符不是关键字之一,而是标识符 76 for(k=0;k<identifieres.number && identifieres.str[k]!=nstring;k++ ); //检查是否是已经记录过的标识符 77 if(k==identifieres.number ){ //不是已经标识过的标识符 78 identifieres.str[k]=nstring; 79 st+="<4,";st=st+char(‘0‘+k);st+=">"; 80 identifieres.number++; 81 } 82 else{ 83 st+="<4,";st=st+char(‘0‘+k);st+=">"; 84 } 85 } 86 } 87 else nochar=1; 88 89 } while(ch!=‘#‘); 90 91 cout<<st<<endl; 92 cout<<"identifieres:"; 93 for(i=0;i<identifieres.number;i++ ){cout<<identifieres.str[i]<<" ";} cout<<endl; 94 cout<<"Unsigned_integer:"; 95 for(i=0;i<Unsigned_integer.number;i++ ){cout<<Unsigned_integer.str[i]<<" ";} cout<<endl; 96 97 return 0; 98 } 99
-----------------------------------
题目1001:
1 1001. 输入输出文法1 2 总提交数量: 95 通过数量: 53 3 4 时间限制:1秒 内存限制:256兆 5 题目描述 6 7 8 设文法的非终结符,终结符,产生式为,开始符号为 9 struct { int Nv;string VN[10];} Vns={3,"E","T","F"}; 10 struct { int Nt;string VT[10];} Vts={7,"+","-","*","/","(",")","i"}; 11 struct { int Np;string PL[20],PR[20];} ps={0}; 12 string S="E"; 13 14 输入产生式的个数, 15 分别输入产生式的左边和右边符号 16 17 按非终结符顺序输出产生式 18 输入格式 19 8 20 E E+T 21 T T*F 22 E T 23 T F 24 F (E) 25 F i 26 E E-T 27 T T/F 28 29 输出格式 30 G[E]: 31 E::=E+T | T | E-T 32 T::=T*F | F | T/F 33 F::=(E) | i 34 35 样例输入 36 将样例输入复制到剪贴板 37 6 38 E E+T 39 T T*F 40 E T 41 T F 42 F (E) 43 F i 44 样例输出 45 G[E]: 46 E::=E+T | T 47 T::=T*F | F 48 F::=(E) | i
AC代码:
#include <iostream> #include <string> using namespace std; struct { int Nv;string VN[10];} Vns={3,"E","T","F"}; struct { int Nt;string VT[10];} Vts={7,"+","-","*","/","(",")","i"}; struct { int Np;string PL[20],PR[20];} ps={0}; string S="E"; int main(){ int num; cin>>num; num++; string temp; int k; string result[Vns.Nv]; while(num--){ getline(cin,temp); for(k=0;k<Vns.Nv;k++ ){ if(temp.substr(0,1)==Vns.VN[k] ) { result[k]+=temp.substr(2) + " | "; break; } } } for(k=0;k<Vns.Nv;k++){ result[k] = result[k].substr(0,result[k].length()-3 ); } cout<<"G["<<S<<"]:\\n"; for(k=0;k<Vns.Nv;k++){ cout<<Vns.VN[k]<<"::="<<result[k]<<endl; } }
-----------------------------------
题目1002:
1 1002. 输入输出文法2 2 总提交数量: 76 通过数量: 53 3 4 时间限制:1秒 内存限制:256兆 5 题目描述 6 输入开始符号,非终结符,终结符,产生式 7 按非终结符顺序输出产生式; 8 9 输入格式 10 输入开始符号; 11 非终结符个数,非终结符,空格符分隔; 12 终结符个数,终结符,空格符分隔; 13 产生式的个数,各产生式的左边和右边符号,空格符分隔; 14 15 输出格式 16 G[开始符号]: 17 按非终结符顺序输出各产生式; 18 19 样例输入 20 将样例输入复制到剪贴板 21 Z 22 8 Z E F P G T Q S 23 3 + * i 24 18 25 Z E+T 26 E E 27 P G 28 F F 29 P G 30 G G 31 T T*i 32 Q E 33 S i 34 E S+F 35 F FP 36 G GG 37 Q E+F 38 E T 39 F P 40 G F 41 Q T 42 Q S 43 样例输出 44 G[Z]: 45 Z::=E+T 46 E::=E | S+F | T 47 F::=F | FP | P 48 P::=G | G 49 G::=G | GG | F 50 T::=T*i 51 Q::=E | E+F | T | S 52 S::=i
AC代码:
1 #include <iostream> 2 #include <string> 3 #include <stdlib.h> 4 using namespace std; 5 6 struct { int Nv;string VN[10];} Vns={0}; 7 struct { int Nt;string VT[10];} Vts={0}; 8 struct { int Np;string PL[20],PR[20];} ps={0}; 9 string S=""; 10 11 int main(){ 12 cin>>S; 13 cin>>Vns.Nv ; 14 for(int i=0;i<Vns.Nv;i++ ){ 15 cin>>Vns.VN[i]; 16 } 17 18 cin>>Vts.Nt ; 19 for(int i=0;i<Vts.Nt;i++ ){ 20 cin>>Vts.VT[i] ; 21 } 22 23 int num; cin>>num; num++; 24 string temp; int k; 25 string result[Vns.Nv]; 26 while(num--){ 27 getline(cin,temp); 28 for(k=0;k<Vns.Nv;k++ ){ 29 if(temp.substr(0,1)==Vns.VN[k] ) { 30 result[k]+=temp.substr(2) + " | "; 31 break; 32 } 33 } 34 } 35 for(k=0;k<Vns.Nv;k++){ 36 result[k] = result[k].substr(0,result[k].length()-3 ); 37 } 38 39 cout<<"G["<<S<<"]:\\n"; 40 for(k=0;k<Vns.Nv;k++){ 41 cout<<Vns.VN[k]<<"::="<<result[k]<<endl; 42 } 43 }
----------------------------------
题目1003:
1 1003. 输入文法压缩自产生式文法和不可达文法 2 总提交数量: 122 通过数量: 59 3 4 时间限制:1秒 内存限制:256兆 5 题目描述 6 输入开始符号,非终结符,终结符,产生式 7 压缩自产生式文法和不可达文法后,按非终结符顺序输出产生式; 8 9 输入格式 10 11 输入开始符号; 12 非终结符个数,非终结符,空格符分隔; 13 终结符个数,终结符,空格符分隔; 14 产生式的个数,各产生式的左边和右边符号,空格符分隔; 15 16 输出格式 17 18 delete self production:自产生式文法 19 unreached Vn:不可达非终结符 20 delete production:不可达产生式 21 delete VN:不可达非终结符 22 G[开始符号]: 23 压缩自产生式文法和不可达文法后,按非终结符顺序输出各产生式; 24 25 样例输入 26 将样例输入复制到剪贴板 27 Z 28 8 Z E F P G T Q S 29 3 + * i 30 18 31 Z E+T 32 E E 33 P G 34 F F 35 P G 36 G G 37 T T*i 38 Q E 39 S i 40 E S+F 41 F FP 42 G GG 43 Q E+F 44 E T 45 F P 46 G F 47 Q T 48 Q S 49 样例输出 50 delete self production:E::=E 51 delete self production:F::=F 52 delete self production:G::=G 53 unreached Vn:Q 54 delete production:Q::=E 55 delete production:Q::=E+F 56 delete production:Q::=T 57 delete production:Q::=S 58 delete VN:Q 59 G[Z]: 60 Z::=E+T 61 E::=S+F | T 62 F::=FP | P 63 P::=G | G 64 G
以上是关于编译原理的一些练习题的主要内容,如果未能解决你的问题,请参考以下文章