⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syntax.cpp

📁 Win32 Console下C++实现的PL/0语言编译程序
💻 CPP
字号:
/*
FileName:		syntax.cpp
Author:			LiWen
Create:			2005-12-17
Last Modified:	2005-12-30
Discription:	语法分析和语义分析处理模块
*/
#include "compiler.h"
//////////////////////////////////////////////////////////////////////////////////////////////
//语法分析中的错误一般有两种:词写错或者词漏写。但只有在特殊情况下才能分辨出到底属于那种错误
//为了使语法分析尽可能的进行下去,在处理错误时,均认为是漏写错误错误,当一个语法分析单位结束
//后,对其后跟符号集进行检测,直到找到后跟符号集为止,再进行下一个语法单位的分析
//这样做,不可避免的会在出错的语法单元内相继报告出一些无效错误,我们只能根据特殊情况来修正
//
//
#define iskeyword(a) (a>=beginsym && a<=procsym)
#define isrelation(a) (a>=eql && a<=geq)
#define isoperation(a) (a>=)
#define isseparator(a) (a>=lparen&&a<=period)
#define isstatebegin(a) (a==ident||a==callsym||a==beginsym||a==ifsym||a==whilesym||a==readsym||a==writesym)
/**********************后跟符号集**************************/
#define isstatefollow(a) (a==period||a==semicolon||a==endsym)
#define isprocbodyfollow(a) (a==period||a==semicolon)
#define isprocdeclfollow(a) (a==procsym||isstatebegin(a))
#define isvarfollow(a)	isprocdeclfollow(a)
#define isconstfollow(a) (a==varsym||isprocdeclfollow(a))
#define iscdtfollow(a) (a==dosym||a==thensym)
#define isexpfollow(a) (isrelation(a)||isstatefollow(a)||a==dosym||a==thensym||a==rparen||a==comma)
#define istermfollow(a) (isexpfollow(a)||a==minus||a==plus)
#define isfactorfollow(a) (istermfollow(a)||a==times||a==slash)

extern symbol sym;
extern int row;
extern char word[];
extern int num;

extern TABLE table[];
extern int tx;

extern INSTRUCTION codelist[];
extern int cx;

/*=======================================================
函数:program
参数:无
描述:处理整个代码
返回:正常0,否则TMNT
========================================================*/
int program(){
	PRT_PROCBODY(0);
	if(sym == period)
		return 0;
	PRT_REPORT(MISSING_PERIOD);
	if(getsym()!=TMNT){
		PRT_REPORT(UNEXPECTED_EXTERN_CODE);
	}
	return 0;
}
/*=======================================================
函数:probody
参数:层数
描述:处理过程体,其第一个词型在sym中,当它返回时
      sym中为下一个语法结构的第一个词型
	  不检查开始符号集,交付statement处理
返回:正常0,否则TMNT
========================================================*/
int procbody(int lev){
	int dx = 3;
	int tx0,dx0,cx0;
	if(lev>LEVMAX){
		PRT_REPORT(PROC_LEV_TOO_DEEP);
	}
	tx0 = tx;					//记录
	dx0 = dx;
	cx0 = cx;
	table[tx0].addr = cx;			//useful in call procedure outside
	PRT_TRANSFORM(JMP,0,0);			//先为0,0,后面修改
	if(sym == constsym){
		PRT_CONSTDECLARE(lev,&dx);
	}
	if(sym == varsym){
		PRT_VARDECLARE(lev,&dx);
	}
	while(sym == procsym){
		PRT_PROCDECLARE(lev,&dx);
	}
	codelist[cx0].a = cx;
	table[tx0].addr = cx;
	PRT_TRANSFORM(INT,0,dx);
	PRT_STATEMENT(lev,&dx);
	PRT_TABLEPOP(tx-tx0);
	PRT_TRANSFORM(OPR,0,0);
	if(!isprocbodyfollow(sym)){
		PRT_REPORT(UNEXPECTED_PROCBODY_FOLLOW);
		while(!isprocbodyfollow(sym)){
			PRT_GETSYM();
		}
	}
	return 0;
}

