实验4-5 预测分析表方法实验报告
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
elseif afollow(x)error(1);else error(2);
}while(x!=“#”)
三.实验要求
给定算术表达式文法,编写程序。
测试数据:
1.算术表达式文法
E→TE’
E’→ +TE’|- TE’|ε
T→FT’
T’→*FT’|/ FT’|%FT’|ε
F→(E) |id|num
给定一符合该文法的句子,如id+id*id#,运行预测分析程序,给出分析过程和每一步的分析结果。
case 6:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=1;break;
case 7:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
case 9: Push('G');Push('T');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
case 40:Push('i');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 41:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
case 43:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
(2)栈顶为非终结符A,串中当前单词不属于FOLLOW(A),则可使串指针下移一个位置(认为输入串中当前单词多余),继续分析。----------错误编号为2
(3)栈顶为终结符,且不等于串中当前单词,则从栈中弹出此终结符(认为输入串中缺少当前单词)或者将串指针下移一个位置(认为串中当前单词多余)。在程序中可选择上述ห้องสมุดไป่ตู้种观点中的一种进行处理。-------------错误编号3
构造正规式数组:char P[10][10]={“E->TE’”,”E’->+TE’”,……..}; (正规式可只存储右半部分,如E->TE’可存储为TE’,正规式中的符号可替换,如可将E’改为M )
构造预测分析表:int analyze_table[10][10]={ } //数组元素值存放正规式的编号,-1表示出错
将“#”和文法开始符依次压入栈中;
把第一个输入符号读入a;
do{
把栈顶符号弹出并放入x中;
if(x∈VT)
{
if(x==a)将下一输入符号读入a;
elseerror(3);
}
else
if(M[x,a]=“x→y1y2…yk”)
{
按逆序依次把yk、yk−1、…、y1压入栈中;
输出“x→y1y2…yk”;
case 16:printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 20:Push('S');Push('F');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
case 21:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;/////
{"ERROR", "G->+TG", "G->-TG", "ERROR", "ERROR","ERROR","G->ε", "G->ε", "ERROR", "ERROR"},//G
{"T->FS", "ERROR", "ERROR", "ERROR", "ERROR", "T->FS", "ERROR", "ERROR", "ERROR", "T->FS"},//T
//产生式表:E->TE' 1:E'->+TE' 2:E'->空
// 3:T->FT' 4:T'->*FT' 5:T'->空6:F->(E) 7:F->id
intanalysis_table[10][11]={0,-1,-1,0,-2,-2,0,0,0,0,0,
-1,1,-1,-1,2,2,0,0,0,0,0,
{"ERROR", "S->ε", "S->ε", "S->*FS", "S->/FS", "ERROR", "S->ε", "S->ε", "S->%FS", "ERROR"},//S
{"F->i", "ERROR", "ERROR", "ERROR", "ERROR","F->(E)","ERROR","ERROR", "ERROR", "F->n"} //F
{1,-1,-1,-1,-1, 1,-1,-1,-1, 1} //F
};
char* tstring[5][10] =
{
/* 0 1 2 3 4 5 6 7 8 9 */
/* i + - * / ( ) # % n */
{"E->TG", "ERROR", "ERROR", "ERROR", "ERROR","E->TG", "ERROR", "ERROR", "ERROR", "E->TG"},//E
} Lchar;
Lchar *p,*h,*temp,*top,*base;
char zhongjf; //终结符
char feijf; //非终结符
int a=0,i,j,k=0,table_index; //i,j用来表示数组中的位置,table_index用来记录10*i+j的值
int table[5][10] = //tstring的简化表-1代表当前终结符属于follow(A) -2代表当前终结符不属于follow(A)
构造非终结符数组:char Vn[10]={};
构造follow集数组:char *follow[10][10]={ } (可将follow集与预测分析表合并存放)
数据构造示例(使用的预测分析表构造方法1):
/*data1.h简单算术表达式数据*/
charVN[10][5]={"E","E'","T","T'","F"};//非终结符表
(2)预测分析表的构造方法2
可使用三维数组
Char analyze_table[10][10][10]={ }
或
Char *analyze_table[10][10][10]={ }
2.针对预测分析表构造方法1的查找方法提示:
(1)查非终结符表得到非终结符的序号no1
(2)查终结符表得到终结符的序号no2
}; //分析表
void Push(char pchar)//压栈
{
temp=(Lchar*)malloc(sizeof(Lchar));
temp->char_ch=pchar;
temp->next=top;
top=temp;
}
void Pop(void)//出栈
{
if(top->char_ch!='#')
(3)根据no1和no2查正规式表得到对应正规式的序号no3=analyze_table[no1][no2],如果no3=-1表示出错。
(4)根据no3查找对应的正规式P[no3]
(5)对正规式进行处理
3.错误处理机制
紧急方式的错误恢复方法(抛弃某些符号,继续向下分析)
(1)栈顶为非终结符A,串中当前单词属于FOLLOW(A),则从栈中弹出A(此时可认为输入串中缺少A表示的结构),继续分析。---------错误编号为1
{
/*i + - * / ( ) # % n*/
{1,-2,-2,-2,-2, 1,-1,-1,-2, 1},//E
{-2,1, 1,-2,-2,-2, 1, 1,-2,-2},//G
{1,-1,-1,-2,-2, 1,-1,-1,-2, 1},//T
{-2,1, 1, 1, 1,-2, 1, 1, 1,-2},//S
因此error()函数的编写方式可按如下方式处理
Error(int errornum)
{
If(errornum==1)………………
Else if(errornum==2)……………
Else………………..
//或者可用choose case语句处理
}
4.增加了错误处理的预测分析程序预测分析程序的算法:
case 29:Push('S');Push('F');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
case 33:Push('S');Push('F');Push('*');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
top=top->next;
}
void DoForPush(int t) //输出动作
{
switch(t)
{
case 0: Push('G');Push('T');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
case 5: Push('G');Push('T');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
intlength_vn=5;//非终结符的个数
charVT[15][5]={"id","+","*","(",")","#"};//终结符表
intlength_vt=6;//终结符的个数
charFa[15][10]={"TE'","+TE'","","FT'","*FT'","","(E)","id"};
输出形式参考下图:
四、编写实验报告
程序源代码
#include<iostream.h>
#include<stdio.h>
#include<malloc.h>
#include <conio.h>
#define true 1
typedef struct LLchar
{
char char_ch;
struct LLchar *next;
case 22:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
case 25:Push('S');Push('F');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
case 27:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
实验4-5预测分析表方法
一、实验目的
理解预测分析表方法的实现原理。
二、实验内容:
编写一通用的预测法分析程序,要求有一定的错误处理能力,出错后能够使程序继续运行下去,直到分析过程结束。可通过不同的文法(通过数据表现)进行测试。
二、实验内容提示
1.算法数据构造:
构造终结符数组:char Vt[10][5]={“id”,”+”……};
3,-2,-1,3,-2,-2,0,0,0,0,0,
-1,5, 4,-1,5, 5,0,0,0,0,0,
7,-2,-2,6,-2,-2,0,0,0,0,0};
//预测分析表,-1表示出错,-2表示该行终结符的follow集合,用于错误处理
(1)预测分析表的构造方法1
给文法的正规式编号:存放在字符数组中,从0开始编号,正规式的编号即为该正规式在数组中对应的下标。
case 34:Push('S');Push('F');Push('/');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 38:Push('S');Push('F');Push('%');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 44:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
case 45:Push(')');Push('E');Push('(');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 11:Push('G');Push('T');Push('+');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 12:Push('G');Push('T');Push('-');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
elseif afollow(x)error(1);else error(2);
}while(x!=“#”)
三.实验要求
给定算术表达式文法,编写程序。
测试数据:
1.算术表达式文法
E→TE’
E’→ +TE’|- TE’|ε
T→FT’
T’→*FT’|/ FT’|%FT’|ε
F→(E) |id|num
给定一符合该文法的句子,如id+id*id#,运行预测分析程序,给出分析过程和每一步的分析结果。
case 6:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=1;break;
case 7:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
case 9: Push('G');Push('T');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
case 40:Push('i');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 41:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
case 43:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
(2)栈顶为非终结符A,串中当前单词不属于FOLLOW(A),则可使串指针下移一个位置(认为输入串中当前单词多余),继续分析。----------错误编号为2
(3)栈顶为终结符,且不等于串中当前单词,则从栈中弹出此终结符(认为输入串中缺少当前单词)或者将串指针下移一个位置(认为串中当前单词多余)。在程序中可选择上述ห้องสมุดไป่ตู้种观点中的一种进行处理。-------------错误编号3
构造正规式数组:char P[10][10]={“E->TE’”,”E’->+TE’”,……..}; (正规式可只存储右半部分,如E->TE’可存储为TE’,正规式中的符号可替换,如可将E’改为M )
构造预测分析表:int analyze_table[10][10]={ } //数组元素值存放正规式的编号,-1表示出错
将“#”和文法开始符依次压入栈中;
把第一个输入符号读入a;
do{
把栈顶符号弹出并放入x中;
if(x∈VT)
{
if(x==a)将下一输入符号读入a;
elseerror(3);
}
else
if(M[x,a]=“x→y1y2…yk”)
{
按逆序依次把yk、yk−1、…、y1压入栈中;
输出“x→y1y2…yk”;
case 16:printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 20:Push('S');Push('F');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
case 21:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;/////
{"ERROR", "G->+TG", "G->-TG", "ERROR", "ERROR","ERROR","G->ε", "G->ε", "ERROR", "ERROR"},//G
{"T->FS", "ERROR", "ERROR", "ERROR", "ERROR", "T->FS", "ERROR", "ERROR", "ERROR", "T->FS"},//T
//产生式表:E->TE' 1:E'->+TE' 2:E'->空
// 3:T->FT' 4:T'->*FT' 5:T'->空6:F->(E) 7:F->id
intanalysis_table[10][11]={0,-1,-1,0,-2,-2,0,0,0,0,0,
-1,1,-1,-1,2,2,0,0,0,0,0,
{"ERROR", "S->ε", "S->ε", "S->*FS", "S->/FS", "ERROR", "S->ε", "S->ε", "S->%FS", "ERROR"},//S
{"F->i", "ERROR", "ERROR", "ERROR", "ERROR","F->(E)","ERROR","ERROR", "ERROR", "F->n"} //F
{1,-1,-1,-1,-1, 1,-1,-1,-1, 1} //F
};
char* tstring[5][10] =
{
/* 0 1 2 3 4 5 6 7 8 9 */
/* i + - * / ( ) # % n */
{"E->TG", "ERROR", "ERROR", "ERROR", "ERROR","E->TG", "ERROR", "ERROR", "ERROR", "E->TG"},//E
} Lchar;
Lchar *p,*h,*temp,*top,*base;
char zhongjf; //终结符
char feijf; //非终结符
int a=0,i,j,k=0,table_index; //i,j用来表示数组中的位置,table_index用来记录10*i+j的值
int table[5][10] = //tstring的简化表-1代表当前终结符属于follow(A) -2代表当前终结符不属于follow(A)
构造非终结符数组:char Vn[10]={};
构造follow集数组:char *follow[10][10]={ } (可将follow集与预测分析表合并存放)
数据构造示例(使用的预测分析表构造方法1):
/*data1.h简单算术表达式数据*/
charVN[10][5]={"E","E'","T","T'","F"};//非终结符表
(2)预测分析表的构造方法2
可使用三维数组
Char analyze_table[10][10][10]={ }
或
Char *analyze_table[10][10][10]={ }
2.针对预测分析表构造方法1的查找方法提示:
(1)查非终结符表得到非终结符的序号no1
(2)查终结符表得到终结符的序号no2
}; //分析表
void Push(char pchar)//压栈
{
temp=(Lchar*)malloc(sizeof(Lchar));
temp->char_ch=pchar;
temp->next=top;
top=temp;
}
void Pop(void)//出栈
{
if(top->char_ch!='#')
(3)根据no1和no2查正规式表得到对应正规式的序号no3=analyze_table[no1][no2],如果no3=-1表示出错。
(4)根据no3查找对应的正规式P[no3]
(5)对正规式进行处理
3.错误处理机制
紧急方式的错误恢复方法(抛弃某些符号,继续向下分析)
(1)栈顶为非终结符A,串中当前单词属于FOLLOW(A),则从栈中弹出A(此时可认为输入串中缺少A表示的结构),继续分析。---------错误编号为1
{
/*i + - * / ( ) # % n*/
{1,-2,-2,-2,-2, 1,-1,-1,-2, 1},//E
{-2,1, 1,-2,-2,-2, 1, 1,-2,-2},//G
{1,-1,-1,-2,-2, 1,-1,-1,-2, 1},//T
{-2,1, 1, 1, 1,-2, 1, 1, 1,-2},//S
因此error()函数的编写方式可按如下方式处理
Error(int errornum)
{
If(errornum==1)………………
Else if(errornum==2)……………
Else………………..
//或者可用choose case语句处理
}
4.增加了错误处理的预测分析程序预测分析程序的算法:
case 29:Push('S');Push('F');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
case 33:Push('S');Push('F');Push('*');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
top=top->next;
}
void DoForPush(int t) //输出动作
{
switch(t)
{
case 0: Push('G');Push('T');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
case 5: Push('G');Push('T');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
intlength_vn=5;//非终结符的个数
charVT[15][5]={"id","+","*","(",")","#"};//终结符表
intlength_vt=6;//终结符的个数
charFa[15][10]={"TE'","+TE'","","FT'","*FT'","","(E)","id"};
输出形式参考下图:
四、编写实验报告
程序源代码
#include<iostream.h>
#include<stdio.h>
#include<malloc.h>
#include <conio.h>
#define true 1
typedef struct LLchar
{
char char_ch;
struct LLchar *next;
case 22:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
case 25:Push('S');Push('F');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=0;break;
case 27:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
实验4-5预测分析表方法
一、实验目的
理解预测分析表方法的实现原理。
二、实验内容:
编写一通用的预测法分析程序,要求有一定的错误处理能力,出错后能够使程序继续运行下去,直到分析过程结束。可通过不同的文法(通过数据表现)进行测试。
二、实验内容提示
1.算法数据构造:
构造终结符数组:char Vt[10][5]={“id”,”+”……};
3,-2,-1,3,-2,-2,0,0,0,0,0,
-1,5, 4,-1,5, 5,0,0,0,0,0,
7,-2,-2,6,-2,-2,0,0,0,0,0};
//预测分析表,-1表示出错,-2表示该行终结符的follow集合,用于错误处理
(1)预测分析表的构造方法1
给文法的正规式编号:存放在字符数组中,从0开始编号,正规式的编号即为该正规式在数组中对应的下标。
case 34:Push('S');Push('F');Push('/');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 38:Push('S');Push('F');Push('%');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 44:printf("\t\t%s%c","错误1,跳过,弹出",top->char_ch);Pop();k=0;break;
case 45:Push(')');Push('E');Push('(');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 11:Push('G');Push('T');Push('+');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;
case 12:Push('G');Push('T');Push('-');printf("\t\t%s%s","展开非终结符",tstring[i][j]);k=1;break;