编译原理 | 课程设计 — 语法分析

第1关:使用C/C++语言编写PL/0编译程序的语法分析程序

1、任务描述

基于第二章的词法分析程序,使用C/C++语言编写PL/0编译程序的语法分析程序。

2、编程要求

完成上述编程任务,将C/C++语言源程序复制粘贴到右侧代码编辑器,点击“评测”按钮,运行程序,系统会自动进行结果对比。

3、测试说明

平台会对你编写的代码进行测试:

测试输入:

const a = 10;
var   b, c;
procedure p;
    if a <= 10 then
        begin
            c := b + a;
        end;
begin
    read(b);
    while b # 0 do
        begin
            call p;
            write(2 * c);
            read(b);
        end;
end.

预期输出:

语法正确

测试输入:

const a := 10;
var   b, c;
procedure p;
    if a <= 10 then
        begin
            c := b + a;
        end;
begin
    read(b);
    while b # 0 do
        begin
            call p;
            write(2 * c);
            read(b);
        end;
end.

预期输出:

(语法错误,行号:1)

测试输入:

const a = 10;
var   b, c;
//单行注释
/*
* 多行注释
*/
procedure p;
    if a <= 10 then
        begin
            c := b + a
        end;
begin
    read(b);
    while b # 0 do
        begin
            call p;
            write(2 * c);
            read(b);
        end;
end.

预期输出:

(语法错误,行号:13)

测试输入:

const a = 10;
var   b, c;
//单行注释
/*
* 多行注释
*/
procedure p;
    if a <= 10 then
        begin
            c := b + a;
        end;
begin
    read(b);
    while b # 0
        begin
            call p;
            write(2 * c);
            read(b);
        end;
end.

预期输出:

(语法错误,行号:17)

测试输入:

const a := 10;
var   b, c d;
//单行注释
/*
* 多行注释
*/
procedure procedure fun1;
    if a <= 10 
        begin
            c = b + a
        end;
begin
    read(b;
    while b # 0 
        begin
            call fun1;
            write 2 * c);
            read(b);
        end;
end.

预期输出:

(语法错误,行号:1)
(语法错误,行号:2)
(语法错误,行号:10)
(语法错误,行号:11)
(语法错误,行号:13)
(语法错误,行号:16)
(语法错误,行号:17)
(语法错误,行号:20)

4、代码 

#include
#include
#include 
#include 

using namespace std;
int h=1;               //行号
char a[2000];         //所有字符
string END = "end.";
int i=0;
int ii=0;
char str[88]= "\0";
string ss[200]= {"\0"};
int cuowu=0;
int r=0;

string bao[20]= {"begin","call",
                 "const","do","end","if",
                 "odd","procedure",
                 "read","then",
                 "var","while","write"
                };

void strcatt(char *s,char c) {        //strcat(a,b)  将字符串a和b连起来
	int i=0;
	while(s[i]!='\0') i++;
	s[i]=c;
	s[i+1]='\0';

}

int length(char *a) {     //字符串的长度
	int i=0;
	while(a[i]!='\0') {
		i++;
	}
	return i;
}

int isstring(char ch) {              //判断是否字符
	if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
		return 1;
	else
		return 0;
}

int isyun(char ch) {                    //是否运算符
	if(ch=='>'||ch=='<'||ch=='='||ch=='*'||ch=='-'||ch=='+'||ch=='#')
		return 1;
	else
		return 0;
}

int isnum(char ch) {               //是否数字
	if((ch>='0'&&ch<='9'))
		return 1;
	else
		return 0;
}
int isjie(char ch) {          //是否界符
	if(ch==';'||ch=='.'||ch==','||ch=='('||ch==')')
		return 1;
	else
		return 0;
}

int isbao(char *s) {          //是否保留字

	for(int i=0; i<20; i++) if(bao[i].compare(s)==0) return 1;

	return 0;
}

void bb(char c) {        //处理字符串
	if(isstring(c)||isnum(c)) {
		strcatt(str,c);
		i++;
		bb(a[i]);
	}
//    else if(isnum(str[0])!=1)
	else if(c==' '||c=='\n'||c=='\0'||isyun(c)||isjie(c)) {
		if(isbao(str)) {
			ss[ii++]=str;
			//printf("(保留字,%s)\n",str);
			str[0]='\0';
		} else {
			if(length(str)>=8) printf("(标识符长度超长,%s,行号:%d)\n",str,h);
			else ss[ii++]=str;//printf("(标识符,%s)\n",str);
			str[0]='\0';
		}

	} else {
		strcatt(str,c);
		printf("(非法字符(串),%s,行号:%d)\n",str,h);
		i++;
		str[0]='\0';
	}
	//else printf("error\n");
}