/*=======================================================
函数:constdeclare
参数:层数,层偏移指针
描述:处理常量声明
返回:正常0,否则TMNT
========================================================*/
int constdeclare(int lev,int* pdx){
	int i;
	PRT_GETSYM();
	while(1){
		if(sym == ident){
			i = tablesearch(word);
			if(i!=0 && table[i].lev == lev){
				PRT_REPORT(IDENT_REDECLARED);
			}
			PRT_GETSYM();
		}else{
			PRT_REPORT(IDENT_IN_CONST_EXPECTING);
		}
		if(sym == eql){
			PRT_GETSYM();
		}else{
			PRT_REPORT(EQL_IN_CONST_EXPECTING);
		}
		if(sym == number){
			PRT_TABLEINSERT(lev,cst,pdx);
			PRT_GETSYM();
		}else{
			PRT_REPORT(NUM_IN_CONST_EXPECTING);
		}
		if(sym == comma){
			PRT_GETSYM();
		}else if(sym == semicolon){
			PRT_GETSYM();
			break;
		}else{
			PRT_REPORT(MISSING_SEMICOLON_IN_CONST);
			break;
		}
	}
	if(!isconstfollow(sym)){
		PRT_REPORT(UNEXPECTED_CONST_FOLLOW);
		while(!isconstfollow(sym)){
			PRT_GETSYM();
		}
	}
	return 0;
}
/*=======================================================
函数:vardeclare
参数:层数,层偏移指针
描述:处理变量声明
返回:正常0,否则TMNT
========================================================*/
int vardeclare(int lev, int* pdx){
	int i;
	PRT_GETSYM();
	while(1){
		if(sym == ident){
			i = tablesearch(word);
			if(i!=0 && table[i].lev == lev){
				PRT_REPORT(IDENT_REDECLARED);
			}
			PRT_GETSYM();
		}else{
			PRT_REPORT(IDENT_IN_VAR_EXPECTING);
		}
		PRT_TABLEINSERT(lev,var,pdx);
		if(sym == comma){
			PRT_GETSYM();
		}else if(sym == semicolon){
			PRT_GETSYM();
			break;
		}else{
			PRT_REPORT(MISSING_SEMICOLON_IN_VAR);
		}
	}
	if(!isvarfollow(sym)){
		PRT_REPORT(UNEXPECTED_VAR_FOLLOW);
		while(!isvarfollow(sym)){
			PRT_GETSYM();
		}
	}
	return 0;
}

int procdeclare(int lev,int*pdx){
	int i;
	PRT_GETSYM();
	if(sym == ident){
		i = tablesearch(word);
		if(i!=0 && table[i].lev == lev){
			PRT_REPORT(IDENT_REDECLARED);
		}
		PRT_TABLEINSERT(lev,proc,pdx);
		PRT_GETSYM();
	}else{
		PRT_REPORT(IDENT_IN_PROC_EXPECTING);
	}
	if(sym == semicolon){
		PRT_GETSYM();
	}else{
		PRT_REPORT(MISSING_SEMICOLON_IN_PROC);
	}
	PRT_PROCBODY(lev+1);
	if(sym == semicolon){
		PRT_GETSYM();
	}else{
		PRT_REPORT(MISSING_SEMICOLON_END_PROC);
	}
	if(!isprocdeclfollow(sym)){
		PRT_REPORT(UNEXPECTED_PROCDECL_FOLLOW);
		while(!isprocdeclfollow(sym)){
			PRT_GETSYM();
		}
	}
	return 0;
}

int statement(int lev,int* pdx){
	int i;
	int tcx,ccx;		//for jpc and PRT_CONDITION
	switch(sym){
	case ident:
		i = tablesearch(word);
		if(i == 0){
			PRT_REPORT(VAR_UNDECLARED);
			PRT_TABLEINSERT(lev,var,pdx);
		}else if(table[i].kind == constsym){
			PRT_REPORT(IDENT_CONST_IN_ASSIGN);
		}else if(table[i].kind == proc){
			PRT_REPORT(IDENT_PROC_IN_ASSIGN);
		}
		PRT_GETSYM();
		if(sym != becomes){
			PRT_REPORT(BECOMES_EXPECTING_IN_ASSIGN);
			break;
		}
		PRT_GETSYM();
		PRT_EXP(lev,pdx);
		PRT_TRANSFORM(STO,lev-table[i].lev,table[i].addr);
		break;
	case ifsym:
		PRT_GETSYM();
		PRT_CONDITION(lev,pdx);
		if(sym == thensym){
			PRT_GETSYM();
		}else{
			PRT_REPORT(THEN_EXPECTING_IN_IF);
		}
		tcx = cx;
		PRT_TRANSFORM(JPC,0,0);
		PRT_STATEMENT(lev,pdx);
		codelist[tcx].a = cx;
		break;
	case whilesym:
		PRT_GETSYM();
		ccx = cx;
		PRT_CONDITION(lev,pdx);			// if PRT_CONDITION false jmp
		tcx = cx;
		PRT_TRANSFORM(JPC,0,0);
		if(sym == dosym){
			PRT_GETSYM();
		}else{
			PRT_REPORT(DO_EXPECTING_IN_WHILE);
		}
		PRT_STATEMENT(lev,pdx);
		PRT_TRANSFORM(JMP,0,ccx);
		codelist[tcx].a = cx;
		break;
	case callsym:
		PRT_GETSYM();
		if(sym == ident){
			i = tablesearch(word);
			if(i == 0){
				PRT_REPORT(PROC_UNDECLARED);
			}else if(table[i].kind != proc){
				PRT_REPORT(PROC_EXPECTING_IN_CALL);
			}
			PRT_TRANSFORM(CAL,lev-table[i].lev,table[i].addr);
			PRT_GETSYM();
		}else{
			PRT_REPORT(PROC_EXPECTING_IN_CALL);
		}
		break;
	case readsym:
		PRT_GETSYM();
		if(sym == lparen){
			do{
				PRT_GETSYM();
				if(sym == ident){
					i = tablesearch(word);
					if(i == 0){
						PRT_REPORT(VAR_UNDECLARED);
					}else if(table[i].kind == constsym){
						PRT_REPORT(IDENT_CONST_IN_READ);
					}else if(table[i].kind == proc){
						PRT_REPORT(IDENT_PROC_IN_READ);
					}
					PRT_TRANSFORM(OPR,0,16);
					PRT_TRANSFORM(STO,lev-table[i].lev,table[i].addr);
					PRT_GETSYM();
				}else if(iskeyword(sym)){
					PRT_REPORT(KEYWORD_APPEAR_IN_READ);
				}else{
					PRT_REPORT(IDENT_EXPECTING_IN_READ);
				}
			}while(sym == comma);
		}else{
			PRT_REPORT(MISSING_LPAREN);
		}
		if(sym == rparen){
			PRT_GETSYM();
		}else{
			PRT_REPORT(MISSING_RPAREN);
		}
		break;
	case writesym:
		PRT_GETSYM();
		if(sym != lparen){
			PRT_REPORT(MISSING_LPAREN);
		}else{
			do{
				PRT_GETSYM();
				PRT_EXP(lev,pdx);
				PRT_TRANSFORM(OPR,0,14);
			}while(sym == comma);
		}
		if(sym == rparen){
			PRT_GETSYM();
		}else{
			PRT_REPORT(MISSING_RPAREN);
		}
		PRT_TRANSFORM(OPR,0,15);
		break;
	case beginsym:
		PRT_GETSYM();
		PRT_STATEMENT(lev,pdx);
		while(isstatebegin(sym) || sym == semicolon){
			if(sym==semicolon){
				PRT_GETSYM();
			}else{
				PRT_REPORT(MISSING_SEMICOLON_IN_STATEMENT);
			}
			PRT_STATEMENT(lev,pdx);
		}
		if(sym == endsym){
			PRT_GETSYM();
		}else{
			PRT_REPORT(MISSING_END);
		}
		break;
	default:
		if(isstatefollow(sym))
			break;
		PRT_REPORT(UNEXPECTED_STATEMENT_BEGIN);
		PRT_GETSYM();
		break;
	}
	if(!isstatebegin(sym)&&!isstatefollow(sym)){
		PRT_REPORT(UNEXPECTED_STATEMENT_FOLLOW);
		while(!isstatefollow(sym)){
			PRT_GETSYM();
		}
	}
	return 0;
}

