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();
}

  

结果如下:

 

原文地址:https://www.cnblogs.com/tao614/p/11887950.html