实验二 递归下降语法分析
一、实验目的:
利用C语言编制递归下降分析程序,并对简单语言进行语法分析。
编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
二、实验原理
每个非终结符都对应一个子程序。
该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:
- 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
- 每遇到一个非终结符,则调用相应的子程序
三、实验要求说明
输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。
例如:
输入begin a:=9;x:=2*3;b:=a+x end #
输出success
输入x:=a+b*c end #
输出‘end' error
四、实验步骤
1.待分析的语言的语法(参考P90)
令语句为A,条件为B,表达式为C,项为D,因子为E
2.将其改为文法表示,至少包含
–语句
A-><id>:=<C>|if B then A|while B do A|begin A; end|ε
–条件
B->C=C|C<C|C<=C|C>=C|C>C
B->oddC
–表达式
C->+D|-D|D+D|D-D
–项
D->E|E*E|E/E
–因子
E-><id>
E-><integer>
E->’(’C’)’
3. 消除其左递归
4. 提取公共左因子
5. SELECT集计算
FIRST |
FOLLOW |
SELECT |
FIRST(A-><id>:=<C>)={<id>} FIRST(A->if B then A)={if} FIRST(A->while B do A)={while} FIRST(A->begin A; end)={begin} FIRST(A->ε)={ε} FIRST(B->C=C|C<C|C<=C|C>=C|C>C)={=,<<=,>,>=} FIRST(B->oddC)={odd} FIRST(C->+D|-D|D+D|D-D)={+/-} FIRST(D->E|E*E|E/E)={*,/} FIRST(E-><id>)=<id> FIRST(E-><integer>)=<integer> FIRST(E->’(’C’)’)=<’C’>
|
FOLLOW(A)={end,#} FOLLOW(B)={then,do} FOLLOW(C)={=,<<=,>,>=,)} FOLLOW(D)={+,-} FOLLOW(E)={*,/}
|
SELECT(A-><id>:=<C>)={<id>} SELECT(A->if B then A)={if} SELECT(A->while B do A)={while} SELECT(A->begin A; end)={begin} SELECT(A->ε)={end,#} SELECT(B->C=C|C<C|C<=C|C>=C|C>C)={=,<<=,>,>=} SELECT(B->oddC)={odd} SELECT(C->+D|-D|D+D|D-D)={+/-} SELECT(D->E|E*E|E/E)={*,/} SELECT(E-><id>)=<id> SELECT(E-><integer>)=<integer> SELECT(E->’(’C’)’)=<’C’>
|
6. LL(1)文法判断
其文法SELECT集没有交集,所以为LL(1)文法。
7. 递归下降分析程序
五、实验源程序
#include<string.h> #include<stdio.h> #include<stdlib.h> void lrparser(); void yucu(); void scaner(); //词法分析 void statement();//语句 void condition();//条件 void expression();//表达式 void term();//项 void factor();//因子 int kk=0; char prog[100],token[10];//输入程序段数组,大小为80 int syn,i=0,ks=0,js=0,m,n,sum=0,k=0; char ch; const char *blz[7]= {"begin","if","then","while","do","end","odd"};//保留字 int main() { // for(n=0;n<7;n++){ // printf("%s",blz[n]); // } printf("********************语法分析程序*************** "); printf("请输入源程序,以#结束: "); ch=getchar(); while(ch!='#') { prog[i]=ch; ch=getchar(); i++; } prog[i]='#'; i++; prog[i]='