编译技术实验3:LR语法分析器

源代码

#include<iostream>
#include<fstream>
using namespace std;
#define MAX 20
int table[12][9] = {
	{5,-1,-1,4,-1,-1,1,2,3},
	{-1,6,-1,-1,-1,12,-1,-1,-1},
	{-1,22,7,-1,22,22,-1,-1,-1},
	{-1,24,24,-1,24,24,-1,-1,-1},
	{5,-1,-1,4,-1,-1,8,2,3},
	{-1,26,26,-1,26,26,-1,-1,-1},
	{5,-1,-1,4,-1,-1,-1,9,3},
	{5,-1,-1,4,-1,-1,-1,-1,10},
	{-1,6,-1,-1,11,-1,-1,-1,-1},
	{-1,21,7,-1,21,21,-1,-1,-1},
	{-1,23,23,-1,23,23,-1,-1,-1},
	{-1,25,25,-1,25,25,-1,-1,-1}
};
struct rule {
	char x;
	int y;
}r[6] = { {'E',3},{'E',1},{'T',3},{'T',1},{'F',3},{'F',1} };
char index_char[9] = { 'i','+','*','(',')','#','E','T','F' };
int get_index_char(char i)
{
	for (int j = 0; j < 9; j++)
	{
		if (index_char[j] == i)
			return j;
	}
	return -1;
}
typedef struct {
	int stack[MAX];
	int top;
}status;
void init_stack(status* p)
{
	if (!p)
		cout << "初始化状态栈出错" << endl;
	p->top = -1;
}
void push(status* p, int x)
{
	if (p->top < MAX - 1)
	{
		p->top++;
		p->stack[p->top] = x;
	}
	else cout <<endl<< "状态栈溢出" << endl;
}
int pop(status* p)
{
	int x;
	if (p->top != 0)
	{
		x = p->stack[p->top];
		p->top--;
		return x;
	}
	else
		cout <<endl<< "状态栈为空!" << endl;
}
int get_top(status* p)
{
	int x;
	if (p->top != -1)
	{
		x = p->stack[p->top];
		return x;
	}
	else
	{
		cout <<endl<< "状态栈为空!" << endl;
		return 0;
	}
}
void out_stack(status* p)
{
	int i;
	if (p->top<0)
	{
		cout << endl << "状态栈为空!" << endl;
	}
	for (i = 0; i <= p->top; i++)
	{
		cout << p->stack[i];
	}
}
typedef struct {
	char stack[MAX];
	int top;
}symbol_instr;
void init_stack(symbol_instr* p)
{
	if (!p)
		cout << endl << "初始化符号栈出错!" << endl;
	p->top = -1;
}
void push(symbol_instr* p, char x)
{
	if (p->top < MAX - 1)
	{
		p->top++;
		p->stack[p->top] = x;
	}
	else
		cout << endl << "符号栈溢出!" << endl;
}
char pop(symbol_instr* p)
{
	char x;
	if (p->top != -1)
	{
		x = p->stack[p->top];
		p->top--;
		return x;
	}
	else
	{
		cout << endl << "符号栈为空!" << endl;
		return 0;
	}
}
char get_top(symbol_instr* p)
{
	char x;
	if (p->top != -1)
	{
		x = p->stack[p->top];
		return x;
	}
	else
	{
		cout << endl << "符号栈为空!" << endl;
		return 0;
	}
}
void out_stack1(symbol_instr* p)
{
	int i;
	if (p->top < 0)
		cout << endl << "符号栈为空!" << endl;
	for (int i = 0; i <= p->top; i++)
	{
		cout << p->stack[i];
	}
}
void out_stack2(symbol_instr* p)
{
	int i;
	if (p->top < 0)
		cout << endl << "符号栈为空!" << endl;
	for (int i = p->top; i >=0; i--)
	{
		cout << p->stack[i];
	}
}
void print(status* status_p, symbol_instr* symbol_p, symbol_instr* instr_p)
{
	int i;
	out_stack(status_p);
	for (i = 0; i < 20 - status_p->top; i++)
		cout << " ";
	out_stack1(symbol_p);
	for (i = 0; i < 20; i++)
		cout << " ";
	out_stack2(instr_p);
	cout << endl;
}
int goto_char(status* status_p, symbol_instr* instr_p)
{
	char x;
	int y, z;
	x = get_top(instr_p);
	y = get_top(status_p);
	z = get_index_char(x);
	return table[y][z];
}
void action(status* status_p, symbol_instr* symbol_p, symbol_instr* instr_p)
{
	int i, j, x;
	char a;
	i = goto_char(status_p, instr_p);
	if (i == -1)
	{
		cout << "归约出错!" << endl;
	}
	if (i == 12)
	{
		cout << "归约成功!" << endl;
	}
	if (i >= 0 && i <= 11)
	{
		push(status_p, i);
		a = pop(instr_p);
		push(symbol_p, a);
		print(status_p, symbol_p, instr_p);
		action(status_p, symbol_p, instr_p);
	}
	if (i >= 21 && i <= 26)
	{
		x = r[i - 21].y;
		for (j = 0; j < x; j++)
		{
			pop(status_p);
			pop(symbol_p);
		}
		push(instr_p, r[i - 21].x);
		action(status_p, symbol_p, instr_p);
	}
}
int main()
{
	char x;
	status* status_p;
	symbol_instr* symbol_p, * instr_p;
	status_p = new status;
	symbol_p = new symbol_instr;
	instr_p = new symbol_instr;
	init_stack(status_p);
	init_stack(symbol_p);
	init_stack(instr_p);
	push(status_p, 0);
	push(symbol_p,'#');
	/*cout << "请输入要分析文件的位置和后缀:" << endl;
	char filepath[50];
	fstream file(filepath, ios::out);
	if (!file)
	{
		cout << "文件不存在!" << endl;
		return 0;
	}*/
	cout << "请输入要归约的字符串,以'#'字符结束!" << endl;
	do
	{
		x = cin.get();
		if (x != ' ' && x != '\t' && x != '\n')
			push(symbol_p, x);
	} while (x != '#');
	while (symbol_p->top != 0)
	{
		x = pop(symbol_p);
		push(instr_p, x);
	}
	cout << endl << endl;
	cout << endl << "状态栈               符号栈               输入串              " << endl;
	print(status_p, symbol_p, instr_p);
	action(status_p, symbol_p, instr_p);
	return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值