zoukankan      html  css  js  c++  java
  • LL(1)文法的判断

    文法 G(S):

    (1)S -> AB

    (2)A ->Da|ε

    (3)B -> cC

    (4)C -> aADC |ε

    (5)D -> b|ε

    验证文法 G(S)是不是 LL(1)文法.

    FIRST(S)={b,a,c}

    FIRST(A)={b,a}

    FIRST(B)={c}

    FIRST(C)={a}

    FIRST(D)={b}

    FOLLOW(A)={c,b,a,#}

    FOLLOW(C)={#}

    FOLLOW(D)={a,#}

    SELLECT(A ->Da)={a,b}

    SELLECT(A ->ε)={c,b,a,#}

    SELLECT(C -> aADC)={a}

    SELLECT(C -> ε)={#}

    SELLECT(D -> b)={b}

    SELLECT(D -> ε)={a,#}

    因为

    SELLECT(A ->Da)∩SELLECT(A ->ε)≠∅

    SELLECT(C -> aADC)∩SELLECT(C -> ε)=∅

    SELLECT(D -> b)∩SELLECT(D -> ε)=∅

    故文法 G(S)不是 LL(1)文法.

    2.法消除左递归之后的表达式文法是否是LL(1)文法?

    消除左递归后:

    E→TE'

    E'→+TE'|ε

    T→FT'

    T'→*FT'|ε

    F→(E)|i

    FIRST集:

    FIRST(E)→FIRST(T)→FIRST(F)→{ ( , i }

    FIRST(E')→{+,ε}

    FIRST(T)→FIRST(F)→{ ( , i }

    FIRST(T')→{*,ε}

    FIRST(F)→{ ( , i }

    FOLLOW集:

    FOLLOW(E)→{ ) , #  }

    FOLLOW(E')→{ ) , # }

    FOLLOW(T)→{ + , ) , # }

    FOLLOW(T')→{ + , ) , # }

    FOLLOW(F)→{ * , + , ) , # }

    SELECT集:

    SELECT(E→TE')={ ( , i }

    SELECT(E'→+TE')={+}

    SELECT(E'→ε)={),#}

    SELECT(T→FT')={ ( , i }

    SELECT(T'→*FT')={*}

    SELECT(T'→ε)={+,),#}

    SELECT(F→(E))={(}

    SELECT(F→i)={i}

    因为

    SELECT(E'→+TE')∩SELECT(E'→ε)=∅

    SELECT(T'→*FT')∩SELECT(T'→ε)=∅

    SELECT(F→(E))∩SELECT(F→i)=∅

    故该文法是 LL(1)文法.

    3.接2,如果是LL(1)文法,写出它的递归下降语法程序。

    E()

        {T();

           E'();

         }

    E'()

    T()

    T'()

    F()

    递归下降语法程序:

    void ParseS()
    {
    	switch(lookahead){
    		case (,i:
    			ParseT();
    			ParseE'();
    			break;
    		default:
    			printf("syntax error 
    ");
    			exit(0);
    	}
    }
    void ParseE'()
    {
    	switch(lookahead){
    		case +:
    			MatchToken(+);
    			ParseT();
    			ParseE'();
    			break;
    		case ),#:
    			break;
    		default:
    			printf("syntax error 
    ");
    			exit(0);		
    	}
    }
    void ParseT()
    {
    	switch(lookahead){
    		case (,i:
    			ParseF();
    			ParseT'();
    			break;
    		default:
    			printf("syntax error 
    ");
    			exit(0);
    	}
    }
    void ParseT'()
    {
    	switch(lookahead){
    		case *:
    			MatchToken(*);
    			ParseF();
    			ParseT'();
    			break;
    		case +,),#:
    			break;
    		default:
    			printf("syntax error 
    ");
    			exit(0);		
    	}
    }
    void ParseF()
    {
    	switch(lookahead){
    		case (:
    			MatchToken(();
    			ParseE();
    			MatchToken());
    			break;
    		case i:
    			MatchToken(i);
    			break;
    		default:
    			printf("syntax error 
    ");
    			exit(0);		
    	}
    }
    

      

     4.加上实验一的词法分析程序,形成可运行的语法分析程序,分析任意输入的符号串是不是合法的表达式。

    使用上面的文法进行的语法分析程序代码如下:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char prog[]="a*b+c#",token[20]; //程序段,单词符号
    char ch;
    int syn,p,m,n,sum;//单词符号类型syn,整数sum
    char *rwtab[6] = {"begin","if","then","while","do","end"};
    
    void E();
    void T();
    void E1();
    void T1();
    void F();
    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 E(){
    	T();
    	E1();
    }
    
    
    
    void E1(){
    	if (syn == 13){
    		scaner();
    		T();
    		E1();
    	}
    	else if(syn ==0 || syn == 28){
    		
    	}
    	else
    		error();
    }
    
    void T(){
    	F();
    	T1();
    }
    
    void T1(){
    	if(syn == 15){
    		scaner();
    		F();
    		T1();
    	}
    	else if (syn == 0 || syn == 28 || syn ==13){
    		
    	}
    	else
    		error();
    }
    
    void F(){
    	if(syn == 27){
    		scaner();
    		E();
    		if(syn == 28){
    			scaner();
    			printf("success
    ");
    		}
    		else
    			error();
    	}
    	else if(syn == 11 || syn == 10){
    		scaner();
    		printf("success
    ");
    	}	
    	else
    		error();
    }
    
    void error(){
    	printf("error
    ");
    	printf("
    (%s,出错!)",token);
    }
    
    main(){
    	scaner();
    	E();
    }
    

      

    结果如下:

     

  • 相关阅读:
    gevent实现基于epoll和协程的服务器
    用greenlet实现协程消费者生产者
    More is better(MST)(求无向图中最大集合元素个数)
    小希的迷宫(MST单棵树判断法则)
    畅通工程再续(MST)
    畅通工程再续
    畅通工程
    还是畅通工程(MST)
    Minimum Inversion Number
    Who Gets the Most Candies?(线段树 + 反素数 )
  • 原文地址:https://www.cnblogs.com/tao614/p/11887950.html
Copyright © 2011-2022 走看看