编译原理中递归下降(语法分析针对加减乘除算术表达式)用C语言实现

一.前言

今天又是一周一例的编译原理课,此次实验是实现算术表达式的部分功能(也可以说全部功能)。我花了2.3小时干完了!感觉干完了,仿佛没有了灵魂了。没有上次干词法分析那么有灵魂。没有什么快感。嗯嗯,就这样干完了。行了,废话不多说。直接上正餐。
(因为要写大学生必备实验报告,截图就是白底黑字)

二.内容要求

一、授课内容:
(一) 授课科目:编译原理
(二) 授课内容:实验二 递归下降分析程序设计
(三) 授课类型:实 验
二、教学目的要求
1.目的:通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
2.要求:
(1) 选择最有代表性的语法分析方法,算符优先法、递归子程序法和状态矩阵法之一进行实验。
(2) 选择对各种常见的程序语言都通用的语法结构,如赋值语句(尤其指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
三、教学设想:
1.教学方法设想:先以例子讲解,然后学生动手实验,实验为主。
2.教具运用设想:多媒体。
四、教学过程:
1.题目
题目 编写一个递归下降子程序,实现加减乘除算术表达式的判断。 试采用具有递归功能的高级语言(如PASCAL等等)编制递归下降法的语法分析程序,并用它对FORTRAN语言算术表达式的一个简化子集进行语法分析。分析过程不嵌入任何语义动作。
分析对象的BNF定义如下:
〈算术表达式〉::=〈项〉|〈算术表达式〉+〈项〉|〈算术表达式〉-〈项〉
〈项〉::=〈因式〉|〈项〉*〈因式〉|〈项〉/〈因式〉
〈因式〉::=〈变量〉| (〈算术表达式〉)
〈变量〉::=〈字母〉
〈字母〉::=A|B|C|D|E|f|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z

三.实现的功能和代码

功能1.不加“#”也能判断,系统自动给用户输入的加“#”
截图:
在这里插入图片描述

功能2.可以识别小数和整数
在这里插入图片描述

功能3.可以识别标识符
在这里插入图片描述
功能4.可以错误定位(采取程序员计算数法,默认从0开始)
在这里插入图片描述
大写字母在编译原理一律认为是非终结符号。

代码:

#include <stdio.h>
#include<string.h>
int p,tz,i;//tz错误标志位,1表示有错
char st[80];//字符串
char ch;//每次取的字符 
int flag;
char sym()//取下一个字符
{
	return st[p];
}

void error(int n)//报错
{
	printf("error%d\n",n);
}



void f()  // F->i|(E)
{	
	void e();
	void t();
	char sym();
	flag=1;//一次只能是一类,小数|整数|小写字母|标识符|算法表达式 | 
	ch=sym();
		if((ch>='a'&&ch<='z'||ch=='_')&&flag){//识别标识符 
			flag=0;
			while(ch>='a'&&ch<='z'||ch=='_'||ch>='0'&&ch<='9'){
				p++;
				ch=sym();
			}
		}
		else if(ch>='a'&&ch<='z'&&flag)//识别小写字母 
			  {
			  	p++;
			  	flag=0;
			  }
			else if(ch >='0'&&ch<='9'||ch=='.'&&flag)//识别数(小数和整数) 新增功能 
					{
					 	flag=0;
					  while(ch >='0'&&ch<='9')//识别整数 
					  {
				       p++;
				       ch=sym();
					  }
				      
					  if(ch=='.'){//识别小数 
				      	p++;
				      	ch=sym();
				      	while(ch >='0'&&ch<='9')
						  {
					       p++;
				       	   ch=sym();
						  }
					  }
					}
				else if(ch=='('&&flag)//识别算术表达式 
					{	
						flag=0;
						p++;
						e();
						if(ch==')')
							p++;
						else{  
							error(p); 
							tz=1;
						}
					}
					else //不是项或算数表达式
					{  
						error(p);
						tz=1;
					}
			}//end of f

void t()      //T->F{*F|/F}
{
	void f();
	f();
	ch=sym();
		while(ch=='*'||ch=='/')
		{
			p++;
			f();
			ch=sym();
		}
	
	

}
void e()      //E->T{+T|-T}
{
	t();
	ch=sym();
		while(ch=='+'||ch=='-')
		{
			p++;
			t();
			ch=sym();
		}
}

void main()
{
  printf("please input expression (end with #):");
   gets(st);
   strcat(st,"#");
   p=0; 
   ch=sym();
  /* if(ch=='#')
   {
    printf("finished\n");
    //exit();
   return ;
   }*/

   while(ch!='#')//循环,以#结束程序
   {	
	   e();
       if(ch!='#'||tz==1)
	   {
         printf("error,again\n");
         tz=0;
	   }
       else printf("right,again!\n");
     printf("please input expression (end with #):");
     fflush(stdin);
	 gets(st);
	 strcat(st,"#");
     p=0;
	 ch=sym();
   }
    printf("finished\n");
  }
  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无言月梧桐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值