第十二次作业 递归下降语法分析

一、实验目的:

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

–语句

–条件

–表达式

3. 消除其左递归

4. 提取公共左因子

5. SELECT集计算

6. LL(1)文法判断

7. 递归下降分析程序

源代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

char read[800],d[8]; //程序段 单词
char ch; //单词中的字符
int syn,t,m=0; //单词符号种别码 指针p
int n,count=0; //整数count
char *id[40]={"begin","if","then","while","do","end","char","double","enum","float","int","long","short","signed",
"struct","union","unsigned","void","for","break","continue","else","goto","switch","case","default",
"return","auto","extern","register","static","const","sizeof","typedef","volatile"}; //保留字
int w=0; //判断是否有错误

void scaner();
void lrparser();
void yucu();
void statement();
void condition();
void expression();
void term();
void factor();

void scaner(){ //读取一个字符
m=0;
//初始化数组d
for(n=0;n<8;n++){
d[n]=NULL;
}
ch=read[t++];
//遇到空格指针加1
while(ch==' '){
ch=read[t];
t++;
}
//标识符
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
m=0;
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
d[m++]=ch;
ch=read[t++];
}
t--;
syn=10;
//保留字
for(n=0;n<6;n++){
if(strcmp(d,id[n])==0){
syn=n+1;
break;
}
}
}
//数字
else if((ch>='0'&&ch<='9')){
count=0;
while((ch>='0'&&ch<='9')){
count=count*10+ch-'0';
ch=read[t++];
}
t--;
syn=11;
}
else{
switch(ch){
case '<':m=0;
d[m++]=ch;
ch=read[t++];
if(ch=='>'){
syn=22;
d[m++]=ch;
}
else if(ch=='='){
syn=21;
d[m++]=ch;
}
else{
syn=20;
t--;
}
break;
case '>':m=0;
d[m++]=ch;
ch=read[t++];
if(ch=='='){
syn=24;
d[m++]=ch;
}
else{
syn=23;
t--;
}
break;
case ':':m=0;
d[m++]=ch;
ch=read[t++];
if(ch=='='){
syn=18;
d[m++]=ch;
}
else{
syn=17;
t--;
}
break;
case '*':syn=15;d[0]=ch;break;
case '/':syn=16;d[0]=ch;break;
case '+':syn=13;d[0]=ch;break;
case '-':syn=14;d[0]=ch;break;
case '=':syn=25;d[0]=ch;break;
case ';':syn=26;d[0]=ch;break;
case '(':syn=27;d[0]=ch;break;
case ')':syn=28;d[0]=ch;break;
case '#':syn=0;d[0]=ch;break;
case '\n':syn=-2;d[0]=ch;break;
}
}
}

//判断开初始符号和终结符
void lrparser(){
if (syn==1) { //begin
scaner();
yucu();
if (syn==6) { //end
scaner();
if (syn==0 && w==0){
printf("success \n");
}
}
else {
printf("error,lose 'end' ! \n");
w=1;
exit(0);
}
}
else {
printf("error,lose 'begin' ! \n");
w=1;
exit(0);
}
return;
}


void yucu() {
statement();
while(syn==26) {
scaner();
statement();
}
return;
}

void statement(){
if (syn==10) { //为标识符
scaner();
if (syn==18) { //为 :=
scaner();
expression();
}
else {
printf("error!");
w=1;
exit(0);
}
}
else if(syn==2){ //为if
condition();
scaner();
if(syn==3){
statement();
}
else{
printf("error,lose 'then' ! \n");
w=1;
exit(0);
}
}
else {
printf("error!");
w=1;
exit(0);
}

return;
}

void condition(){
expression();
if(syn==25||syn==0||syn==20||syn==21||syn==23||syn==24){
scaner();
}
else{
printf("error! \n");
w=1;
exit(0);
}
expression();
return;
}

void expression(){
term();
while(syn==13 || syn==14) {
scaner();
term();
}
return;
}

void term(){
factor();
while(syn==15 || syn==16) {
scaner();
factor();
}
return;
}

void factor(){
if(syn==10 || syn==11){
scaner(); //为标识符或整常数时,读下一个单词符号
}
else if(syn==27) {
scaner();
expression();
if(syn==28){
scaner();
}
else {
printf(" ')' 错误\n");
w=1;
exit(0);
}
} else {
printf("表达式错误\n");
w=1;
exit(0);
}
return;
}
int main(void){
//指针从0开始
t=0;
int i;
printf("请输入源程序:\n");
do {
scanf("%c",&ch);
read[t++]=ch;
} while(ch!='#');
//指针从0开始
t=0;
do{
scaner();
lrparser();
}while(syn!=0);
printf("语法分析结束!\n");

}

运行结果:

1.

2.

猜你喜欢

转载自www.cnblogs.com/fqy1028/p/11959063.html