int expression(int lev,int*pdx){
	enum symbol opr = sym;
	if(sym == plus || sym == minus){
		PRT_GETSYM();
	}
	PRT_TERM(lev,pdx);
	if(opr == minus){
		PRT_TRANSFORM(OPR,0,1);
	}
	while(sym == plus || sym == minus){
		opr = sym;
		PRT_GETSYM();
		PRT_TERM(lev,pdx);
		if(opr == plus){
			PRT_TRANSFORM(OPR,0,2);
		}else if(opr == minus){
			PRT_TRANSFORM(OPR,0,3);
		}
	}
	return 0;
}
int term(int lev,int* pdx){
	int opr;
	PRT_FACTOR(lev,pdx);
	while(sym == times || sym == slash){
		opr = (sym == times)?4:5;
		PRT_GETSYM();
		PRT_FACTOR(lev,pdx);
		PRT_TRANSFORM(OPR,0,opr);
	}
	return 0;
}

int factor(int lev,int* pdx){
	int i;
	if(sym == ident){
		i = tablesearch(word);
		if(i == 0){
			PRT_REPORT(VAR_UNDECLARED);
		}else if(table[i].kind == proc){
			PRT_REPORT(IDENT_PROC_IN_EXP);
		}else if(table[i].kind == cst){
			PRT_TRANSFORM(LIT,0,table[i].val);
		}else if(table[i].kind == var){
			PRT_TRANSFORM(LOD,lev-table[i].lev,table[i].addr);
		}
		PRT_GETSYM();
	}else if(sym == number){
		PRT_TRANSFORM(LIT,0,num);
		PRT_GETSYM();
	}else if(sym == lparen){
		PRT_GETSYM();
		PRT_EXP(lev,pdx);
		//PRT_GETSYM();
		if(sym == rparen){
			PRT_GETSYM();
		}else{
			PRT_REPORT(MISSING_RPAREN);
		}
	}
	if(!isstatebegin(sym)&&!isfactorfollow(sym)){
		PRT_REPORT(UNEXPECTED_FACTOR_FOLLOW);
		while(!isfactorfollow(sym)){
			PRT_GETSYM();
		}
	}
	return 0;
}


int condition(int lev,int* pdx){
	int opr;
	if(sym == oddsym){
		PRT_GETSYM();
		PRT_EXP(lev,pdx);
		return 0;
	}
	PRT_EXP(lev,pdx);
	if(!isrelation(sym)){
		PRT_REPORT(RELATIONOPR_EXPECTING_IN_CDT);
		return 0;
	}
	opr = sym - eql +8;			//8 -> opr 中 eql 的操作码
	PRT_GETSYM();
	PRT_EXP(lev,pdx);
	PRT_TRANSFORM(OPR,0,opr);
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -