作业12 实验二 递归下降语法分析

一、实验目的:

利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

 

二、实验原理

每个非终结符都对应一个子程序。

该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:

  • 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
  • 每遇到一个非终结符,则调用相应的子程序

 

三、实验要求说明

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。

例如:

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

输出success

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

输出‘end' error

 

四、实验步骤

1.待分析的语言的语法(参考P90)

2.将其改为文法表示,至少包含

–语句

–条件

–表达式

3. 消除其左递归

4. 提取公共左因子

5. SELECT集计算

6. LL(1)文法判断

7. 递归下降分析程序

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char prog[80],word[8],ch;
char *tag[6]={"begin","if","then","while","do","end"};
int syn,i,j,p,sum,row,y;
int flag=0;
void E();
void E2();
void E3();
void E4();
void E5();
void getsyn(){
	for(i=0;i<8;i++)
		word[i]=NULL;
	ch=prog[p++]; 
	while(ch==' '){
		ch=prog[p]; 
		p++;
	}
	//标识符
	if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
		j=0;
	while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
		word[j++]=ch;
		ch=prog[p++];
	}
	word[j++]='\0';
	p--;
	syn=10;
	for(i=0;i<6;i++){
		if(strcmp(tag[i],word)==0){
			syn=i+1;
			break;
		}
	}
	}
	//数字
	else if(ch>='0'&&ch<='9'){
		sum=0;
		while(ch>='0'&&ch<='9'){
			sum=sum*10+(ch-'0');
			ch=prog[p++];
		}
		p--;
		syn=11;
	}
	//符号
	else switch(ch){
		case ':':i=0;word[i++]=ch;
			ch=prog[p++];
			if(ch=='='){
				word[i++]=ch;
				syn=18;
			}else{
				syn=17;
				p--;
			}
			break;
		case '<':
			i=0; 
			word[i++]=ch;
			ch=prog[p++];
			if(ch=='='){
				word[i++]=ch;
				syn=21;
			}else if(ch=='>'){
				word[i++]=ch;
				syn=22;
			}else{
				syn=20;
				p--;
			}
			break;
		case '>':
			i=0;
			word[i++]=ch;
			ch=prog[p++];
			if(ch=='='){
				word[i++]=ch;
				syn=24;
			}else{
				syn=23;
				p--;
			}
			break;
		case '+':word[0]=ch;syn=13;break;
		case '-':word[0]=ch;syn=14;break;
		case '*':word[0]=ch;syn=15;break;
		//case '/':word[0]=ch;syn=16;break;
		case '=':word[0]=ch;syn=25;break;
		case ';':word[0]=ch;syn=26;break;
		case '(':word[0]=ch;syn=27;break;
		case ')':word[0]=ch;syn=28;break;
		case '#':word[0]=ch;syn=0;break;
		case '\n':syn=233;break;
		//注释
		case '/':
			i=0;
			word[i++]=ch;
			ch=prog[p++];
			if(ch=='/'){
				do{
					p++;
				}while(prog[p]!='\n');
					if(prog[p]=='\n'){
						syn=233;break;
					}
			}
			
			if(ch=='*'){
				do{
					p++;
					if(p==y-1 ){
						syn=-1;break;
					}
				}while(prog[p]=='*'&&prog[p+1]!='/'||prog[p]!='*'&&prog[p+1]=='/'||prog[p]!='*'&&prog[p+1]!='/');
				if(prog[p]=='*'&&prog[p+1]=='/'){
					p++;p++;
					syn=233;
					break;
				}
			}
			
			else{
				p--;ch=word[i];syn=16;break;
			}
			break;
			
		default:syn=-1;break;
	}
}

void E(){
    if(syn==1){
        getsyn();
        E2();
        while(syn==26){
            getsyn();
            E2();
        }
        if(syn==6){
            
            getsyn();
            if(syn==0 && flag==0){
                printf("success!\n");
            }        
        }
        else{
            printf("语法错误,缺少end!\n");
        }
    }else{
        printf("语法错误,缺少begin!\n");
        flag=1;
    }
    return ; 
    
}

void E2(){
    if(syn==10){
        getsyn();
        if(syn==18){
            getsyn();
            E3();
        }else{
            printf("表达式语法有误!错误为:%s\n",word);
            flag=1;
        }
    }else{
        if(flag!=1&&syn!=6){
            printf("表达式语法有误,错误为:%s\n",word);
            flag=1;
    }       
   }
	return ;
}

void E3(){
    E4();
    while(syn==13||syn==14){
        getsyn();
        E4();
    } 
    return ;
} 

void E4(){
    E5();
    while(syn==15||syn==16){
        getsyn();
        E5();
    } 
    return ;
}

void E5(){
    if(syn==10||syn==11){
        getsyn();
    }else if(syn==27){
        getsyn();
        E3();
        if(syn==28)
            getsyn();
        else{
            printf("缺少')',语法有误!\n");
            flag=1;
        }
    }
    else{
        printf("表达式语法有误!错误为:%s\n",word);
        flag=1;
    }
    return ;
}

int main(){
    p=0;
    printf("请输入语句段:");
    do{
        ch=getchar();
        prog[p++]=ch;
    }while(ch!='#');
    p=0;
    getsyn();
    E();
    printf("分析完毕!");
    getchar();    
}

 

 

 

 

 

 

 

 

posted @ 2019-11-29 19:04  seele233  阅读(187)  评论(0)    收藏  举报