编译原理自顶向下语法分析实现

  • 近段时间学习编译原理,借鉴了部分前辈代码,实现了龙书的伪代码。
  • 不足之处敬请指正。

下面展示一些 内联代码片

#include <iostream>
#include<string>
#include<vector>
#include<stack>
using namespace std;

//使用X、Y、Z 代替 E'、T'、F'
//非终结符
char non_terminal[7] = { 'E','X','T','Y','F','Z','P' };
//终结符
char terminal[9] = { '(','i','+','-','*','/','^',')','#' };

//分析表
string analystate[7][9] = {
  {"TX","TX","NULL","NULL","NULL","NULL","NULL","NULL","NULL"},//TX->TE' E
  {"NULL","NULL","+TX","-TX","NULL","NULL","NULL","e","e"},//E'
  {"FY","FY","NULL","NULL","NULL","NULL","NULL","NULL","NULL"},//FY->FT' T      
  {"NULL","NULL","e","e","*FY","/FY","NULL","e","e"}, //T'
  {"PZ","PZ","NULL","NULL","NULL","NULL","NULL","NULL","NULL"},//PZ->PF' F
  {"NULL","NULL","e","e","e","e","^F","e","e"},        //F'
  {"(E)","i","NULL","NULL","NULL","NULL","NULL","NULL","NULL"}  //P
};

//获取非终结符索引
int GetNonIndex(char p) {

	for (int i = 0; i < 7; i++) {

		if (p == non_terminal[i]) {

			return i;
		}

	}

	return -1;//错误
}

//获取终结符索引
int GetTermIndex(char p) {

	for (int i = 0; i < 9; i++) {

		if (p == terminal[i]) {

			return i;
		}

	}

	return -1;//错误

}
//自顶向下预测分析
bool GramSyntax(const string & stament) {

	stack<char>AnalStack;//定义分析栈
	char ip;
	string expr;
	int x, y,i=0;//y代表终结符,x代表非终结符
	int len;
	AnalStack.push('#');
	AnalStack.push('E');
	char Symbol = AnalStack.top();//X=栈顶
	ip = stament[i];
	while (Symbol != '#') {
		
		y = GetTermIndex(Symbol);//判断是否是终结符
		if (y != -1) {//X是终结符
			
			if (Symbol == ip) {

				AnalStack.pop();
				i++;
				ip = stament[i];
			}
			else {//语法报错

				cout << "语法错误" << endl;
				return false;
			}


		}
		else {//X是非终结符

		 //分别获取x,y的位置
			
			x = GetNonIndex(Symbol);//获取非中介
			y = GetTermIndex(ip);
			if (y == -1) {
				cout << "输入终结符不匹配,错误输入为:" << ip<<endl;
				return false;
			}
			expr = analystate[x][y];//获取预测分析表内容
			if (expr == "NULL") {//M[X,a] error()

				cout << "语法规则错误:" <<ip<< endl;
				return false;
			}
			if (expr == "e") {//弹出栈

				AnalStack.pop();
			}
			else {//否则将表达式逆序入栈

				AnalStack.pop();

				for (int k = expr.size() - 1; k >= 0; k--) {

					AnalStack.push(expr[k]);
				}

			}


		}


		Symbol = AnalStack.top();//X=栈顶符号



	}
	cout << "分析完毕,语法正确" << endl;
	return true;
}
int main() {

	string pp = "(i++i)*i#";
	bool isok = GramSyntax(pp);
	return 0;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值