编译原理的一些练习题

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
View Code

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   
View Code

-----------------------------------

题目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
View Code

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; 
    }
} 
View Code

-----------------------------------

题目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
View Code

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 } 
View Code

----------------------------------

题目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

以上是关于编译原理的一些练习题的主要内容,如果未能解决你的问题,请参考以下文章

编译原理习题解析-第1章

编译时,运行时解释

如何有条件地将 C 代码片段编译到我的 Perl 模块?

词法分析练习题编译原理

语法分析练习题5 LR规范的LR分析编译原理

词法分析练习题2 DFA极小化正则式转NFA编译原理