您的位置:首页 > 其它

编译原理实验之预测分析算法的设计与实现

2014-09-08 23:45 831 查看
不要被大段的代码吓到,其实问题很简单,只需照着书上的过程走即可。

实验要求:

输入文法及待分析的输入串,输出其预测分析过程及结果。(基本要求就是:所有字符都只有一个字符组成,不能出现A*等字符,你可自行修改自己的文法后在用下面的代码)

注明:代码分了多个写,主函数是1.cpp代码如下(后期我会再发个链接过来可直接看到源文件,对不太熟悉VS工具的比较有帮助),想看中间结果的话可以将注释解开即可:

#include"head.h"
#include"apart_from.h"
#include"first.h"
#include"follw.h"
#include"table.h"
#include"judge.h"

int main(){
int i=0,j;
while((scanf("%s",form[i].formula),form[i].formula[0])!='#'){
i++;
}
sum = i;
apart();

First();
Follow();
printf("非终结符:\n");
printf("%s\n",ter_symbol);
printf("终结符:\n");
printf("%s\n",non_ter);

/*
printf("first集:\n");
for(j=0;j<strlen(ter_symbol);j++)
printf("%s\n",first_set[j]);
printf("follow集:\n");
for(j=0;j<strlen(ter_symbol);j++)
printf("%s\n",follow_set[j]);
*/

getTable();
//printTable();//输出预测表
printf("输入串(以‘#’号键结束):\n");
scanf("%s",inter_symbol);
while(inter_symbol[strlen(inter_symbol)-1]!='#'){
printf("输入串没有以‘#’号键结束,请重新输入:\n");
scanf("%s",inter_symbol);
}
printf("步骤 符号栈 输入串 所用产生式\n");
printf("---- ------ ------ ----------\n");
Judge();
return 0;
}

 
apart_from.h的代码:

 void apart(){
int i,len,k=0,j,l,p;
for(i=0;i<sum;i++){
for(j=0;j<k;j++){
if(ter_symbol[j]==form[i].formula[0])
break;
}
if(j==k)
ter_symbol[k++] = form[i].formula[0];
}//非终结符
ter_symbol[k]='\0';

k=0;
for(i=0;i<sum;i++){
len = strlen(form[i].formula);
for(j=3;j<len;j++){
if(form[i].formula[j]=='$')
break;
for(l=0;l<strlen(ter_symbol);l++){
if(form[i].formula[j]==ter_symbol[l])
break;
}
for(p=0;p<k;p++){
if(form[i].formula[j]==non_ter[p])
break;
}
if(l==strlen(ter_symbol)&&p==k){
non_ter[k++]=form[i].formula[j];
}
}
}//终结符
non_ter[k]='\0';
}
head.h的代码:

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

typedef struct {
char formula[200];//表达式
}grammerElement;
grammerElement form[200]; //原始文法的产生式集
int sum;

char ter_symbol[200];//非终结符号
char non_ter[200];//终结符号
char inter_symbol[400];//输入符号
char first_set[100][100];//各产生式右部的FIRST集
char follow_set[100][100];//各产生式左部的FOLLOW集
int M[200][200];//分析表

//判断是非终结符
int get_ter(char a){
for(int i=0;i<strlen(ter_symbol);i++)
if(ter_symbol[i]==a)
return i;
return -1;
}
//判断是终结符
int get_non(char a){
for(int i=0;i<strlen(non_ter);i++){
if(non_ter[i]==a)
return i;
}
return -1;
}

//判断将要加入的first集的终结符是否已经存在。
int is_sameFir(int col,int stop,char a){
for(int i=1;i<stop;i++){
if(first_set[col][i]==a)
return 0;
}
return 1;
}

//判断将要加入的follow集的终结符是否已经存在。
int is_sameFol(int col,int stop,char a){
for(int i=1;i<stop;i++){
if(follow_set[col][i]==a)
return 0;
}
return 1;
}

void printTable(){
for(int i=0;i<strlen(ter_symbol);i++){
for(int j=0;j<strlen(non_ter)+1;j++)
printf("%d ",M[i][j]);
printf("\n");
}
}

first.h的代码:

