基于算符优先分析算法的语法制导翻译——程序设计与编译原理

一、在算符优先语法分析的基础上进行翻译工作(即语义分析),每当将一个最左素短语归约为一个非终结符号时,就调用对应产生式的语义子程序,去完成相应的语义翻译工作,这步归约使用的产生式对非终结符号不加区分(即将所有的非终结符号用一个通用的非终结符号表示)。

判断是句子的情况下,输出:四元式序列(*,val,count,T1)

算符优先分析前期准备:https://blog.csdn.net/lfy905805357/article/details/89333111

二、code

#include 
#include "stdio.h"
#include "stdlib.h"
#include 
#include 
#include 
using namespace std;
char Data[20][20];                    //算符优先关系
char s[100];                          //模拟符号栈s
string str[100];                      //用来类似模拟符号栈s,不过该栈为字符串(用于同时给非终结符加上下标,例如P1)
char lable[20];                       //文法终极符集
char input[100];                      //文法输入符号串
char In_str[20][10];                  //用于输入串的分析
char text[20][10];
int k;
char a;
int j;
char q;
int r;                                //文法规则个数
int r1;                               //转化后文法规则个数
char st[10][30];                      //用来存储文法规则
char first[10][10];                   //文法非终结符FIRSTVT集
char last[10][10];                    //文法非终结符LASTVT集
int fflag[10] = { 0 };                //标志第i个非终结符的FIRSTVT集是否已求出
int lflag[10] = { 0 };                //标志第i个非终结符的LASTVT集是否已求出
map charmap;                //用来判断该字符的下标是几
map stringmap;         //用来下标,值健对查找
stringstream ss;                      //利用该stringstream来进行其他类型转换为字符串
string qua[100][4];                   //存储四元组
int quaCounts=0;                      //四元组个数
int deal();                           //对输入串的分析
int deal1();                          //对输入串的分析(包括求四元组)
int Terminator(char c);               //判断字符c是否是终极符
int getIndex(char c);                 //求字符c在算符优先关系表中的下标
void out(int j, int k, char *s);      //打印s栈
void out1(int j, int k, string *str); //打印str栈
void firstvt(char c);                 //求非终结符c的FIRSTVT集
void lastvt(char c);                  //求非终结符c的LASTVT集
void table();                         //创建文法优先关系表
bool check(char *in);                 //判断输入是不是都是终结符构成的句子
int main()
{
	int i, j, k = 0;
	printf("请输入文法规则数:");
	cin >> r;
	printf("请输入文法规则:\n");
	for (i = 0; i> st[i];		        //存储文法规则,初始化FIRSTVT集和LASTVT集*/
		first[i][0] = 0;            /*first[i][0]和last[i][0]分别表示st[i][0]非终极
									符的FIRSTVT集和LASTVT集中元素的个数*/
		last[i][0] = 0;
	}
	for (i = 0; i'Z')
			{
				printf("不是算符文法!\n");
				exit(-1);
			}
			if (st[i][j] >= 'A'&&st[i][j] <= 'Z')
			{
				if (st[i][j + 1] >= 'A'&&st[i][j + 1] <= 'Z')//两非终结符不能相邻
				{
					printf("不是算符文法!\n");
					exit(-1);
				}
			}
		}
	}
	for (i = 0; i'Z') && st[i][j] != '-'&&st[i][j] != '>'&&st[i][j] != '|')
				lable[k++] = st[i][j];
		}
	}
	lable[k] = '#';//把井号终结符加入到终结符集合里面
	lable[k + 1] = '\0';
	table();

	printf("每个非终结符的FIRSTVT集为:\n");    //输出每个非终结符的FIRSTVT集
	for (i = 0; i> input && input != "exit") {
		int flag=deal1();//标记是否符合文法定义
		if(flag==1&&check(input)){//检测输入串是否是终结符组成的句子
            cout<<"该符号串是句子!"<"
	后的转化文法,用于最后的规约)*/
	for (i = 0; i')//归约
		{
			out(1, k, s);
			printf("%c", a);
			out(i + 1, z, input);
			printf("规约\n");
			do
			{
				q = s[j];
				if (Terminator(s[j - 1]))
					j = j - 1;
				else j = j - 2;
				x = getIndex(s[j]);
				y = getIndex(q);
			} while (Data[x][y] != '<');
			int m, n, N;
			for (m = j + 1; m <= k; m++)
			{
				for (N = 0; N')//归约
		{
			out1(1, k, str);
			printf("%c", a);
			out(i + 1, z, input);
			printf("规约");
			do
			{
				q = s[j];
				if (Terminator(s[j - 1]))
					j = j - 1;
				else j = j - 2;
				x = getIndex(s[j]);
				y = getIndex(q);
			} while (Data[x][y] != '<');
			int m, n, N;
			for (m = j + 1; m <= k; m++)
			{
				for (N = 0; N%c%d%c%c%d",In_str[N][0],m,s[m],m,s[m+1],s[m+2],m+2);
							    //printf("s[%d]==%c&In_str[%d][%d]==%c&s[%d]==%c&In_str[%d][%d]==%c",m,s[m],N,n,In_str[N][n],m+1,s[m+1],N,n+1,In_str[N][n+1]);
								string avl=str[m];//提前保留还未规约更新的值用于输出
								s[j + 1] = In_str[N][0];//规约代替例如T->E+P
								charmap[In_str[N][0]]+=1;//利用map存储记忆该X的下标,例如X1->i
                                ss<"<(E)这种情况而设定
                                if (s[m] == In_str[N][n])
								{
								    //printf("%c%d->%c",In_str[N][0],m,In_str[N][n]);
									string avl=str[m];//提前保留还未规约更新的值用于输出
									s[j + 1] = In_str[N][0];//规约代替T->(E)
									charmap[s[j + 1]]+=1;//利用map存储记忆该X的下标,例如X1->i
									ss<"<i
								if (s[m] == In_str[N][n])
								{
								    //printf("%c%d->%c",In_str[N][0],m,In_str[N][n]);
									s[j + 1] = In_str[N][0];//将终结符i利用X规约代替
									charmap[s[j + 1]]+=1;//利用map存储记忆该X的下标,例如X1->i
									ss<"<i那么stringmap[X1]="i",用于四元组输出求值
									ss.str("");//ss清空
									goto outer;//直接跳出全部循环
								}
						}
					}
			}
			outer://循环跳出位置
			k = j + 1;//栈顶位置k更新
			printf("\n");//下一行
			if (k == 2 && a == '#')//规约完毕,只剩#X符号
			{
				out1(1, k, str);
				printf("%c", a);
				out(i + 1, z, input);
				printf("结束\n");
				printf("\n输入串符合文法的定义!\n");
				return 1;                               //输入串符合文法的定义
			}
		}
		else
			if (Data[x][y] == '<' || Data[x][y] == '=')
			{                                                //移进
				out1(1, k, str);//输出当前范围内的栈str
				printf("%c", a);
				out(i + 1, z, input);
				printf("移进\n");
				k++;
				s[k] = a;//移进赋值
				//类似的栈str也对应移进赋值,此处借用ss将char转换为string类型
				ss<

三、结果

基于算符优先分析算法的语法制导翻译——程序设计与编译原理_第1张图片

你可能感兴趣的:(程序设计与编译原理,程序设计与编译原理,算符优先分析,C++,语法制导翻译)