编译原理——实验2 递归下降语法分析程序设计

编译原理——实验2 递归下降语法分析程序设计

【实验要求】

(1)待分析的简单语言的词法同实验1

(2)待分析的简单语言的语法

用扩充的BNF表示如下:

1)<程序>::=begin<语句串>end

2) <语句串>::=<语句>{;<语句>}

3) <语句>::=<赋值语句>

4) <赋值语句>::=ID:=<表达式>

5) <表达式>::=<项>{+<项>|-<项>}

6) <项>::=<因子>{*<因子>|/<因子>}

7) <因子>::=ID|NUM|(<表达式>)

(3)语法分析程序的功能

输入单词串以”#”结束,如果是文法正确的句子,输出成功信息;否则输出错误信息。

例如:

输入   begin a:=9; x:=2 * 3; b:=a + x end #

输出   success

输入   x:=a + b * c end #

输出   error

 

这个实验二与实验一是有一定联系的,实验一请观看:

实验一 词法分析器实验:https://blog.csdn.net/weixin_44566432/article/details/105415058

 

具体代码:

#include <iostream>
#include <cstring>
using namespace std;
 
char prog[800];	//存储程序 
char token[10];	//存储单词字符串
char ch;	//当前字符 
int syn;	//单词种别码 
int sum;	//整型常数 
int p;	//prog指针
int m;	//token指针
int n; 
int kk;	//错误标记 
//关键字 
const char * rwtab[6] = {"begin", "if", "then", "while", "do", "end"};
 
bool isLetter(char ch);	//判断是否为字母 
bool isDigit(char ch);	//判断是否为数字 
void scanner();			//扫描分析器 
void Irparser();		//语法分析器 
void yucu();			//语句串分析函数 
void statement();		//语句分析函数 
void expression();		//表达式分析函数 
void term();
void factor(); 
 
bool isLetter(char ch){
	if ((ch <= 'z' && ch >='a') || (ch <'Z' && ch >= 'A')){
		return true;
	}
	else{
		return false;
	}
}

bool isDigit(char ch){
	if(ch >= '0' && ch <= '9'){
		return true;
	}
	else{
		return false;
	}
	
} 
 
void scanner(){
	//清空token 
	for (n = 0 ; n < 8; n++){
		token[n] = NULL;
	}
	m = 0; 
	
	//获取下一个有效字符 
	ch = prog[p];
	while(ch == ' '){
		p++;
		ch = prog[p];
	}
	
	if(isDigit(ch)){
		//字符为数字 
		sum = 0;
		while (isDigit(ch)){
			sum = sum * 10 + ch - '0';	//str转换为数值类型
			p++;
			ch = prog[p]; 
			syn = 11;
		}
	}
	//字符为字符串 
	else if(isLetter(ch)){
		while(isDigit(ch) || isLetter(ch)){
			token[m] = ch;
			m++;
			p++;
			ch = prog[p];
		}
		token[m] = '\0';
		m++; 
		syn = 10;
		for(n = 0; n < 6; n++){
			if(strcmp(token, rwtab[n]) == 0){
				syn = n + 1;
				break;	
			}
		}
	}
	else{
 	    switch (ch){
 			case '<':
 				syn = 20;
 				m = 0;
 				token[m] = ch;
 				m++;
 				p++;
 				ch = prog[p];
	            if (ch == '>') {
	                syn = 21;
					token[m] = ch;
					m++;
	 				p++;
	 				ch = prog[p];					
	            }
	            else if (ch == '=') {
	                syn = 22;
					token[m++] = ch;
					m++;
					p++;
 					ch = prog[p];
	        	}
	            break;
	        
			case '>':
				syn = 23;
	            m = 0;
	            token[m++] = ch;
	            p++;
	            ch = prog[p];    
	            if (ch == '=') {
	            	syn = 24;
	                token[m] = ch;
	                m++;
	                p++;
            		ch = prog[p];
	            }
	            break;
	            
	        case ':':
	        	syn = 17;
	            m = 0;
	            token[m] = ch;
	            m++;
	            p++;
	            ch = prog[p];    
	            if (ch == '=') {
	            	syn = 18;
	                token[m] = ch;
	                m++;
	                p++;
	                ch = prog[p];
	            }
	            break;
	            
	        case '+':
	            syn = 13;
	            token[0] = ch;
				p++;
            	ch = prog[p];
	            break;
	            
	        case '-':
	            syn = 14;
	            token[0] = ch;
	            p++;
            	ch = prog[p];
				break;
	            
	        case '*':
	            syn = 15;
	            token[0] = ch;
	            p++;
            	ch = prog[p];
	            break;
	            
	        case '/':
	            syn = 16;
	            token[0] = ch;
	            p++;
            	ch = prog[p];
	            break;
 
	        case '=':
	            syn = 25;
	            token[0] = ch;
	            p++;
            	ch = prog[p];
	            break;
	            
	        case ';':
	            syn = 26;
	            token[0] = ch;
	            p++;
            	ch = prog[p];
	            break;
	            
	        case '(':
	            syn = 27;
	            token[0] = ch;
	            p++;
            	ch = prog[p];
	            break;
	            
	        case ')':
	            syn = 28;
	            token[0] = ch;
	            p++;
            	ch = prog[p];
	            break;
	            
	        case '#':
	            syn = 0;
	            token[0] = ch;
	            break;
	        default:
	        	syn = -1;
	        	break;        	
	        }
	} 
}

void Irparser(){
	if (syn ==1){
		scanner();
		yucu();
		if (syn == 6){
			scanner();	
			if (syn == 0 && (kk == 0)){
				cout << "success" << endl;
			}
		}
	    else{
			if (kk != 1){
				cout << "缺少end,error" << endl;
				kk = 1;
			}
		}
	}
	else{
		cout << "begin,error!" << endl;
		kk = 1;
	}
}

void yucu(){
	statement();
	while (syn == 26){
		scanner();
		statement();
	}
}

void statement(){
	if (syn == 10){
		scanner();
		if (syn == 18){
			scanner();
			expression();
		}
		else{
			cout << "赋值号error!" << endl;
			kk = 1;
		}
	}
	else{
		cout << "语句(标识符)error!" << endl;
		kk = 1; 
	}
}

void expression(){
	term();
	while(syn == 13 || syn == 14){
		scanner();
		term();
	}
}

void term(){
	factor() ;
	while (syn == 15 || syn == 16){
		scanner(); 
		factor();
	}
} 

void factor(){
	if(syn == 10 || syn == 11){
		scanner(); 
	}
	else if (syn == 27){
		scanner(); 
		expression();
		if (syn == 28){
			scanner(); 
		}
		else{
			cout << ")error!" << endl;
			kk = 1;
		}
	}
} 
 
int main(int argc, char** argv) {
 
	cout << "please input string: \n" << endl;
	
	p = 0;
	char str;
	
	//获取程序 
	do{
		str = getchar();
		prog[p] = str;
		p++;	
	}while(str != '#');
	
	p = 0;
	ch = prog[p];
	
	scanner();
	Irparser();
 
	//开始分析 
//	do{
//		scanner();
//		switch(syn){
//			case 11:
//				cout << "(" << syn << "," << sum << ")" << endl;
//				break;
//			case -1:
//				cout << "error" << endl;
//				break;
//			default:
//				cout << "("<< syn << "," << token << ")" <<endl;
//		}
//	}while(syn != 0);

	
    system("pause");
 
	return 0;
}
 
 
 
 
 
 

是的,终于写完啦,好开心!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值