//求一个非终结符的first集
int getFirst(char a,int col){
int i,j,k=1,l,p;
for(i=0;i<sum;i++){
if(form[i].formula[0]==a){
for(j=0;j<strlen(non_ter);j++){
if(form[i].formula[3]==non_ter[j])
break;
} //判断是否是终结符
if(j<strlen(non_ter)){
if(is_sameFir(col,k,form[i].formula[3]))
first_set[col][k++]=form[i].formula[3];
continue;
}//右部首字母是终结符;
else if(form[i].formula[3]=='$'){
if(is_sameFir(col,k,'$'))
first_set[col][k++]='$';
continue;
}//右部首字母是kong;
else if(form[i].formula[3]==a)
continue;//右部首字母是自己;
else{//printf("%d 1\n",col);
for(l=3;l<strlen(form[i].formula);l++){//循环表达式找
for(j=0;j<strlen(ter_symbol);j++){//printf("%d 2\n",col);
if(form[i].formula[l]==ter_symbol[j])
break;
}//找到非终结符的下标
if(j==strlen(ter_symbol)){//printf("%d 3\n",col);
if(is_sameFir(col,k,form[i].formula[l]))
first_set[col][k++]=form[i].formula[l];
break;
}//循环中碰到终结符,结束

if(first_set[j][0]=='0')
getFirst(form[i].formula[l],j);//printf("%d 4\n",col);}//first集未求,递归求first集

for(p=1;p<strlen(first_set[j]);p++){//检查first集有没有空
if(first_set[j][p]=='$')
break;
else if(is_sameFir(col,k,first_set[j][p])) //把非空的加进first集
first_set[col][k++]=first_set[j][p];//printf("%d 5\n",col);}
}
if(p==strlen(first_set[j])){//没有非空的就跳出
//flag=1;
break;
}
}
if(l==strlen(form[i].formula)&&is_sameFir(col,k,'$'))
first_set[col][k++]='$';
}
}
}
first_set[col][k]='\0';
first_set[col][0]='1';//标志已经求得first集
return 0;
}

void First(){
int i,len_ter=strlen(ter_symbol);
for(i=0;i<len_ter;i++){
first_set[i][0]='0';
}
for(i=0;i<len_ter;i++){
if(first_set[i][0]=='0')
getFirst(ter_symbol[i],i);
}
}


follow.h的代码:

int getFollow(char a,int col){
int i,j,len,k=1,p,l,flag;
if(col==0)
k=2;
for(i=0;i<sum;i++){
len=strlen(form[i].formula);

for(j=3;j<len;j++){
flag=0;
if(form[i].formula[j]==a){
if(j<len-1){//printf("%d %c1\n",col,a);//当前非终结符不是最终字符
for(p=0;p<strlen(ter_symbol);p++){
if(form[i].formula[j+1]==ter_symbol[p])
break;
}//找到后边非终结符的下标
if(p==strlen(ter_symbol)){//终结符
if(is_sameFol(col,k,form[i].formula[j+1]))
follow_set[col][k++]=form[i].formula[j+1];//printf("%d 2\n",col);
continue;
}
else{//printf("%d 3\n",col);//非终结符
for(l=1;l<strlen(first_set[p]);l++)
if(first_set[p][l]=='$')//将来会有漏洞
{flag=1;}
else if(is_sameFol(col,k,first_set[p][l])){

follow_set[col][k++]=first_set[p][l];
}
}

}//if/
if(j==len-1||flag){//if(col==2) return 0;//printf("%d 4 %s %s\n",col,follow_set[0],follow_set[1]);//

p=get_ter(form[i].formula[0]);//找到后边非终结符的下标
if(a==form[i].formula[0])
{//printf("%d 4 %s %s\n",col,follow_set[0],follow_set[1]);
break;}
if(follow_set[p][0]=='0'){
getFollow(ter_symbol[p],p);
//printf("%d %c5\n",col,ter_symbol[p]);
}
for(l=1;l<strlen(follow_set[p]);l++){
if(is_sameFol(col,k,follow_set[p][l]))
follow_set[col][k++]=follow_set[p][l];
}
}
}
}
}
if(strlen(follow_set[col])>1)
follow_set[col][0]='1';
follow_set[col][k]='\0';
return 0;
}

