【编译原理实验】递归子程序法

文法:

E->TG
G->+TG|-TG|^
T->FS
S->*FS|/FS|^
F->i|(E)

表达式串的每个数符必须以i代替(懒得优化)

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 using namespace std;
  6
  7
  8 int step_Counter=0;//计数第几步
  9 char in[82];//存储输入串
 10 char analized_str[82];int top=-1;//存储分析过的字符串
 11 char *ch;//指向当前正在分析的字符
 12 char * left_Function(char[]);//计算并返回剩余串的起始地址 老师请注意:left:剩余,不是左边
 13
 14 char finished_dri[82];int t_f=-1;//推导式中的已经完成分析的字符串和其栈顶指针
 15 char unfinished_dri[82];int t_uf=-1;//推到是中的未完成分析的字符串和其栈顶指针
 16 char record_div[10000];//记录推导过程的数组
 17 void add(char arr[],char arr1[]);//add方法将未完成部分的栈倒序装入record_div记录数组
 18
 19 int E();
 20 int T();
 21 int F();
 22 int S();
 23 int G();
 24
 25 int main()
 26 {
 27     cout<<"请输入长度不大于81的表达式:";
 28     cin>>in;
 29     //cout<<strlen(in)<<endl;
 30     char const_str[10]="分析串";
 31     printf("步骤\t文法\t%-40s分析字符\t剩余串\n",const_str);
 32     ch=in;
 33
 34     unfinished_dri[++t_uf]=‘E‘;//初始化非终结符栈
 35     strcat(record_div,"E\0");//记录第一条推导
 36
 37
 38     int flag=E();
 39     if(flag==0)
 40         cout<<endl<<"\t\t\tERROR !"<<endl;
 41     else
 42     {
 43         cout<<endl<<"\t\t\tACCEPT !"<<endl;
 44         cout<<"推导过程:"<<endl;
 45         cout<<record_div<<endl;
 46     }
 47     return 0;
 48 }
 49 int E()
 50 {
 51     t_uf--;//非终结符栈栈顶元素出栈
 52     unfinished_dri[++t_uf]=‘G‘;//非终结符倒序入非终结符栈
 53     unfinished_dri[++t_uf]=‘T‘;
 54
 55     unfinished_dri[t_uf+1]=‘\0‘;//给栈顶元素增加结束标识,以免出错
 56     strcat(record_div,"\n=>");//以下三条是记录推导的语句
 57     strcat(record_div,finished_dri);
 58     add(record_div,unfinished_dri);//因为非终结符栈是倒序的,所以不能直接使用strcat函数,要进行一次颠倒才能进行连接
 59     //以上解释使用于下面的几个函数,故不再解释
 60
 61
 62     step_Counter++;//标识第几步的变量
 63     analized_str[top+1]=‘\0‘;//为第一次调用此函数做准备
 64     char * left_str=left_Function(analized_str);//得到剩余串的起始地址
 65     printf("%d\tE=>TG\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);//格式打印输出
 66     //cout<<"调用了函数E"<<endl;
 67     if(*ch==‘#‘)
 68         return 1;
 69     int flag=T();
 70     if(flag==0)
 71         return 0;
 72     else
 73     {
 74         flag=G();
 75         if(flag==0)
 76             return 0;
 77         else
 78         {
 79             return 1;
 80         }
 81     }
 82 }
 83 int T()
 84 {
 85     t_uf--;
 86     unfinished_dri[++t_uf]=‘S‘;
 87     unfinished_dri[++t_uf]=‘F‘;
 88
 89     unfinished_dri[t_uf+1]=‘\0‘;
 90     finished_dri[t_f+1]=‘\0‘;
 91     strcat(record_div,"\n=>");
 92     strcat(record_div,finished_dri);
 93     add(record_div,unfinished_dri);
 94
 95
 96     step_Counter++;
 97     analized_str[top+1]=‘\0‘;
 98     char * left_str=left_Function(analized_str);
 99     printf("%d\tT=>FS\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);
100     //cout<<"调用了函数T"<<endl;
101     if(*ch==‘#‘)
102         return 1;
103     int flag=F();
104     if(flag==0)
105         return 0;
106     else
107     {
108         flag=S();
109         if(flag==0)
110             return 0;
111         else
112         {
113             return 1;
114         }
115     }
116 }
117 int F()
118 {
119     if(*ch==‘#‘)
120         return 1;
121     //cout<<"调用了函数F"<<endl;
122     if(*ch==‘i‘)
123     {
124         t_uf--;//未完成的部分栈顶出栈
125         finished_dri[++t_f]=‘i‘;//完成的部分入栈
126         unfinished_dri[t_uf+1]=‘\0‘;
127         finished_dri[t_f+1]=‘\0‘;
128         strcat(record_div,"\n=>");
129         strcat(record_div,finished_dri);
130         add(record_div,unfinished_dri);
131
132
133
134         top++;
135         analized_str[top]=‘i‘;
136         analized_str[top+1]=‘\0‘;
137         step_Counter++;
138         char * left_str=left_Function(analized_str);
139         printf("%d\tF=>i\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);
140         //cout<<++step_Counter<<"i匹配"<<endl;
141         ch++;
142         return 1;
143     }
144     else if(*ch==‘(‘)
145     {
146
147
148         t_uf--;//未完成的部分F栈顶出栈
149         finished_dri[++t_f]=‘(‘;//完成的部分入栈
150         unfinished_dri[++t_uf]=‘)‘;//未完成的部分倒序入栈
151         unfinished_dri[++t_uf]=‘E‘;//未完成的部分倒序入栈
152         unfinished_dri[t_uf+1]=‘\0‘;
153         finished_dri[t_f+1]=‘\0‘;
154         strcat(record_div,"\n=>");
155         strcat(record_div,finished_dri);
156         add(record_div,unfinished_dri);
157
158
159         top++;
160         analized_str[top]=‘(‘;
161         analized_str[top+1]=‘\0‘;
162         step_Counter++;
163         char * left_str=left_Function(analized_str);
164         printf("%d\tF=>(E)\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);
165         //cout<<++step_Counter<<"(匹配"<<endl;
166         ch++;
167         int flag=E();
168         if(flag==0)
169             return 0;
170         else
171         {
172             if(*ch==‘)‘)
173             {
174                 t_uf--;//完成部分出栈
175                 finished_dri[++t_f]=‘)‘;//完成部分入栈
176
177
178                 unfinished_dri[t_uf+1]=‘\0‘;
179                 finished_dri[t_f+1]=‘\0‘;
180                 strcat(record_div,"\n=>");
181                 strcat(record_div,finished_dri);
182                 add(record_div,unfinished_dri);
183
184                 top++;
185                 analized_str[top]=‘)‘;
186                 analized_str[top+1]=‘\0‘;
187                 step_Counter++;
188                 char * left_str=left_Function(analized_str);
189                 printf("%d\tF=>(E)\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);
190             //    cout<<++step_Counter<<")匹配"<<endl;
191                 ch++;
192                 return 1;
193             }
194             else
195                 return 0;
196         }
197     }
198     else
199     {
200         return 0;
201     }
202 }
203 int S()
204 {
205     //cout<<"调用了函数S"<<endl;
206     if(*ch==‘*‘)
207     {
208         t_uf--;//非终结符S出栈
209         finished_dri[++t_f]=‘*‘;//终结符入栈
210         unfinished_dri[++t_uf]=‘S‘;//非终结符倒序入栈
211         unfinished_dri[++t_uf]=‘F‘;
212         unfinished_dri[t_uf+1]=‘\0‘;
213         finished_dri[t_f+1]=‘\0‘;
214         strcat(record_div,"\n=>");
215         strcat(record_div,finished_dri);
216         add(record_div,unfinished_dri);
217
218
219
220         top++;
221         analized_str[top]=‘*‘;
222         analized_str[top+1]=‘\0‘;
223         step_Counter++;
224         char * left_str=left_Function(analized_str);
225         printf("%d\tS=>*FS\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);
226     //    cout<<++step_Counter<<"*匹配"<<endl;
227         ch++;
228         int flag=F();
229         if(flag==0)
230             return 0;
231         else
232         {
233             flag=S();
234             if(flag==1)
235                 return 1;
236             else
237                 return 0;
238         }
239     }
240     else if(*ch==‘/‘)
241     {
242         t_uf--;//非终结符S出栈
243         finished_dri[++t_f]=‘/‘;//终结符入栈
244         unfinished_dri[++t_uf]=‘S‘;
245         unfinished_dri[++t_uf]=‘F‘;
246         unfinished_dri[t_uf+1]=‘\0‘;
247         finished_dri[t_f+1]=‘\0‘;
248         strcat(record_div,"\n=>");
249         strcat(record_div,finished_dri);
250         add(record_div,unfinished_dri);
251
252
253         top++;
254         analized_str[top]=‘/‘;
255         analized_str[top+1]=‘\0‘;
256         step_Counter++;
257         char * left_str=left_Function(analized_str);
258         printf("%d\tS=>/FS\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);
259     //    cout<<++step_Counter<<"/匹配!"<<endl;
260         ch++;
261         int flag=F();
262         if(flag==0)
263             return 0;
264         else
265         {
266             flag=S();
267             if(flag==1)
268             return 1;
269             else
270                 return 0;
271         }
272     }
273     else
274     {
275         t_uf--;//非终结符S出栈
276         finished_dri[++t_f]=‘^‘;//终结符入栈
277         unfinished_dri[t_uf+1]=‘\0‘;
278         finished_dri[t_f+1]=‘\0‘;
279         strcat(record_div,"\n=>");
280         strcat(record_div,finished_dri);
281         add(record_div,unfinished_dri);
282
283
284         step_Counter++;
285         char * left_str=left_Function(analized_str);
286         printf("%d\tS=>^\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);
287         return 1;
288     }
289 }
290 int G()
291 {
292     //cout<<"调用了函数G"<<endl;
293     if(*ch==‘+‘)
294     {
295         t_uf--;//非终结符S出栈
296         finished_dri[++t_f]=‘+‘;//终结符入栈
297         unfinished_dri[++t_uf]=‘G‘;
298         unfinished_dri[++t_uf]=‘T‘;
299         unfinished_dri[t_uf+1]=‘\0‘;
300         finished_dri[t_f+1]=‘\0‘;
301         strcat(record_div,"\n=>");
302         strcat(record_div,finished_dri);
303         add(record_div,unfinished_dri);
304
305
306
307         top++;
308         analized_str[top]=‘+‘;
309         analized_str[top+1]=‘\0‘;
310         step_Counter++;
311         char * left_str=left_Function(analized_str);
312         printf("%d\tG=>+TG\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);
313     //    cout<<++step_Counter<<"+匹配"<<endl;
314         ch++;
315         int flag=T();
316         if(flag==0)
317             return 0;
318         else
319         {
320             flag=G();
321             if(flag==1)
322             return 1;
323             else
324                 return 0;
325         }
326     }
327     else if(*ch==‘-‘)
328     {
329
330         t_uf--;//非终结符S出栈
331         finished_dri[++t_f]=‘-‘;//终结符入栈
332         unfinished_dri[++t_uf]=‘G‘;
333         unfinished_dri[++t_uf]=‘T‘;
334         unfinished_dri[t_uf+1]=‘\0‘;
335         finished_dri[t_f+1]=‘\0‘;
336         strcat(record_div,"\n=>");
337         strcat(record_div,finished_dri);
338         add(record_div,unfinished_dri);
339
340
341
342         top++;
343         analized_str[top]=‘-‘;
344         analized_str[top+1]=‘\0‘;
345         step_Counter++;
346         char * left_str=left_Function(analized_str);
347         printf("%d\tG=>-TG\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);
348     //    cout<<++step_Counter<<"-匹配"<<endl;
349         ch++;
350         int flag=T();
351         if(flag==0)
352             return 0;
353         else
354         {
355             flag=G();
356             if(flag==1)
357             return 1;
358             else
359                 return 0;
360         }
361     }
362     else
363     {
364
365         t_uf--;
366         finished_dri[++t_f]=‘^‘;
367         unfinished_dri[t_uf+1]=‘\0‘;
368         finished_dri[t_f+1]=‘\0‘;
369         strcat(record_div,"\n=>");
370         strcat(record_div,finished_dri);
371         add(record_div,unfinished_dri);
372
373         step_Counter++;
374         char * left_str=left_Function(analized_str);
375         printf("%d\tG=>^\t%-40s%c\t\t%s\n",step_Counter,analized_str,*ch,left_str);
376         return 1;
377     }
378 }
379
380
381 char * left_Function(char aim[])//获取剩余的字符串 老师请注意:left:剩余,不是左边
382 {
383     char * left;
384     int length=strlen(aim);
385     left=&in[length];
386     return left;
387 }
388
389 void add(char aim[],char source[])
390 {
391     char temp[1000];int top=-1;
392     int len=strlen(source);
393     for(int i=len-1;i>=0;i--)
394     {
395         temp[++top]=source[i];
396     }
397     temp[++top]=‘\0‘;
398     strcat(aim,temp);
399 }
400
401 //测试数据:((i*i+i)*i/i)-(i*i*(i+i)/i-i-i)*i/i+i-i#

时间: 2024-08-03 20:36:12

【编译原理实验】递归子程序法的相关文章

编译原理实验代码(词法分析,语法分析,中间代码生成)

花了一天写出的程序没有顾及很多层面,但对于理解基本的实验道理和交上实验还是有点帮助的.代码实现了基于有限自动机的词法分析,采用递归下降分析法和EBNF文法实现语法分析并生成中间代码. lexAnalysis.h /* * lexAnalysis.h * * Created on: 2014-12-2 * Author: liuqiushan */ #ifndef LEXANALYSIS_H_ #define LEXANALYSIS_H_ #include <stdio.h> #include

哈工大软件学院编译原理实验1——词法分析

这次实验被"过来人"们定位非常easy,实验内容例如以下: ----------------------------------------------------------------------------------- 对例如以下工作进行展开描写叙述 (1) 给出语言的词法规则描写叙述 · 标识符.keyword.整常数.字符常数.浮点常数 · 单界符:+,-,×,;,- · 双界符:/*,:=,>=,<=,!=,- · 凝视 (2) 针对这样的单词的状态转换图和程

编译原理 实验3 语法分析

语法分析 一. 实验目的 算术表达式的文法可以是(你可以根据需要适当改变): E→E+E|E-E|E*E|E/E|(E)|i 根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确. 二. 实验环境 操作系统:window xp 编写环境:visual c++ 编写语言:c语言 三. 实验内容 程序输入/输出示例: 如参考C语言的运算符.输入如下表达式(以分号为结束)和输出结果: (1)10; 输出:正确 (2)1+2; 输出:正确 (3)(1+2)/3+4-(5+6/7); 输出:正

编译原理实验二:LL(1)语法分析器

一.实验要求 不得不想吐槽一下编译原理的实验代码量实在是太大了,是编译原理撑起了我大学四年的代码量... 这次实验比上次要复杂得多,涵盖的功能也更多了,我觉得这次实验主要的难点有两个(其实都是难点...): 1. 提取左公因子或消除左递归(实现了消除左递归) 2. 递归求First集和Follow集 其它的只要按照课本上的步骤顺序写下来就好(但是代码量超多...),下面我贴出实验的一些关键代码和算法思想. 二.基于预测分析表法的语法分析 2.1 代码结构 2.1.1  Grammar类    功

吉首大学_编译原理实验题_基于预測方法的语法分析程序的设计【通过代码】

一.实验要求 实验二 基于预測方法的语法分析程序的设计 一.实验目的 了解预測分析器的基本构成及用自顶向下的预測法对表达式进行语法分析的方法,掌握预測语法分析程序的手工构造方法. 二.实验内容 1.了解编译程序的基于预測方法的语法分析过程. 2.依据预測分析原理设计一个基于预測方法的语法分析程序. 三.实验要求 对给定文法G[S]: S->AT       A->BU     T->+AT|$      U->*BU|$    B->(S)|m 当中,$表示空串. 1.推断上

编译原理 - 实验三 - 递归下降语法分析器的调试及扩展

一. 语法分析介绍 语法分析是编译过程的核心部分,它的主要任务是按照程序语言的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行语法检查,为语义分析和代码生成做准备.执行语法分析任务的程序叫语法分析程序或语法分析器. 二. 所实现的语义分析和代码生成程序能处理什么语句 (1)简单变量的声明语句 (2)表达式语句 (3)if语句. (4)while语句 (5)for语句 (6)write语句 (7)read语句 (8)do语句. (9)处理过程调用和返回 三.实验过程 ①用VC

编译原理 实验2 DFA的运行

DFA的运行 一. 实验目的 1.理解有穷自动机的作用: 2.利用状态图和状态表表示有穷自动机: 3.以程序实现有穷自动机的运行过程; 4.利用状态表和有穷自动机的运行原理编制程序,使得程序能够识别一个输入串是否为一个有效的符号串.具体可以选择下面之一:无符号定点实数,无符号正偶数,自然数,整数,十六进制数,或其他自己定义的符号串. 二. 实验环境 操作系统:window xp 编写环境:visual c++ 编写语言:c语言 三. 实验内容 1.简单介绍你所设计的有穷自动机.(要求必须完成无符

编译原理实验:java实现语法分析器

实验方法:递归下降分析法基本思想是,对文法中的每个非终结符编写一个函数,每个函数的功能是识别由该非终结符所表示的语法成分.因此需要分别构造 E,E’,T,T’,F 函数来执行自己的识别功能,根据文法的内容顺序决定函数的识别功能. java程序实现: import java.util.Scanner; public class GrammarAnalysis { static char[] s = new char[100]; static int sing; static int i; //用来

编译原理实验LL(1)完整Scala实现代码与测试数据

完成了形式上的消除左递归,但是还存在bug,不能直接用于求解实际问题,但过实验指导书的样例是没问题的.先上几组测试数据. test.data(指导书上的样例): 1 E->TG 2 G->+TG|-TG 3 G->ε 4 T->FS 5 S->*FS|/FS 6 S->ε 7 F->(E) 8 F->i test2.data: 1 E->E+T|T 2 T->T-T|F 3 T->T+T|x 4 F->(E)|i  test3.dat