编译原理实验3-算符优先分析法

简介: #include<stdlib.h>#include<stdio.h>#include<string.h>#include<iostream>#define SIZE 128char priority[6][6]; //算符优先关系表数组char input[SIZE]; //存放输入的要进行分析的句子char rem
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#define SIZE 128
char priority[6][6];  //算符优先关系表数组
char input[SIZE];     //存放输入的要进行分析的句子
char remain[SIZE];    //存放剩余串
char AnalyseStack[SIZE];  //分析栈
void analyse();
int  testchar(char x);  //判断字符X在算符优先关系表中的位置
void remainString();    //移进时处理剩余字符串,即去掉剩余字符串第一个字符
int k;
void init()//构造算符优先关系表,并将其存入数组中
{
	priority[1][0]='>';
	priority[1][1]='>';
	priority[1][2]='<';
	priority[1][3]='<';
	priority[1][4]='>';
	priority[1][5]='>';

	priority[2][0]='>';
	priority[2][1]='>';
	priority[2][2]='$';//无优先关系的用$表示
	priority[2][3]='$';
	priority[2][4]='>';
	priority[2][5]='>';

	priority[3][0]='<';
	priority[3][1]='<';
	priority[3][2]='<';
	priority[3][3]='<';
	priority[3][4]='=';
	priority[3][5]='$';

	priority[4][0]='>';
	priority[4][1]='>';
	priority[4][2]='$';
	priority[4][3]='$';
	priority[4][4]='>';
	priority[4][5]='>';

	priority[5][0]='<';
	priority[5][1]='<';
	priority[5][2]='<';
	priority[5][3]='<';
	priority[5][4]='$';
	priority[5][5]='=';
}
void analyse()//对所输入的句子进行算符优先分析过程的函数
{
	int i,j,f,z,z1,n,n1,z2,n2;
	int count=0;//操作的步骤数
	char a; //用于存放正在分析的字符
	char p,Q,p1,p2;
	f=strlen(input);  //测出数组的长度
	for(i=0;i<=f;i++)
	{
		a=input[i];
		if(i==0)
			remainString();
		if(AnalyseStack[k]=='+'||AnalyseStack[k]=='*'||AnalyseStack[k]=='i'
     ||AnalyseStack[k]=='('||AnalyseStack[k]==')'||AnalyseStack[k]=='#')
			j=k;
		else
			j=k-1;
		z=testchar(AnalyseStack[j]);//从优先关系表中查出s[j]和a的优先关系
		if(a=='+'||a=='*'||a=='i'||a=='('||a==')'||a=='#')
			n=testchar(a);
		else //如果句子含有不是终结符集合里的其它字符,不合法
		{
			printf("错误!该句子不是该文法的合法句子!\n");
			break;
		}
		p=priority[z][n];
		if(p=='$')
		{
			printf("错误!该句子不是该文法的合法句子!\n");
			return;
		}
		if(p=='>')
	{ for( ; ; )
		{
        Q=AnalyseStack[j];
			 if(AnalyseStack[j-1]=='+'||AnalyseStack[j-1]=='*'||AnalyseStack[j-1]=='i'
       ||AnalyseStack[j-1]=='('||AnalyseStack[j-1]==')'||AnalyseStack[j-1]=='#')
				 j=j-1;
			 else
				 j=j-2;
			 z1=testchar(AnalyseStack[j]);
			 n1=testchar(Q);
			 p1=priority[z1][n1];
			 if(p1=='<')  //把AnalyseStack[j+1]~AnalyseStack[k]归约为N
			 {
				 count++;
				 printf("(%d)     %s\t%10c\t%5c%17s\t    归约\n",count,AnalyseStack,p,a,remain);
				 k=j+1;
				 i--;
				 AnalyseStack[k]='N';
				 int r,r1;
				 r=strlen(AnalyseStack);
				 for(r1=k+1;r1<r;r1++)
					 AnalyseStack[r1]='\0';
			 break;
			 }
			 else
			   continue;
		}
	}
		else
		{
			if(p=='<')  //表示移进
			{
				count++;
				printf("(%d)     %s\t%10c\t%5c%17s\t    移进\n",count,AnalyseStack,p,a,remain);
				k=k+1;
				AnalyseStack[k]=a;
				remainString();
			}
			else
			{
				if(p=='=')
				{
					z2=testchar(AnalyseStack[j]);
					n2=testchar('#');
					p2=priority[z2][n2];
					if(p2=='=')
					{
						count++;
						printf("(%d)     %s\t%10c\t%5c%17s\t    接受\n",count,AnalyseStack,p,a,remain);
						printf("该句子是该文法的合法句子。\n");
						break;
					}
					else
					{
						count++;
						printf("(%d)     %s\t%10c\t%5c%17s\t    移进\n",count,AnalyseStack,p,a,remain);
						k=k+1;
						AnalyseStack[k]=a;
						remainString();
					}
				}
				else
				{
					printf("错误!该句子不是该文法的合法句子!\n");
					break;
				}
			}
		}
	}
}

