设计简单算数表达式语法分析器算法(LR来实现)

#include<iostream>
#include<stack>
#include<algorithm>
using namespace std;
char L[20] = "i+-*/()#ETF";//判断依据
int search(char c)//对应列寻找
{
	int i = 0;
	while (L[i] != '\0')
	{
		if (c == L[i])
			return i;
		i++;
	}
	if (c >= 'a' && c <= 'z' || c >= '0' && c <= '9')
	{
		return 0;
	}
	return -1;

}
int toTen(string s)
{
	int num = 0;
	int i = 1;
	while (s[i] != '\0')
	{
		num = num * 10 + s[i] - '0';
		i++;
	}
	return num;
}
int main()
{
	//分析表
	string LR[16][12] = {
		//i      +     -     *     /      (      )     #       E    T    F
		{"s1","null","null","null","null","s5","null","null","s2","s3","s4"},
		{"null","r8","r8","r8","r8","null","r8","r8","null","null","null"},
		{"null","s6","s7","null","null","null","null","acc","null","null","null"},
		{"null","r3","r3","s8","s9","null","r3","r3","null","null","null"},
		{"null","r6","r6","r6","r6","null","r6","r6","null","null","null"},
		{"s1","null","null","null","null","s5","null","null","s15","s3","s4"},
		{"s1","null","null","null","null","s5","null","null","null","s13","s4"},
		{"s1","null","null","null","null","s5","null","null","null","s14","s4"},
		{"s1","null","null","null","null","s5","null","null","null","null","s11"},
		{"s1","null","null","null","null","s5","null","null","null","null","s10"},
		{"null","r5","r5","r5","r5","null","r5","r5","null","null","null"},
		{"null","r4","r4","r4","r4","null","r4","r4","null","null","null"},
		{"null","r7","r7","r7","r7","null","r7","r7","null","null","null"},
		{"null","r1","r1","s8","s9","null","r1","r1","null","null","null"},
		{"null","r2","r2","s8","s9","null","r2","r2","null","null","null"},
		{"null","s6","s7","null","null","null","s12","null","null","null","null"}
	};
	stack<int>status;//状态栈
	stack<char>letter;//符号栈
	status.push(0);
	letter.push('#');
	int len[10] = { 0,3,3,1,3,3,1,3,1 };//1-8号文法每个文法长度
	char head[20] = { 'S','E','E','E','T','T','T','F','F' };


	string str;
	cin >> str;//读入一段算术表达式
	str += '#';//在末尾加上结束标识符
	int index = 0;
	while (index < str.length())
	{
		int column = search(str[index]);
		if (LR[status.top()][column][0] == 's')//移进
		{
			int st1 = toTen(LR[status.top()][column]);
			status.push(st1);//状态入栈
			letter.push(str[index]);//符号入栈
		}
		else if (LR[status.top()][column][0] == 'r')//规约
		{
			while (LR[status.top()][column][0] == 'r')//若继续规约
			{
				int st1 = toTen(LR[status.top()][column]);//规约表达式序号
				char ch = head[st1];//规约所得符号
				int st2 = len[st1];//规约表达式长度
				for (int i = 0; i < st2; i++)//状态和符号出栈
				{
					status.pop();
					letter.pop();
				}
				letter.push(ch);//将规约符号入栈
				int col = search(ch);//找到规约符号对应列
				status.push(toTen(LR[status.top()][col]));//将规约符号对应的状态入栈
			}
			if (LR[status.top()][column] == "acc")//结束标志
			{
				cout << endl << "true";
				break;
			}
			else if(LR[status.top()][column][0] == 's')//移进标志
			{
				letter.push(str[index]);//符号入栈
				status.push(toTen(LR[status.top()][column]));//对应状态入栈
			}
			else//错误
			{
				cout << endl << "false" << endl;
				break;
			}
			
		}
		else if ((LR[status.top()][column] == "acc"))
		{
			cout <<endl<< "true" ;
			break;
		}
		else
		{
			cout <<endl<< "false";
			break;
		}
		index++;
	}
	return 0;
}

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
LR(Left-to-right, Rightmost derivation)是一种自底向上的语法分析方法,通常用于构建编译器的语法分析器。其基本原理是使用一个有限状态自动机,读入一个输入字符串并尝试将其转换为目标语言的语法结构。 对于设计简单算数表达式语法分析器算法,可以先定义算数表达式的文法规则,然后使用LR分析方法生成语法分析器。例如,一个简单算数表达式文法规则可以定义如下: ``` E -> E + T | E - T | T T -> T * F | T / F | F F -> ( E ) | num ``` 其中,E表示表达式,T表示项,F表示因子,num表示数字。这个文法规则可以表示加减乘除四则运算,以及括号嵌套等基本运算。 接下来,可以使用LR分析方法来生成语法分析器。具体实现过程包括以下几个步骤: 1. 构建LR分析表:根据文法规则,生成LR分析表,包括ACTION和GOTO两个部分。ACTION表记录在当前状态下,读入下一个字符后应该执行的动作(移进、规约或接受),GOTO表记录在当前状态下,读入下一个非终结符后应该转移到的状态。 2. 实现LR分析器:根据生成的LR分析表,实现LR语法分析器,输入一个算数表达式,输出其语法树或错误信息。 3. 进行语法分析:使用实现LR分析器对输入的算数表达式进行语法分析,得到其语法树或错误信息。 总的来说,LR分析器的实现原理是根据文法规则生成LR分析表,然后使用该表来进行自底向上的语法分析,最终得到输入字符串的语法结构。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值