编译原理 用递归下降语法分析(包含词法分析) 来分析 test语言

 

下面的代码是摸爬滚打出来的,不一定完全正确(不过确实可以找出test语言里的9处错误哈)。

 

Test语言:

{
int a;
int i;
int 2b;
int c
for (i=1; i <= 10 i=i+1)
{
;
a=a+i
b=b*i;
{
c=a+b;
}
while(x<=)
{
C=a+b+(x*y;

if (a>b) 
{
read a;
}
else 
{
write b+5;
}
write c
}

语法分析代码(包含词法分析):

#include<stdio.h>
#include<ctype.h>
#include <conio.h>
#include<string.h>
#include<iostream>
#define keywordSum 7 
#include<stdlib.h> 
using namespace std;
char *keyword[keywordSum] = {"if","else","for","while","int","write","read"};
char words1[50] = "+-*(){};,:";
char words2[10] = "><=!";

 
char Scanin[300],Scanout[300];
char buffer1[20], buffer2[40]; //存放每个单词的类型和内容 
FILE *fin,*fout;
FILE *fp;   //用于语法分析时进行单词的依次读取 



//以下是各个函数的定义,包括词法分析函数,语法分析的入口,语法分析的每个产生式的函数。 
int TESTparse();
int program();
int compound_stat();
int statement();
int arithmetic_exprerrsion();
int assignment_exprerrsion();
int assignment_stat();
int bool_exprerrsion();
int term();
int factor();
int if_stat();
int while_stat();
int for_stat();
int write_stat();
int read_stat();
int declaration_stat();
int declaration_list();
int statement_list();
int compound_stat();
int TESTscan();


int main(){
	int err=0; //错误代码 
	err=TESTscan(); //词法分析 
	if(err>0)
	{
		cout<<"词法分析出现错误!"<<endl;;
	}
	else 
	{
		cout<<"词法分析完成!"<<endl;
		err = TESTparse(); //语法分析 
		if(err>0){
			cout << "语法分析出错!"<<endl;
		} else cout << "分析完成!"<<endl;
	}
	return 0;
}



declaration_stat(){
	int err = 0;
	fscanf(fp, "%s %s\n", &buffer1, &buffer2); 
	printf("%s %s\n", buffer1, buffer2);
	if (strcmp(buffer1, "ID"))	return(err = 3);
	if (err > 0) return(err);
	fscanf(fp, "%s %s\n", &buffer1, &buffer2); 
	printf("%s %s\n", buffer1, buffer2);
	if (strcmp(buffer1, ";"))	return(err = 4);
	fscanf(fp, "%s %s\n", &buffer1, &buffer2); 
	printf("%s %s\n", buffer1, buffer2);
	return(err);
}
declaration_list()
{
	int err = 0;
	while (strcmp(buffer1, "int") == 0)
	{
		err = declaration_stat();
		if (err > 0) return(err);
	}
	return(err);
}
statement()
{
	int err = 0;
	if (err == 0 && strcmp(buffer1, "if") == 0) 
		err = if_stat();
	if (err == 0 && strcmp(buffer1, "while") == 0) 
		err = while_stat();
	if (err == 0 && strcmp(buffer1, "for") == 0) 
		err = for_stat();
	if (err == 0 && strcmp(buffer1, "read") == 0) 
		err = read_stat();
	if (err == 0 && strcmp(buffer1, "write") == 0) 
		err = write_stat();
	if (err == 0 && strcmp(buffer1, "{") == 0) 
		err = compound_stat();
	if (err == 0 && (strcmp(buffer1, "ID") == 0 || strcmp(buffer1, "NUM") == 0 || strcmp(buffer1, "(") == 0)) 
		err = assignment_stat();
	if (err == 0 && strcmp(buffer1,";")==0)
	{
		fscanf(fp, "%s %s\n", &buffer1, &buffer2);
		printf("%s %s\n", buffer1, buffer2);
		return err;
	}
	return(err);
}
statement_list()
{
	int err = 0;
	//cout << "statement_list"<<endl; 
	while(strcmp(buffer1, "}"))   
	{
		err = statement();
		if (err > 0) return(err);	
	}

//	cout<<"statement_list:out"<<buffer1<<endl;

	return(err);
}

if_stat(){
	int err = 0;  //if
//	cout<<"if_stat"<<endl; 
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	if (strcmp(buffer1, "(")) 	
		return(err = 5);  
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	err = bool_exprerrsion();
	if (err > 0) 
		return(err);
	if (strcmp(buffer1, ")"))  
		return(err = 6); 
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	err = statement();
	if (err > 0) return(err);
	if (strcmp(buffer1, "else") == 0)
	{
		fscanf(fp, "%s %s\n", &buffer1, &buffer2);
		printf("%s %s\n", buffer1, buffer2);
		err = statement();
		if (err > 0) return(err);
		
	}
	return(err);
}
while_stat()
{
	int err = 0;
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	if (strcmp(buffer1, "("))  
		return(err = 5);  
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	err = bool_exprerrsion();
	if (err > 0) 
		return(err);
	if (strcmp(buffer1, ")"))  
		return(err = 6); 
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	err = statement();
	if (err > 0) 
		return(err);
	return(err);
}
for_stat(){
	int err = 0;
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	if (strcmp(buffer1, "("))  
		return(err = 5);
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	err = assignment_exprerrsion();
	if (err > 0) 
		return(err);
	if (strcmp(buffer1, ";")) 	
		return(err = 4);  
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	err = bool_exprerrsion();
	if (err > 0) 
		return(err);
	if (strcmp(buffer1, ";"))  
		return(err = 4);  
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	err = assignment_exprerrsion();
	if (err > 0) 
		return(err);
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	err = statement();
	if (err > 0) 
		return(err);

	return(err);

}
 read_stat()
{
	int err = 0, addrerrs;
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	if (strcmp(buffer1, "ID"))  
		return(err = 3);  
	if (err > 0) 
		return(err);

 

	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	if (strcmp(buffer1, ";"))  
		return(err = 4);  
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	return(err);
}
write_stat(){
	int err = 0;
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	err =  arithmetic_exprerrsion();
	if (err > 0)
		return(err);
	if (strcmp(buffer1, ";"))  
		return(err = 4);  
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	return(err);
}
compound_stat(){
	int err = 0; 
//	cout << "in"<<endl;
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
//	cout << buffer2<<endl;	
	err = statement_list();
	if(err>0) 
		return(err);
//	fpp = fp;
//	int chs = fgetc(fpp);
//	if(chs == EOF) 
//	{
//	    return (2);
//	}
	if(fscanf(fp, "%s %s\n", &buffer1, &buffer2)>0){
		printf("%s %s\n", buffer1, buffer2);
	}
	else{
		return 2;
	}  
//	cout << "out" <<endl;
	return (err);
}
assignment_exprerrsion()
{	
	int err = 0;
	if (strcmp(buffer1,"ID")) 
		return err=3;  
	if (err > 0)return err;
	fscanf(fp,"%s %s\n",&buffer1,&buffer2);
	printf("%s %s\n", buffer1, buffer2);
	//cout << buffer1 << endl;
	if (strcmp(buffer1,"=")) 
		return err =11; //期待一个等号 
    fscanf(fp,"%s %s\n",&buffer1,&buffer2);
    printf("%s %s\n", buffer1, buffer2);
    //cout<<buffer2<<endl;
    err = arithmetic_exprerrsion();
	if (err > 0)return err;
	return err;

}
assignment_stat(){
	int err = 0;
	err = assignment_exprerrsion();
//	cout << buffer2<<endl;
//	cout << err ;
	if (err > 0) 
		return (err);
	if (strcmp(buffer1,";")) 
		return err =4; //期待一个分号 
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	return err;
}
bool_exprerrsion(){
	int err=0;
    err=arithmetic_exprerrsion();
    if(err>0)
	    return(err);
    if(strcmp(buffer1,">")==0 || strcmp(buffer1,">=")==0
       || strcmp(buffer1,"<")==0 || strcmp(buffer1,"<=")==0
       || strcmp(buffer1,"==")==0 || strcmp(buffer1,"!=")==0)
    {
        fscanf(fp,"%s %s\n",buffer1,&buffer2);
        printf("%s %s\n",buffer1,buffer2);
        err=arithmetic_exprerrsion();
        if(err>0)
		    return(err);
    }
    return(err);
}
arithmetic_exprerrsion(){
	int err=0;
    err=term();
    if(err>0)
	    return(err);
    while(strcmp(buffer1,"+")==0 || strcmp(buffer1,"-")==0)
    {
        fscanf(fp,"%s %s\n",buffer1,&buffer2);
        printf("%s %s\n",buffer1,buffer2);
        err=term();
        if(err>0)
		    return(err);
    }
    return(err);
}
term(){
	int err=0;
    err=factor();
    if(err>0)
	    return(err);
    while(strcmp(buffer1,"*")==0 || strcmp(buffer1,"/")==0)
    {
        fscanf(fp,"%s %s\n",buffer1,&buffer2);
        printf("%s %s\n",buffer1,buffer2);
        err=factor();
        if(err>0)
		    return(err);
    }
    return(err);
}
factor()
{
    int err=0;
   // cout<<buffer1<<endl;
    if(strcmp(buffer1,"(")==0)
    {
        fscanf(fp,"%s %s\n",buffer1,&buffer2);
        printf("%s %s\n",buffer1,buffer2);
        err=arithmetic_exprerrsion();
        if(err>0)
		    return(err);
        if(strcmp(buffer1,")"))
		   return(err=6);
        fscanf(fp,"%s %s\n",buffer1,&buffer2);
        printf("%s %s\n",buffer1,buffer2);
    }else
    {
        if(strcmp(buffer1,"ID")==0)
        {

            if(err>0)
			    return(err);
            fscanf(fp,"%s %s\n",buffer1,&buffer2);
            printf("%s %s\n",buffer1,buffer2);
            return(err);
        }
        if(strcmp(buffer1,"NUM")==0)
        {
            fscanf(fp,"%s %s\n",buffer1,&buffer2);
            printf("%s %s\n",buffer1,buffer2);
            return(err);
        }else
        {
            err=7;
            return(err);
        }
    }
    return(err);
}
program(){
	int err = 0, i;
	fscanf(fp, "%s %s\n", buffer1, buffer2);
	printf("%s %s\n", buffer1, buffer2);
	if (strcmp(buffer1, "{")) //以读到{为入口  而且必须以{为起始 
	{
		err = 1;
		return(err);
	}
	fscanf(fp, "%s %s\n", &buffer1, &buffer2);
	printf("%s %s\n", buffer1, buffer2);
	err = declaration_list();
	if (err > 0)
	    return(err);
	err = statement_list();
	if (err>0)
	    return(err);
	if (strcmp(buffer1, "}")) //} 为结束 
	{
		err = 2;
		return(err);
	}
	int chs = fgetc(fp); //若结束后还有内容,则为冗余 
	if(chs != EOF) 
	{
		return 9;
	}
	return(err);
}
TESTparse(){
	int err = 0;
	if ((fp = fopen(Scanout, "r")) == NULL) //读词法分析的结果用于语法分析 
	{
		printf("\n打开%s错误!\n", Scanout);
		err = 8;
		return(err);
	}
	if (err == 0) err = program();
	printf("==语法、语义分析及代码生成程序结果==\n");
	switch (err)
	{
	case 0: printf("语法分析成功!\n"); break;
	case 1: printf("缺少{!\n"); break;
	case 2: printf("缺少}!\n"); break;
	case 3: printf("缺少标识符!\n"); break;
	case 4: printf("少分号!\n"); break;
	case 5: printf("缺少(!\n"); break;
	case 6: printf("缺少)!\n"); break;
	case 7: printf("缺少操作数!\n"); break;
	case 8: printf("打开文件 %s失败!\n", Scanout); break;
	case 9:printf("尾部有多余!\n");break;
	case 11:printf("期待一个=!\n");break; 
	}
	fclose(fp);
	fclose(fout);
	return(err);
}

TESTscan(){

	char ch, buffer1[40]; 
	int err = 0, j, n; 
	printf("请输入源程序文件名(包括路径):");
	scanf("%s", Scanin);
	printf("请输入词法分析输出文件名(包括路径):");
	scanf("%s", Scanout);
	if ((fin = fopen(Scanin, "r")) == NULL) 
	{
		printf("\n打开词法分析输入文件出错!\n");
		return(1);
	}
	if ((fout = fopen(Scanout, "w")) == NULL) 
	{
		printf("\n创建词法分析输出文件出错!\n");
		return(2); 
	}
	ch = getc(fin);
	while (ch != EOF)
	{
		while (ch == ' ' || ch == '\n' || ch == '\t') ch = getc(fin);
		if (ch == EOF) break;
		if (isalpha(ch)) 
		{
			buffer1[0] = ch; j = 1;
			ch = getc(fin);
			while (isalnum(ch))
			{
				buffer1[j++] = ch;  
				ch = getc(fin);
			}
			buffer1[j] = '\0'; 
			
			n = 0;
			while ((n < keywordSum) && strcmp(buffer1, keyword[n])) n++;
			if (n >= keywordSum)  
				fprintf(fout, "%s\t%s\n", "ID", buffer1);  
			else
				fprintf(fout, "%s\t%s\n", buffer1, buffer1);
		}
		else if (isdigit(ch))
		{
			buffer1[0] = ch; j = 1;
			ch = getc(fin);  
			while (isdigit(ch)) 
			{
				buffer1[j++] = ch; 
				ch = getc(fin); 
			}
			buffer1[j] = '\0'; 	 
			fprintf(fout, "%s\t%s\n", "NUM", buffer1); 
		}
		else if (strchr(words1, ch) > 0)
		{
			buffer1[0] = ch; buffer1[1] = '\0';
			ch = getc(fin);
			fprintf(fout, "%s\t%s\n", buffer1, buffer1); 
		}
		else if (strchr(words2, ch) > 0) 
		{
			buffer1[0] = ch;
			ch = getc(fin);
			if (ch == '=') 
			{
				buffer1[1] = ch; buffer1[2] = '\0'; 
				ch = getc(fin);
			}
			else
				buffer1[1] = '\0';
			fprintf(fout, "%s\t%s\n", buffer1, buffer1);
		}
		else if (ch == '/') 
		{
			ch = getc(fin); 
			if (ch == '*') 
			{
				char ch1;
				ch1 = getc(fin); 
				do
				{
					ch = ch1; ch1 = getc(fin);
				} 
				while ((ch != '*' || ch1 != '/') && ch1 != EOF);  
				ch = getc(fin);
			}
			else 
			{
				buffer1[0] = '/'; buffer1[1] = '\0';
				fprintf(fout, "%s\t%s\n", buffer1, buffer1);  
			}
		}
		else
		{
			buffer1[0] = ch; buffer1[1] = '\0';
			ch = getc(fin);  
			err = 3; 
			fprintf(fout, "%s\t%s\n", "ERROR", buffer1); 
		}
	}
	fclose(fin);
	fclose(fout);
	return(err); 
}

修改好了后的test语言:

{
int a;
int i;
int b;
int c;
int x;
int y;
int C;
for (i=1; i <= 10; i=i+1)
{
;
a=a+i;
b=b*i;
{
c=a+b;
}
while(x<=y)
{
C=a+b+(x*y);

if (a>b) 
{
read a;
}
else 
{
write b+5;
}
write c;
}
}
}

貌似不太符合理论要求哈。

好了,祝各位学业顺利

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值