int testchar(char x)
{
	int m;
	if(x=='+')
		m=0;
	if(x=='*')
		m=1;
	if(x=='i')
		m=2;
	if(x=='(')
		m=3;
	if(x==')')
		m=4;
	if(x=='#')
		m=5;
	return m;
}
void remainString()
{
	int i,j;
	i=strlen(remain);
	for(j=0;j<i;j++)
		remain[j]=remain[j+1];
	remain[i-1]='\0';
}

int main()
{
	init();
	printf("请输入要进行分析的句子(以#号结束输入):\n");
    gets(input);//将输入的字符串存到数组中
	printf("步骤    栈           优先关系    当前符号    剩余输入串   移进或归约\n");
	k=0;
	AnalyseStack[k]='#';
	AnalyseStack[k+1]='\0';
	int length,i; //初始化剩余字符串数组为输入串
	length=strlen(input);//
	for(i=0;i<length;i++)
		remain[i]=input[i];
	remain[i]='\0';
	analyse();//对所输入的句子进行算符优先分析过程的函数
	return 0;
}

目录
相关文章
|
1天前
|
资源调度
回归方程优良性评价(原理+实践+代码)
回归方程优良性评价(原理+实践+代码)
回归方程优良性评价(原理+实践+代码)
|
9月前
|
编解码 JavaScript
解释基本的3D理论
本文介绍了所有基本理论,这些理论在开始使用 3D 时很有用。
65 0
解释基本的3D理论
|
9月前
|
编译器 C语言
编译原理(三)目标代码的生成与优化基本概念
编译原理(三)目标代码的生成与优化基本概念
|
11月前
|
算法 网络安全 API
冰桶算法要点解读
冰桶算法(Leaky Bucket Algorithm)是一种限流算法,用于控制单位时间内系统的请求数量。它通过模拟一个“漏水的桶”来限制请求的数量。
|
机器学习/深度学习 算法
数据结构与算法关系(中):如何评判一个算法的好坏
大家好,我是MicroStone,一个曾在三家世界500强企业担任要职的一线互联网工程师。上一节,我们了解到算法的一些特征,想必大家都掌握了算法设计要求,在学习或工作中根据业务需求设计要设计一个算法,我们要如何评估一个算法的好坏呐?下面我们来看看算法的度量方式。
132 0
|
算法
算法设计与分析/数据结构与算法实验2:循环赛安排问题
算法设计与分析/数据结构与算法实验2:循环赛安排问题
262 0
算法设计与分析/数据结构与算法实验2:循环赛安排问题
|
算法 Oracle Java
深度剖析 | 【JVM深层系列】[HotSpotVM研究系列] JVM调优的"标准参数"的各种陷阱和坑点分析(攻克盲点及混淆点)「 1 」
深度剖析 | 【JVM深层系列】[HotSpotVM研究系列] JVM调优的"标准参数"的各种陷阱和坑点分析(攻克盲点及混淆点)「 1 」
111 0
|
程序员
编程基本功:找到问题的合理解释,才算解决问题
编程基本功:找到问题的合理解释,才算解决问题
64 0
|
Java Android开发
JVM诊断工具中的深堆、浅堆、支配树,你都明白吗
JVM诊断工具中的深堆、浅堆、支配树,你都明白吗
138 0
JVM诊断工具中的深堆、浅堆、支配树,你都明白吗
|
自然语言处理 程序员 编译器
Python编程基础:实验4——组合数据的综合实验
Python编程基础:实验4——组合数据的综合实验代码练习
350 0
Python编程基础:实验4——组合数据的综合实验