void aa(char c) {   //处理数字串
	if(isnum(c)) {
		strcatt(str,a[i]);
		i++;
		aa(a[i]);
	} else if(!isstring(c)) {
		if(length(str)>=6) printf("(无符号整数越界,%s,行号:%d)\n",str,h);
		else ss[ii++]=str;//printf("(无符号整数,%s)\n",str);
		str[0]='\0';
	} else {
		while(a[i]!=' '&& isjie(a[i])!=1 && a[i]!='\0') {
			strcatt(str,a[i]);
			i++;
		}
		printf("(非法字符(串),%s,行号:%d)\n",str,h);
		str[0]='\0';

		//strcatt(str,c);
		//i++;
		//printf("(非法字符(串),%s,行号:%d)\n",str,h);
	}
	// else printf("error num\n");
}
void zhushi() {
	if(!ss[ii].compare("\n")) {
		ii++;
		h++;
	}
	if(!ss[ii].compare("//")) {
		ii++;
		ii++;
		while(!ss[ii].compare("\n")) {
			ii++;
			h++;
		}
		zhushi();
	} else if(!ss[ii].compare("/*")) {
		ii++;
		while(ss[ii].compare("*/")) {
			if(!ss[ii].compare("\n")) {
				ii++;
				h++;
			} else {
				ii++;
			}

		}
		ii++;
	}
	while(!ss[ii].compare("\n")) {
		ii++;
		h++;
	}
}

void changliang();
void error(int a);
void bianliang();
void yuju();
void tiaojian();
void biaodashi();
void xiang();
void yinzi();
void fenchengxv();
void shuzi() {
	ii++;
}
void biaoshifu() {
	ii++;
}
int  id() {
	int tt=0;
	for(tt=0; tt")||!ss[ii].compare(">=")) {
		ii++;
		biaodashi();
	} else if(!ss[ii].compare("odd")) {
		ii++;
		biaodashi();
	} else  error(0);
	//if(!ss[ii].compare("\n")) {ii++; h++;}
}

void biaodashi() {       //表达式
	xiang();
	if(!ss[ii].compare("+")||!ss[ii].compare("-")) {
		ii++;
		xiang();
		while (!ss[ii].compare("+")||!ss[ii].compare("-")) {
			ii++;
			xiang();
		}

	}
	//else if(!ss[ii].compare("\n")) {ii++; h++;}

}

void xiang() {     //项
	yinzi();
	while(!ss[ii].compare("*")||!ss[ii].compare("/")) {
		ii++;
		yinzi();
	}
}

void yinzi() {       //因子
	if(!ss[ii].compare("(")) {
		ii++;
		biaodashi();
		if(!ss[ii].compare(")")) {
			ii++;
		} else error(0);
	} else if(!ss[ii].compare("\n")) {
		ii++;
		h++;
	} else ii++;
}

//用gets()来输入,自动舍弃\n,输入一个字符串,结尾使用\0.


int main() {

	a[0]='\0';
	scanf("%[^\.]",a);
	a[length(a)]='.';



	while(a[i]!='\0') {   //每一行的每个字符    //词法分析

		if(a[i]=='\0') break;
		if(a[i]==9) {
			i++;
			continue;
		}  
		if(a[i]==' ')  {
			i++;
			continue;
		}
		if(a[i]=='\n') {
			ss[ii++]="\n";//ss用于存储单词,ii当前单词下标
			i++;
			h++;
		} else if(isstring(a[i])) {
			bb(a[i]);
			continue;//处理字符
		} else if(isnum(a[i])) {
			aa(a[i]) ;
			continue;//处理数字
		} else if(a[i]=='/') {
			if(a[i+1]=='/') {
				ss[ii++]="//";
				i=i+2;
				str[0]='\0';
				while(a[i]!='\n') strcatt(str,a[i++]);
				ss[ii++]=str;
				ss[ii++]="\n";
				i++;
				continue;
			} else if (a[i+1]=='*') {
				ss[ii++]="/*";
				i=i+2;
				while(!(a[i]=='*'&&a[i+1]=='/')) {
					if(a[i]=='\n') {
						ss[ii++]="\n";
						i++;
						continue;
					}
					str[0]='\0';
					while(a[i]!='\n') strcatt(str,a[i++]);
					ss[ii++]=str;
					ss[ii++]="\n";
					i++;
				}
				ss[ii++]="*/";
				i=i+2;
				str[0]='\0';
				continue;
			} else {
				while(a[i]!=' '&& isjie(a[i])!=1 && a[i]!='\0') {
					strcatt(str,a[i]);
					i++;
				}
				printf("(非法字符(串),%s,行号:%d)\n",str,h);
				str[0]='\0';
				break;
			}

		} else if(a[i]=='<'||a[i]=='>') {
			i++;
			if(a[i]=='=')  {
				if(a[i-1]=='<') ss[ii]="<=";

				else ss[ii]=">=";
				ii++;
				i++;
				continue;
			} else {
				if(a[i-1]=='<') ss[ii]="<";
				else ss[ii]=">";
				ii++;

				continue;
			}
		} else if(a[i]==':') {
			i++;
			if (a[i]=='=') {
				ss[ii++]=":=";

				i++;
				continue;
			} else {
				printf(":后面不是=号\n");
				continue;
			}
		} else if(isyun(a[i])) {
			ss[ii++]=a[i];
			i++;
			continue;
		} else if(isjie(a[i])) {
			ss[ii++]=a[i];
			i++;
			continue;
		} else {
			printf("(非法字符(串),%c,行号:%d)\n",a[i],h);
			i++;
		}
	}

	//语法分析
	i=0;
	ii=0;
	h=1;
	chengxv();
	return 0;
}

你可能感兴趣的:(编译原理,c++,c语言,编辑器,算法)