zoukankan      html  css  js  c++  java
  • 实验二 递归下降语法分析

    一、实验目的:

    利用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.将其改为文法表示,至少包含

    –语句

    Y→i:=B | if T then Y1 | while T do Y1 | begin Y1 end | ε

    Y1→i:=B

    –条件

    T→B:=B

    –表达式

    B→i*i | i-i | i+i | i/i| i→iB'|ε

    B'→*i | -i | +i | /i

    3. 消除其左递归

    4. 提取公共左因子

    5. SELECT集计算

    6. LL(1)文法判断

    7. 递归下降分析程序

    源程序:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char prog[]="begin a:=9;x:=2*3;b:=a+x end #",token[20]; //程序段,单词符号
    //char prog[]="x:=a+b*c end #",token[20]; 
    char ch;
    int syn,p,m,n,sum;//单词符号类型syn,整数sum
    char *rwtab[6] = {"begin","if","then","while","do","end"};
    
    void Y();
    void Y1();
    void B();
    void B1();
    void T();
    void error();
    
    void scaner(){
    	for (n=0;n<20;n++)
    		token[n]=NULL;
    	m=0;
    	sum=0;
    	ch=prog[p++];
    	while(ch==' '){ //跳过空格 
    		ch=prog[p++];
    	}
    	if(ch>='a'&&ch<='z'){	//判断单词 
    		while(ch>='a'&&ch<='z'){
    			token[m++]=ch;
    			ch=prog[p++];
    		}
    		syn=10;
    		p--;
    		for(n=0;n<6;n++){
    			if(strcmp(token,rwtab[n])==0){
    				syn=n+1;
    				break;
    			}
    		}
    	}
    	else{	
    		if(ch>='0'&&ch<='9'){	//判断数字 
    			while(ch>='0'&&ch<='9'){
    				sum=sum*10+(ch-'0');
    				ch=prog[p++];
    			}
    			syn=11;
    			p--;
    		}
    		else{
    			switch(ch){
    				case '<':
    					token[m++]=ch;
    					ch=prog[p++];
    					if(ch=='>'){	//<>
    						syn=22;
    						token[m++]=ch;
    					}
    					else if(ch=='='){	//<=
    						syn=21;
    						token[m++]=ch;
    					}
    					else{	//<
    						syn=20;
    						p--;
    					}
    					break;
    				
    				case '>':
    					m=0;
    					token[m++]=ch;
    					ch=prog[p++];
    					if(ch=='='){	//>=
    						syn=24;
    						token[m++]=ch;
    					}
    					else{	//>
    						syn=23;
    						p--;
    					}
    					break;
    					
    				case ':':
    					m=0;
    					token[m++]=ch;
    					ch=prog[p++];
    					if(ch=='='){	//:=
    						syn=18;
    						token[m++]=ch;
    					}
    					else{	//:
    						syn=17;
    						p--;
    					}
    					break;
    					
    				case '+':syn=13;token[0]=ch;break;
    				case '-':syn=14;token[0]=ch;break;
    				case '*':syn=15;token[0]=ch;break;
    				case '/':syn=16;token[0]=ch;break;
    				case '=':syn=25;token[0]=ch;break;
    				case ';':syn=26;token[0]=ch;break;
    				case '(':syn=27;token[0]=ch;break;
    				case ')':syn=28;token[0]=ch;break;
    				case '#':syn=0;token[0]=ch;break;
    				default:syn=-1;token[0]=ch;break;
    			}
    		}
    	}
    }
    
    
    void Y(){
    	if(syn == 1){
    		scaner();
    		while(syn!=6&&syn!=0){
    			Y1();
    		}
    		if(syn == 6){
    			scaner();
    			printf("success");
    		}
    		else
    			error();
    	}
    	else if (syn ==4){
    		scaner();
    		while(syn!=5){
    			T();
    		}
    		if(syn == 5 ){
    			scaner();
    			while(syn!=0){
    				Y1();
    			}
    		}
    		else
    			error();
    	}
    	else if (syn ==2){
    		scaner();
    		while(syn!=3){
    			T();
    		}
    		if(syn == 3){
    			scaner();
    			while(syn!=0){
    				Y1();
    			}
    		}
    		else
    			error();
    	}
    	else if	(syn ==0){//空 
    	}
    	else if(syn == 10){//变量 
    		if(syn ==2 || syn ==5|| syn==6){
    			error();
    		}
    		else{
    			scaner();
    			if(syn==18){
    				scaner();
    				B();
    				while(syn!=0){
    					Y1();
    				}	
    			}
    			else
    				error();
    		}	
    	}
    	else
    		error();
    }
    void Y1(){
    		if(syn == 10){
    			scaner();
    			if(syn==18){
    				scaner();
    				B();
    				}	
    			}
    			else
    				error();
    }	
    
    void B(){
    	if(syn == 10|| syn ==11){//变量或者数字 
    		scaner();
    		while(syn==13||syn==14||syn==15||syn==16){
    			B1();
    		}
    		if(syn == 26){
    			scaner();
    		}
    	}
    	else
    		error();
    }
    void B1(){
    		if(syn == 13){//+ 
    			scaner();
    			if(syn == 10|| syn ==11){
    				scaner();
    			}
    			else
    				error();
    		}
    		else if(syn == 14){//- 
    			scaner();
    			if(syn == 10|| syn ==11){
    				scaner();
    			}
    			else
    				error();
    		}
    		else if(syn == 15){//* 
    			scaner();
    			if(syn == 10|| syn ==11){
    				scaner();
    			}
    			else
    				error();
    		}
    		else if(syn == 16){// / 
    			scaner();
    			if(syn == 10|| syn ==11){
    				scaner();
    			}
    			else
    				error();
    		}
    }
    void T(){
    	B();
    	if(syn == 18){
    		scaner();
    		B();
    	}
    	else
    		error();
    }
    
    
    
    void error(){
    	printf("error
    ");
    	printf("
    (%s,出错!)",token);
    	exit(0);
    }
    
    main(){
    	scaner();
    	Y();	
    }
    

      实验结果:

  • 相关阅读:
    python 文件 笔记
    python 模块、包 笔记
    类、对象
    python 函数 笔记
    测试价值体现
    断舍离-笔记2
    Happy 2006 POJ
    Triangle War POJ
    Complete the sequence! POJ
    放苹果 POJ
  • 原文地址:https://www.cnblogs.com/tao614/p/11934437.html
Copyright © 2011-2022 走看看