1. 文法 G(S):
(1)S -> AB
(2)A ->Da|ε
(3)B -> cC
(4)C -> aADC |ε
(5)D -> b|ε
验证文法 G(S)是不是 LL(1)文法?
答:
FIRST(Da)={b,a}
FIRST(ε)={ε}
FIRST(aADC)={a}
FIRST(b)={b}
FOLLOW(A)={c,b,a,#}
FOLLOW(C)={#,}
FOLLOW(D)={a,#}
SELECT(A->Da)=FIRST(Da)={b,a}
SELECT(A->ε)=FIRST(ε)-{ε}UFOLLOW(A)=FOLLOW(A)={c,b,a,#}
因为SELECT(A->Da) ∩ SELECT(A->ε) ≠ Ø
所以G(S)不是 LL(1)文法。
2.(上次作业)消除左递归之后的表达式文法是否是LL(1)文法?
答:表达式文法为:
(1)E->TE'
(2)E'->+TE' | ε
(3)T->FT'
(4)T'->*FT' | ε
(5)F->(E) | i
FIRST(+TE')={+}
FIRST(ε)={ε}
FIRST(*FT')={*}
FIRST((E))={ ( }
FIRST(i)={i}
FOLLOW(E')={ ),# }
FOLLOW(T')={+,),#}
FOLLOW(F)={*,+,),#}
SELECT(E'->+TE')=FIRST(+TE')={+}
SELECT(E'->ε)=FIRST(ε)-{ε}UFOLLOW(E')=FOLLOW(E')={ ),# }
SELECT(T'->*FT')=FIRST(*FT')={*}
SELECT(T'->ε)=FIRST(ε)-{ε}UFOLLOW(T')=FOLLOW(T')={ +,),# }
SELECT(F->(E))=FIRST((E))={ ( }
SELECT(F->i)=FIRST(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()
答:
SELECT集:
SELECT(E->TE')=FIRST(TE')={ (, i }
SELECT(E'->+TE')=FIRST(+TE')={+}
SELECT(E'->ε)=FIRST(ε)-{ε}UFOLLOW(E')=FOLLOW(E')={ ),# }
SELECT(T->FT')=FIRST(FT')={ (,i }
SELECT(T'->*FT')=FIRST(*FT')={*}
SELECT(T'->ε)=FIRST(ε)-{ε}UFOLLOW(T')=FOLLOW(T')={ +,),# }
SELECT(F->(E))=FIRST((E))={ ( }
SELECT(F->i)=FIRST(i)={i}
递归下降语法分析程序:
void ParseE(){
switch(lookahead){
case '(','i':
ParseT();
ParseE'();
break;
default:
print("syntax error ");
exit(0);
}
}
void ParseE'(){
switch(lookahead){
case '+':
MatchToken('+');
ParseT();
ParseE'();
break;
case ')','#':
break;
default:
print("syntax error ");
exit(0);
}
}
void ParseT(){
switch(lookahead){
case '(','i':
ParseF();
ParseT'();
break;
default:
print("syntax error ");
exit(0);
}
}
void ParseT'(){
switch(lookahead){
case '*':
MatchToken('*');
ParseF();
ParseT'();
break;
case '+',')','#':
break;
default:
print("syntax error ");
exit(0);
}
}
void ParseF(){
switch(lookahead){
case '(':
MatchToken('(');
ParseE();
MatchToken(')');
break;
case 'i':
MatchToken('i');
break;
default:
print("syntax error ");
exit(0);
}
}
4.加上实验一的词法分析程序,形成可运行的语法分析程序,分析任意输入的符号串是不是合法的表达式。
1 //引入头文件 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 //声明变量 6 char prog[800],dc[8]; //程序段 单词 7 char ch; //单词中的字符 8 int syn,p,m=0; //单词符号种别码 指针p 9 int n,sum=0; //整数sum 10 char *word[6]={"begin","if","then","while","do","end"}; //保留字 11 int kk=0; //判断是否有错误 12 //声明函数 13 void scaner(); 14 void E(); 15 void T(); 16 void E1(); 17 void T1(); 18 void F(); 19 void error(); 20 21 void scaner(){ //读取一个字符 22 m=0; 23 //初始化数组dc 24 for(n=0;n<8;n++){ 25 dc[n]=NULL; 26 } 27 ch=prog[p++]; 28 //遇到空格指针加1 29 while(ch==' '){ 30 ch=prog[p]; 31 p++; 32 } 33 //标识符 34 if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ 35 m=0; 36 while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ 37 dc[m++]=ch; 38 ch=prog[p++]; 39 } 40 p--; 41 syn=10; 42 //保留字 43 for(n=0;n<6;n++){ 44 if(strcmp(dc,word[n])==0){ 45 syn=n+1; 46 break; 47 } 48 } 49 } 50 //数字 51 else if((ch>='0'&&ch<='9')){ 52 sum=0; 53 while((ch>='0'&&ch<='9')){ 54 sum=sum*10+ch-'0'; 55 ch=prog[p++]; 56 } 57 p--; 58 syn=11; 59 } 60 else{ 61 switch(ch){ 62 case '<':m=0; 63 dc[m++]=ch; 64 ch=prog[p++]; 65 if(ch=='>'){ 66 syn=22; 67 dc[m++]=ch; 68 } 69 else if(ch=='='){ 70 syn=21; 71 dc[m++]=ch; 72 } 73 else{ 74 syn=20; 75 p--; 76 } 77 break; 78 case '>':m=0; 79 dc[m++]=ch; 80 ch=prog[p++]; 81 if(ch=='='){ 82 syn=24; 83 dc[m++]=ch; 84 } 85 else{ 86 syn=23; 87 p--; 88 } 89 break; 90 case ':':m=0; 91 dc[m++]=ch; 92 ch=prog[p++]; 93 if(ch=='='){ 94 syn=18; 95 dc[m++]=ch; 96 } 97 else{ 98 syn=17; 99 p--; 100 } 101 break; 102 case '*':syn=15;dc[0]=ch;break; 103 case '/':syn=16;dc[0]=ch;break; 104 case '+':syn=13;dc[0]=ch;break; 105 case '-':syn=14;dc[0]=ch;break; 106 case '=':syn=25;dc[0]=ch;break; 107 case ';':syn=26;dc[0]=ch;break; 108 case '(':syn=27;dc[0]=ch;break; 109 case ')':syn=28;dc[0]=ch;break; 110 case '#':syn=0;dc[0]=ch;break; 111 case ' ':syn=-2;dc[0]=ch;break; 112 } 113 } 114 } 115 void E(){ 116 T(); 117 E1(); 118 } 119 void T(){ 120 F(); 121 T1(); 122 } 123 void E1(){ 124 if(syn==13){ 125 scaner(); 126 T(); 127 E1(); 128 } 129 else if(syn==0 || syn==28){ 130 } 131 else{ 132 kk=1; 133 error(); 134 exit(0); 135 } 136 } 137 void T1(){ 138 if(syn==15){ 139 scaner(); 140 F(); 141 T1(); 142 } 143 else if(syn==0 || syn==28 || syn==13){ 144 } 145 else{ 146 kk=1; 147 error(); 148 exit(0); 149 } 150 } 151 void F(){ 152 if(syn==27){ 153 scaner(); 154 E(); 155 if(syn==28){ 156 scaner(); 157 } 158 else{ 159 kk=1; 160 printf("出错,缺少 ')' , 不是合法的表达式! "); 161 exit(0); 162 } 163 } 164 else if(syn==11 || syn==10){ 165 scaner(); 166 } 167 else{ 168 kk=1; 169 error(); 170 exit(0); 171 } 172 } 173 void error(){ 174 printf(" (%s,出错!),不是合法的表达式!",dc); 175 } 176 int main(void){ 177 //指针从0开始 178 p=0; 179 printf("请输入符号串:"); 180 //逐个字符读入,放入字符数组prog中,直到'#'停止 181 do{ 182 ch=getchar(); 183 prog[p++]=ch; 184 }while(ch!='#'); 185 //指针从0开始 186 p=0; 187 do{ 188 scaner(); 189 E(); 190 }while(syn!=0); 191 if(kk=0){ 192 printf("符号串是合法的表达式!"); 193 } 194 }