void Follow(){
int i;
for(i=0;i<strlen(ter_symbol);i++){
follow_set[i][0]='0';
}
//follow_set[0][0]='1';
follow_set[0][1]='#';
for(i=0;i<strlen(ter_symbol);i++){
// printf("%s\n",follow_set[0]);
if(follow_set[i][0]=='0')
getFollow(ter_symbol[i],i); //printf("%c...............\n",ter_symbol[i]);}
}
}


judge.h的代码:

int top;
char stack[200];
int x;
void Judge(){
stack[0]='#';
stack[1]=form[0].formula[0];
int flag=1,step=0;
int i,j,l;
char print[100];
top=1;
x=0;//printf("---- ------ ------\n");
printf(" %d ",step++);
for(l=0;l<=top;l++)
printf("%c",stack[l]);
for(l=0;l<=22-top+x;l++)
printf(" ");
for(l=x;l<strlen(inter_symbol);l++)
printf("%c",inter_symbol[l]);
printf("\n");
while(flag){
if(get_non(stack[top])>=0){
if(stack[top]==inter_symbol[x]){
x++;//终结符匹配上
top--;
if(step<10)
printf(" %d ",step++);
else
printf(" %d ",step++);
for(l=0;l<=top;l++)
printf("%c",stack[l]);
for(l=0;l<=22-top+x;l++)
printf(" ");
for(l=x;l<strlen(inter_symbol);l++)
printf("%c",inter_symbol[l]);
printf("\n");
}
else
break;
}
else if(stack[top]=='#'){
if(stack[top]==inter_symbol[x])
flag=0;//彻底结束
else
break;
}
else{
int col=get_ter(stack[top]);
int row=get_non(inter_symbol[x]);
if(inter_symbol[x]=='#')
row=strlen(non_ter);
if(M[col][row]>=0){//非终结符
if(form[M[col][row]].formula[3]=='$'){
top--;
}
else
{
for(i=strlen(form[M[col][row]].formula)-1;i>=3;i--){
stack[top++]=form[M[col][row]].formula[i];
}
top--;
}
if(step<10)
printf(" %d ",step++);
else
printf(" %d ",step++);
for(l=0;l<=top;l++)
printf("%c",stack[l]);
for(l=0;l<=22-top+x;l++)
printf(" ");
for(l=x;l<strlen(inter_symbol);l++)
printf("%c",inter_symbol[l]);
for(l=0;l<=(11-strlen(inter_symbol));l++)
printf(" ");
printf("%s",form[M[col][row]].formula);
printf("\n");
}
else break;
}
}
if(flag){
printf("输入串无法匹配成功!\n");
}
else{
printf("输入串匹配成功!\n");
}
}
table.h的代码:

void getTable(){//ter_symbol[200];//非终结符号
// non_ter[200];//终结符号
int i,j,k,col,row,flag=0;
for(i=0;i<strlen(ter_symbol);i++){
for(j=0;j<strlen(non_ter)+1;j++)
M[i][j]=-1;
}
for(i=0;i<sum;i++){//printf("lalallallalallalallalalla\n");
flag=0;
if((row=get_non(form[i].formula[3]))>=0){//printf("%d %d 1\n",row,i);
col=get_ter(form[i].formula[0]);
M[col][row]=i;
}//右部是终结符
else if((row=get_non(form[i].formula[3]))==-1){//非终结符和空
//if()
col=get_ter(form[i].formula[0]);//左部是行坐标
k=get_ter(form[i].formula[3]);//右部非终结符的下标
if(k>=0){
for(j=1;j<strlen(first_set[k]);j++){
if(first_set[k][j]=='$'){//非终结符的first集有空
flag=1;
continue;
}
row=get_non(first_set[k][j]);
M[col][row]=i;
}
}
if(form[i].formula[3]=='$')
{ flag=1;//printf("%c##########################\n",form[i].formula[3]);
}
if(flag){//右部为空,或者右部的first集有空
for(j=1;j<strlen(follow_set[col]);j++){
if(follow_set[col][j]=='#')
row=strlen(non_ter);
else row=get_non(follow_set[col][j]);
M[col][row]=i;
}
}
}
}
}

鄙人不才,欢迎找错。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: