用SLR(1)分析法对简单赋值语句做语法分析

用SLR(1)分析法对简单赋值语句做语法分析

简单赋值语句的文法如下:

〈赋值语句〉∷= 〈标识符〉=〈表达式〉
〈表达式〉∷= 〈项〉|〈表达式〉〈加法运算符〉〈项〉 
〈项〉∷= 〈因子〉|〈项〉〈乘法运算符〉〈因子〉 
〈因子〉∷= 〈标志符〉|〈无符号整数〉|(〈表达式〉)
〈无符号整数〉∷= 〈数字〉|〈无符号整数〉〈数字〉 
〈标志符〉∷= 〈字母〉|〈标志符〉〈字母〉|〈标志符〉〈数字〉 
〈加法运算符〉∷= +-
〈乘法运算符〉∷= */

进行简写并加入S’—>S进行拓广:

0)产生式:S'——>S   
(1)产生式:S——>x=A   
(2)产生式:A——>B   
(3)产生式:A——>ADB   
(4)产生式:B——>H   
(5)产生式:B——>BMH   
(6)产生式:H——>x   
(7)产生式:H——>n   
(8)产生式:H——>(A)9)产生式:D——>+10)产生式:D——>-11)产生式:M——>*12)产生式:M——>/   

对照表:

x			<标识符>
n			<无符号整数>
+			+
-			-
*			*
/			/
(			(
)			)
=			=
;			;
S			<赋值语句>
A			<表达式>
B			<>
D			<加法运算符>
M			<乘法运算符>
H			<因子>

SLR(1)分析表
在这里插入图片描述

SLR(1)分析法实现(C++描述)

//语法分析
stack<int>  statusStack;//状态栈
stack<char> wordStack;//符号栈
//初始化
statusStack.push(0);
wordStack.push(';');
int i = 0;
while (1) {
   
	//分析步骤:
	char type = actionType(statusStack.top(), wordType[i][0]);
	if (type == 'S') {
   
		int ACTION = action(statusStack.top(), wordType[i][0]);
		statusStack.push(ACTION);
		wordStack.push(wordType[i][0]);
		if (i < num - 1)i++;//防止错误串引起越界
	}
	else if (type == 'r') {
   
		int index = action(statusStack.top(), wordType[i][0]);
		int t = formulaRLength[index];
		while (t-- > 0) {
   
			statusStack.pop();
			wordStack.pop();
		}
		int GOTO = goTo(statusStack.top(), formulaL[index][0]);
		statusStack.push(GOTO);
		wordStack.push(formulaL[index][0]);
	}
	else if (type == 'a') {
   
		cout << "该字符串是文法的句子,接受" << endl;
		break;
	}
	else {
   
		cout << "该字符串不是文法的句子!!!" << endl;
		break;
	}
}

完整代码实现(C++)
使用文件d:/input.txt 输入,输出到文件 d:/output.txt中
示例:(一条简单的赋值语句,用分号结尾)

pgvddd=(m9F/3-dd)+(890+er)*67;
#include<iostream>
#include<stack>
#include<fstream>
#include<string.h>
using namespace std;
ofstream fout;

//读取单词
char word[500][20];
char wordType[500][2];// n,x,...
int num = 0;

//SLR(1)分析法
char sym[] = {
    'x','n','+','-','*','/','(',')','=',';','S','A','B','D','M','H' };
int  symI[255];
char formulaL[13][5] = {
    "S\'","S",  "A" ,  "A" ,  "B" , "B" ,  "H" ,"H" ,"H" ,  "D" ,"D" ,"M" ,"M" };
char formulaR[13][5] = {
    "S",  "x=A","B" ,  "ADB" ,"H" , "BMH" ,"x" ,"n" ,"(A)" ,"+" ,"-" ,"*" ,"/" };
int  formulaRLength[13] =   {
     1,    3,    1,     3,     1,    3,     1,   1,   3,     1,   1,   1,   1  };

//                       'x','n','+','-','*','/','(',')','=',';','S','A','B','D','M','H' 
char typeTable[][16] = {
    'S','e','e','e','e','e','e','e','e','e','S','e','e','e','e','e',//0
						 'e','e','e','e','e','e','e','e','e','a','e','e','e','e','e','e',//1
						 'e','e','e','e','e','e','e','e','S','e','e','e','e','e','e','e',//2
						 'S','S','e','e','e','e','S','e','e','e','e','S','S','e','e','S',//3
						 'e','e','S','S','e','e','e','e','e','r','e','e','e','S','e','e',//4
						 'e','e','r','r','S','S','e','r','e','r','e','e','e','e','S','e',//5
						 'r','r','r','r','r','r','r','r','r','r','e','e','e','e','e','e',//6
						 'r','r','r','r','r','r','r','r','r','r','e','e','e','e','e','e',//7
						 'r','r','r','r','r','r','r','r','r','r','e','e','e','e','e','e',//8
						 'S','S','e','e','e','e','S','e','e','e','e','S','S','e','e','S',//9
						 'S','S','e','e','e','e','S','e','e','e','e','e','S','e','e','S',//10
						 'r','r','r','r','r','r','r','r','r','r','e','e','e','e','e','e',//11
						 'r','r','r','r','r','r','r','r','r','r','e','e','e','e','e','e',//12
						 'S','S','e','e','e','e','S','e','e','e','e','e','e','e','e','S',//13
						 'r','r','r','r','r','r','r','r','r','r','e','e','e','e','e','e',//14
						 'r','r','r','r','r','r','r','r','r','r','e','e','e','e','e','e',//15
						 'e','e','S','S','e','e','e','S','e','e','e','e','e','S','e','e',//16
						 'e','e','r','r','S','S','e','r','e','r','e','e','e','e','S','e',//17
						 'r','r','r','r','r','r','r','r','r','r','e','e','e','e','e','e',//18
						 'r','r','r','r','r','r','r','r','r','r','e','e','e','e','e','e' //19
};
//                       'x','n','+','-','*','/','(',')','=',';','S','A','B','D','M','H' 
int numberTable[][16] = {
    2 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 , 1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//0
						 -1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//1
						 -1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 , 3 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//2
						  8 , 7 ,-1 ,-1 ,-1 ,-1 , 9 ,-1 ,-1 ,-1 ,-1 , 4 , 5 ,-1 ,-1 , 6 ,//3
						 -1 ,-1 ,11 ,12 ,-1 ,-1 ,-1 ,-1 ,-1 , 1 ,-1 ,-1 ,-1 ,10 ,-1 ,-1 ,//4
						 -1 ,-1 , 2 , 2 ,14 ,15 ,-1 , 2 ,-1 , 2 ,-1 ,-1 ,-1 ,-1 ,13 ,-1 ,//5
						  4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//6
						  7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//7
						  6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//8
						  8 , 7 ,-1 ,-1 ,-1 ,-1 , 9 ,-1 ,-1 ,-1 ,-1 ,16 , 5 ,-1 ,-1 , 6 ,//9
						  8 , 7 ,-1 ,-1 ,-1 ,-1 , 9 ,-1 ,-1 ,-1 ,-1 ,-1 ,17 ,-1 ,-1 , 6 ,//10
						  9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//11
						 10 ,10 ,10 ,10 ,10 ,10 ,10 ,10 ,10 ,10 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//12
						  8 , 7 ,-1 ,-1 ,-1 ,-1 , 9 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,18 ,//13
						 11 ,11 ,11 ,11 ,11 ,11 ,11 ,11 ,11 ,11 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//14
						 12 ,12 ,12 ,12 ,12 ,12 ,12 ,12 ,12 ,12 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//15
						 -1 ,-1 ,11 ,12 ,-1 ,-1 ,-1 ,19 ,-1 ,-1 ,-1 ,-1 ,-1 ,10 ,-1 ,-1 ,//16
						 -1 ,-1 , 3 , 3 ,14 ,15 ,-1 , 3 ,-1 , 3 ,-1 ,-1 ,-1 ,-1 ,13 ,-1 ,//17
						  5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,//18
						  8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1  //19
};

void getWords(const char* filename) {
   
	FILE* file;
	fopen_s(&file, filename, "r");
	int i = 0;//第i号单词
	int j = 0;//单词的第j号字符
	char c = fgetc(file);
	while (c != EOF) {
   
		//遇到空格,制表符,回车,换行自动跳过
		if (c == 9 || c == 10 || c == 13 || c == 32) {
   
			c = fgetc(file);
		}
		else {
   
			//读取无符号整数
			if (c >= '0' && c <= '9') {
   
				j = 0;
				do {
   
					word[i][j++] = c;
					c = fgetc(file);
				} while (c >= '0' && c <= '9');
				word[i][j] = '\0';//补上字符串结束符
				wordType[i][0] = 'n';
				wordType[i][1] = '\0';//补上字符串结束符
			}//读取标识符(不考虑关键字问题)
			else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
   
				j = 0;
				do {
   
					word[i][j++] = c;
					c = fgetc(file);
				} while ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
				word[i][j] = '\0';//补上字符串结束符
				wordType[i][0] = 'x';
				wordType[i][1] = '\0';//补上字符串结束符
			}
			else {
   
				if (c == '+' || c == '-' || c == '*' || c == '/' || c == '=' || c == '(' || c == ')' || c == ';') {
   
					wordType[i][0] = word[i][0] = c;
					wordType[i][1] = word[i][1] = '\0';
				}
				c = fgetc(file);
			}
		}
		i++;
	}
	num = i;
	cout << "单词" << "\t\t" << "文法符号" << endl;
  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值