LR分析器C语言

该博客介绍了如何使用LR分析器来解析包含加法、乘法和括号的数学表达式,例如'id*(id+id)$'。通过定义LR分析表和栈操作,程序能够识别和处理此类表达式。当遇到无法解析的情况时,程序会输出失败信息。
摘要由CSDN通过智能技术生成

编译原理书上的LR分析器的实现
可以识别加法,乘法,括号混合的式子:如,id*(id+id)$
注意:如果表达式太长,要调大size的大小

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#define size 20//栈的大小
char key[] = {'@', '+','*','(',')','$','E','T','F' };
char* table[][9] = {//LR分析表
	"s5","","","s4","","","1","2","3",
	"","s6","","","","acc","","","",
	"","r2","s7","","r2","r2","","","",
	"","r4","r4","","r4","r4","","","",
	"s5","","","s4","","","8","2","3",
	"","r6","r6","","r6","r6","","","",
	"s5","","","s4","","","","9","3",
	"s5","","","s4","","","","","10",
	"","s6","","","s11","","","","",
	"","r1","s7","","r1","r1","","","",
	"","r3","r3","","r3","r3","","","",
	"","r5","r5","","r5","r5","","",""
};
char stack[size] = "0";
int top = 1;
int is_id = 0;
int flag = 1;

int look(char c) {
	int i = 0;
	for (i = 0; i < 9; i++)
		if (key[i]==c)
			return i;
}

int main() {
	FILE* fp = NULL;
	char ch;
	int len = 0;
	char temp[20] = "";
	fp=fopen("F:\\Visual Studio 练习\\CC++\\练习\\编译原理实验\\code.txt", "r");
	if (!fp) {
		printf_s("文件打开失败。");
		return 0;
	}
	while (fread(&ch, sizeof(char), 1, fp)) {
		if (ch != '+' && ch != '*' && ch != '(' && ch != ')' && ch != '$') {
			temp[len++] = ch;
			is_id = 1;
		}
		else {
			//char c = stack[top - 1];
			//int row = c - '0';
			//char* express = table[row][0];//0 @
			//stack[top++] = '@';
			//stack[top++] = express[1];
			char c;
			int row;
			char* express;
			if (is_id) {
				c = stack[top - 1];
				row = c - '0';
				express = table[row][0];
				stack[top++] = '@';
				stack[top++] = express[1];
				is_id = 0;
			}
			while (1) {
				int col = look(ch);
				c = stack[top-1];
				row = c - '0';
				if (stack[top - 2] >= '0' && stack[top - 2] <= '9')
					row += (stack[top - 2] - '0') * 10;
				express = table[row][col];
				if (express == "") {
					printf("失败。");
					return 0;
				}
				if (express[0] == 'r') {
					if (express[1] == '1') {
						top -= 6;
						stack[top++] = 'E';
						stack[top++] = table[stack[top - 2] - '0'][look('E')][0];
					}
					else if (express[1] == '2') {
						top -= 2;
						stack[top++] = 'E';
						stack[top++] = table[stack[top - 2] - '0'][look('E')][0];
					}
					else if (express[1] =='3') {
						top -= 6;
						if (row >= 10)
							top--;
						stack[top++] = 'T';
						stack[top++] = table[stack[top - 2] - '0'][look('T')][0];
					}
					else if (express[1] == '4') {
						top -= 2;
						stack[top++] = 'T';
						stack[top++] = table[stack[top - 2] - '0'][look('T')][0];
					}
					else if (express[1] == '5') {
						top -= 6;
						if (row >= 10)
							top--;
						stack[top++] = 'F';
						stack[top++] = table[stack[top - 2] - '0'][look('F')][0];
					}
					else if (express[1] == '6') {
						top -= 2;
						stack[top++] = 'F';
						stack[top++] = table[stack[top - 2] - '0'][look('F')][0];
						if (stack[top - 3] - '0' == 7)
							stack[top++] = table[7][look('F')][1];
					}
				}
				else if (express[0] == 'a') {
					printf("接受\n");
					flag = 0;
					break;
				}
				else if (express[0] == 's') {
					stack[top++] = ch;
					stack[top++] = express[1];
					if (strlen(express) == 3)
						stack[top++] = express[2];
					break;
				}
			}
		}
		//printf("%c", ch);
	}
	if(flag==1) printf("失败。");
	return 0;
}
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

咩~~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值