这些资料是我学习的时候在网络上寻找到的,发布出来希望对大家有帮助,一起努力前进,嘿嘿......Microsoft C#规范 2.0 版 GFC用户提交

feedsky 抓虾 pageflakes google reader my yahoo bloglines 鲜果 有道 http://wap.feedsky.com/bliplink

LL(1)源码

LL(1)预测分析表

一.测试文法:(放在文件chanshengshi.txt中)

E->TA

A->+TA

A->~

T->FB

B->*FB

B->~

F->(E)

F->i





二.输出(在analysis_table.txt中)

产生式:

0:E->TA

1:A->+TA

2:A->~

3:T->FB

4:B->*FB

5:B->~

6:F->(E)

7:F->i

--------------------------------------------

first follow

E (i #)

A ~+ #)

T (i +#)

B ~* +#)

F (i *+#)

--------------------------------------------

预测分析表如下:

+ * ( ) i #

E ERROR ERROR 0 ERROR 0 ERROR

A 1 ERROR ERROR 2 ERROR 2

T ERROR ERROR 3 ERROR 3 ERROR

B 5 4 ERROR 5 ERROR 5

F ERROR ERROR 6 ERROR 7 ERROR





三.源码

/*

LL(1)预测分析表的构造,空字用符号~表示

This procedure is written by fanxiangchao.

*/

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<ctype.h>

#include<malloc.h>

#define FALSE 0

#define TRUE 1

#define MAX 100

#define NULL 0

#define ERROR -1

/***********************定义结构体*********************************/

//1.定义非终结符的结构体

struct no_terminal_sign

{

char no_ter; //非终结符

char first[MAX]; //非终结符的first集合

char follow[MAX]; //非终结符的follow集合

};

//2.定义候选式的结构体

struct candidate_formular

{

char candidate[MAX]; //候选式串

char first[MAX]; //候选式的first集合

};

//3.定义产生式的结构体

typedef struct produce

{

char left; //产生式左部

char right[MAX]; //产生式右部

}chanshengshi;

//4.定义终结符的结构体

struct terminal_sign

{

char ter; //终结符

char first[MAX]; //终结符的first集合

};

/******************************************************************/

//函数定义

int is_include(char * a,char b)//一个终结符属于某个集合

{

int i;

for(i=0;a[i]!='\0';i++)

if(b==a[i])

return TRUE;

return FALSE;

}

void add_ter(char * a,char sign)//向一个集合中添加一个终结符

{

int length;

if(!is_include(a,sign)){

length=strlen(a);

a[length]=sign;

a[length+1]='\0';

}

}

void add_ter_to_first(struct no_terminal_sign * a,char sign)//向一个终结符的first集合中添加一个终结符

{

int length;

if(!is_include(a->first,sign)){

length=strlen(a->first);

a->first[length]=sign;

a->first[length+1]='\0';

}

}

void add_ter_to_candidate_first(struct candidate_formular * a,char sign)//向一个候选式的first集合中添加一个终结符

{

int length;

if(!is_include(a->first,sign)){

length=strlen(a->first);

a->first[length]=sign;

a->first[length+1]='\0';

}

}

void add_ter_to_follow(struct no_terminal_sign * a,char sign)//向一个终结符的follow集合中添加一个终结符

{

int length;

if(!is_include(a->follow,sign)){

length=strlen(a->follow);

a->follow[length]=sign;

a->follow[length+1]='\0';

}

}

int is_terminal(char sign,struct terminal_sign *a)//判断一个符号是终结符还是非终结符

{

struct terminal_sign * p;

if(sign=='~') return -1;

for(p=a;p->ter!=NULL;p++)

if(p->ter==sign)

return TRUE;

return FALSE;

}

int is_include_null(struct no_terminal_sign *a)//判断一个非终结符的first集合中包含空字

{

int i;

for(i=0;a->first[i]!='\0';i++)

if(a->first[i]=='~')

return TRUE;

return FALSE;

}

void subtract_null(char *a)//将一个集合减去空字

{

int i,mark;

for(i=0;a[i]!='\0';i++)

if(a[i]=='~')

break;

mark=i;

for(i=mark;i<(signed)strlen(a);i++)

a[i]=a[i+1];

}

void merge_to_first(struct no_terminal_sign * a,char *b)//将集合b添加到非终结符的first集合a

{

int i,n;

n=strlen(a->first);

for(i=0;b[i]!='\0';i++)

if(!is_include(a->first,b[i]))

a->first[n++]=b[i];

a->first[n]='\0';

}

void merge_to_candidate_first(struct candidate_formular * a,char *b)//将集合b添加到候选式的first集合a

{

int i,n;

n=strlen(a->first);

for(i=0;b[i]!='\0';i++)

if(!is_include(a->first,b[i]))

a->first[n++]=b[i];

a->first[n]='\0';

}

void merge_to_follow(struct no_terminal_sign * a,char *b)//将集合b添加到非终结符的first集合a

{

int i,n;

n=strlen(a->follow);

for(i=0;b[i]!='\0';i++)

if(!is_include(a->follow,b[i]))

a->follow[n++]=b[i];

a->follow[n]='\0';

}

struct no_terminal_sign * search_by_sign(char sign,struct no_terminal_sign *a)//根据一个非终结符找到对应的结构体

{

struct no_terminal_sign *p;

for(p=a;p->no_ter!=NULL;p++)

if(p->no_ter==sign)

return p;

return NULL;

}

int sum_first(struct no_terminal_sign * a)//所有first集合元素的和

{

int sum=0;

struct no_terminal_sign * p;

for(p=a;p->no_ter!=NULL;p++)

sum+=strlen(p->first);

return sum;

}

int sum_follow(struct no_terminal_sign * a)//所有follow集合元素的和

{

int sum=0;

struct no_terminal_sign * p;

for(p=a;p->no_ter!=NULL;p++)

sum+=strlen(p->follow);

return sum;

}

struct candidate_formular * search_by_string(char * a,struct candidate_formular *b)//根据产生式右部找到候选式的结构体

{

struct candidate_formular *p;

for(p=b;p->candidate!=NULL;p++)

if(strcmp(p->candidate,a)==0)

return p;

return NULL;

}

int total_ter(struct terminal_sign *a)//终结符的个数

{

struct terminal_sign *p;

int n=0;

for(p=a;p->ter!=NULL;p++)

n++;

return n;

}

int total_no_ter(struct no_terminal_sign *a)//非终结符的个数

{

struct no_terminal_sign *p;

int n=0;

for(p=a;p->no_ter!=NULL;p++)

n++;

return n;

}

//1.非终结符first集合的构造

void no_ter_first_create(chanshengshi *formular,struct no_terminal_sign * no_terminal,struct terminal_sign * terminal)

{

chanshengshi * p;

int n,i;

struct no_terminal_sign *q;

char temp[MAX]=""; //临时数组变量

for(p=formular;p->left!=NULL;p++)

{

n=0;

q=search_by_sign(p->left,no_terminal);//根据产生式左部找到对应的非终结符结构体

if(strcmp(p->right,"~")==0)//如果产生式右部为空字

continue;

struct no_terminal_sign *r;

for(i=0;p->right[i]!='\0';i++)

{

if(!is_terminal(p->right[i],terminal))

{

r=search_by_sign(p->right[i],no_terminal);//根据非终结符找到对应的非终结符结构体

if(is_include_null(r))

n++;

else break;

}

else break;

}

for(i=0;i<n;i++)

{

r=search_by_sign(p->right[i],no_terminal);//根据非终结符找到对应的非终结符结构体

strcpy(temp,""); //临时数组变量赋空串

strcpy(temp,r->first);

subtract_null(temp); //减空字

merge_to_first(q,temp);//将所有非空元素加入左部非终结符的first

}

if(n>=(signed)strlen(p->right))

{

add_ter_to_first(q,'~');

}

else

{

if(is_terminal(p->right[n],terminal))

add_ter_to_first(q,p->right[n]);

else{

r=search_by_sign(p->right[n],no_terminal);//根据非终结符找到对应的非终结符结构体

merge_to_first(q,r->first);//将所有元素加入左部非终结符的first(已确定不含空字)

}

}

}

}

//2.候选式first集合的构造

void candidate_first_create(chanshengshi *formular,struct no_terminal_sign * no_terminal,struct terminal_sign * terminal,struct candidate_formular *candi)

{

int n=0,i;

char temp[MAX]; //临时数组变量

chanshengshi *p;

struct candidate_formular *q;

struct no_terminal_sign *r;

for(p=formular;p->left!=NULL;p++){

q=search_by_string(p->right,candi);

for(i=0;i<p->right[i]!='\0';i++){

if(!is_terminal(p->right[i],terminal)){

r=search_by_sign(p->right[i],no_terminal);

if(is_include_null(r))

n++;

else

break;

}else

break;

}

for(i=0;i<n;i++){

r=search_by_sign(p->right[i],no_terminal);//根据非终结符找到对应的非终结符结构体

strcpy(temp,""); //临时数组变量

strcpy(temp,r->first);

subtract_null(temp); //减空字

merge_to_candidate_first(q,temp);//将所有非空元素加入到候选式的first

}

if(n>=(signed)strlen(p->right)){

add_ter_to_candidate_first(q,'~');

}else{

if(is_terminal(p->right[n],terminal))

add_ter_to_candidate_first(q,p->right[n]);

else{

r=search_by_sign(p->right[i],no_terminal);//根据非终结符找到对应的非终结符结构体

merge_to_candidate_first(q,r->first);//将所有非空元素加入左部非终结符的first

}

}

}

}

//3.非终结符follow集合的构造

void no_ter_follow_create(chanshengshi *formular,struct no_terminal_sign * no_terminal,struct terminal_sign * terminal,struct candidate_formular *candi)

{

struct no_terminal_sign *q,*r,*s;

chanshengshi *p;

int i;

char temp[MAX];

for(p=formular;p->left!=NULL;p++)

{

q=search_by_sign(p->left,no_terminal);//根据产生式左部找到对应的非终结符结构体

for(i=0;i<(signed)strlen(p->right)-1;i++)

{

if(!is_terminal(p->right[i],terminal))

{

//根据非终结符找到对应的非终结符结构体r,即当前需要求follow集合的非终结符

r=search_by_sign(p->right[i],no_terminal);

int n=i+1;//记录当前非终结符的标号

for(int j=i+1;j<(signed)strlen(p->right);j++){

if(!is_terminal(p->right[j],terminal)){

s=search_by_sign(p->right[j],no_terminal);

if(is_include_null(s))

n++;

else

break;

}else

break;

}

for(j=i+1;j<n;j++){

s=search_by_sign(p->right[j],no_terminal);//根据非终结符找到对应的非终结符结构体

strcpy(temp,""); //临时数组变量

strcpy(temp,s->first);

subtract_null(temp); //减空字

merge_to_follow(r,temp);//将所有非空元素加入当前非终结符的follow集合

}


//如果当前非终结符后面的符号都含空字,则将左部非终结符的follow加入到该终结符的follow集合

if(n>=(signed)strlen(p->right))

{

merge_to_follow(r,q->follow);

}else

{

if(is_terminal(p->right[n],terminal))

add_ter_to_follow(r,p->right[n]);

else{

s=search_by_sign(p->right[n],no_terminal);//根据非终结符找到对应的非终结符结构体

merge_to_follow(r,s->first);//将所有元素加入当前非终结符的follow

}

}

}

}

//如果右部的最后一个字符是非终结符,则将左部的follow加到该非终结符的follow

if(!is_terminal(p->right[i],terminal)){

r=search_by_sign(p->right[i],no_terminal);

merge_to_follow(r,q->follow);

}

}

}

/******************************************************************/

//主函数

void main()

{

//构造一个预测分析表,一个二维数组,行代表非终结符序号,列代表非结符序号

int analysis[MAX][MAX];

//定义非终结符集

struct no_terminal_sign no_terminal[MAX];

//定义终结符集

struct terminal_sign terminal[MAX];

//定义开始符号

char start_sign;

//定义产生式集合

chanshengshi formular[MAX];

struct candidate_formular candi[MAX];

chanshengshi *p;

int t1,t2,i,j;

/**********************************************************************/

//读取存放产生式的文件

FILE *in;

if((in=fopen("chanshengshi.txt","r"))==NULL){

printf("cannot open file!\n");

return;

}

char sign;

int no_ter_num=0,ter_num=0,chanshengshi_num=0,candidate_num=0;

char temp[MAX];

sign=fgetc(in);

start_sign=sign;//读取的第一个符号为开始符号

rewind(in); //文件指针重新回到文件头部

//产生式添加并赋初值

while (fscanf(in,"%s",temp)!=-1)

{

formular[chanshengshi_num].left=temp[0];

strcpy(formular[chanshengshi_num].right,temp+3);

chanshengshi_num++;

}

formular[chanshengshi_num].left=NULL;

strcpy(formular[chanshengshi_num].right,"");

//非终结符和终结符添加并赋初值

for(p=formular;p->left!=NULL;p++)

{

//1.将非终结符加入非终结符集并赋初值

for(i=0;i<no_ter_num;i++)

if(p->left==no_terminal[i].no_ter)

break;

if(i>=no_ter_num)

{

no_terminal[no_ter_num].no_ter=p->left;

strcpy(no_terminal[no_ter_num].first,"");

strcpy(no_terminal[no_ter_num].follow,"");

no_ter_num++;

}

//2.将终结符加入非终结符集

for(i=0;p->right[i]!='\0';i++)

if(!((p->right[i]<='Z' && p->right[i]>='A') || (p->right[i]=='~')))

{

for(j=0;j<ter_num;j++)

if(p->right[i]==terminal[j].ter)

break;

if(j>=ter_num){

terminal[ter_num].ter=p->right[i];

strcpy(terminal[ter_num].first,"");

//add_ter(terminal[ter_num].first,temp[i]);

ter_num++;

}

}

//3.将候选式加入候选式集并赋初值

for(i=0;i<candidate_num;i++)

if(strcmp(p->right,candi[i].candidate)==0)

break;

if(i>=candidate_num)

{

strcpy(candi[candidate_num].candidate,p->right);

strcpy(candi[candidate_num].first,"");

candidate_num++;

}

}

//各集合终结标志添加

no_terminal[no_ter_num].no_ter=NULL;

strcpy(no_terminal[no_ter_num].first,"");

strcpy(no_terminal[no_ter_num].follow,"");


formular[chanshengshi_num].left=NULL;

strcpy(formular[chanshengshi_num].right,"");


strcpy(candi[candidate_num].candidate,"");

strcpy(candi[candidate_num].first,"");


terminal[ter_num].ter='#';

strcpy(terminal[ter_num].first,"");

ter_num++;

terminal[ter_num].ter=NULL;

strcpy(terminal[ter_num].first,"");


fclose(in);

/**********************************************************************/

//first集合的构造

//12是处理空字问题,即先把空字写入每个所属first集合

//1

for(p=formular;p->left!=NULL;p++)

{

struct no_terminal_sign *q;

q=search_by_sign(p->left,no_terminal);//根据产生式左部找到对应的非终结符结构体

if(strcmp(p->right,"~")==0)//如果产生式右部为空字

add_ter_to_first(q,'~');//则将空字加入到左部非终结符的first

}

//2

for(p=formular;p->left!=NULL;p++)

{

struct no_terminal_sign *q,*r;

q=search_by_sign(p->left,no_terminal);//根据产生式左部找到对应的非终结符结构体

if(!is_terminal(p->right[0],terminal))

{

r=search_by_sign(p->right[0],no_terminal);

if(is_include_null(r))

add_ter_to_first(q,'~');

}

}

//3构造first集合,直至不在增加为止

while(1)

{

t1=sum_first(no_terminal);

no_ter_first_create(formular,no_terminal,terminal);

t2=sum_first(no_terminal);

if(t1>=t2) break;//first集合不再增大

}

//打印first集合

for(i=0;no_terminal[i].no_ter!=NULL;i++)

printf("%s\n",no_terminal[i].first);

printf("\n");

/********************************************************************/

//产生式候选式的first集合的构造

candidate_first_create(formular, no_terminal,terminal,candi);

//打印候选式的first集合

for(i=0;strcmp(candi[i].candidate,"")!=0;i++)

printf("%s\n",candi[i].first);

printf("\n");

/***********************************************************************/

//非终结符follow集合的构造

struct no_terminal_sign *a;

a=search_by_sign(start_sign,no_terminal);//开始符号的结构体

add_ter_to_follow(a,'#'); //#添加到开始符号的follow集合中

while(1){

t1=sum_follow(no_terminal);

no_ter_follow_create(formular,no_terminal,terminal,candi);

t2=sum_follow(no_terminal);

if(t1>=t2)

break;

}

//打印终结符的follow集合

for(i=0;no_terminal[i].no_ter!=NULL;i++)

printf("%s\n",no_terminal[i].follow);

printf("\n");

/***************************************************************************/

//构造分析表

t1=total_ter(terminal); //终结符个数

t2=total_no_ter(no_terminal); //非终结符个数

printf("%d,%d\n",t1,t2);

//初始化预测分析表

for(i=0;i<t2;i++)

for(j=0;j<t1;j++)

analysis[i][j]=ERROR;

//构造

for(i=0;i<t2;i++){

struct no_terminal_sign *q;

struct candidate_formular *r;

int mark;

for(mark=0;formular[mark].left!=NULL;mark++){ //对每个产生式

q=search_by_sign(formular[mark].left,no_terminal); //由左部找到非终结符结构体

r=search_by_string(formular[mark].right,candi); //由右部找到候选式结构体

if(formular[mark].left==no_terminal[i].no_ter){

for(j=0;j<t1;j++){

if(is_include(r->first,terminal[j].ter)){

analysis[i][j]=mark;

}

}

if(is_include_null(q)){

for(j=0;j<t1;j++){

if(is_include(q->follow,terminal[j].ter)){

analysis[i][j]=mark;

}

}

}

}

}

}

//打印预测分析表

for(i=0;i<t2;i++)

{

for(j=0;j<t1;j++)

printf("%d\t",analysis[i][j]);

printf("\n");

}

/************************************************************************/

//将预测分析表保存到文件中

FILE *fp;

if((fp=fopen("analysis_table.txt","w"))==NULL){

printf("cannot open the file of analysis_table.txt !\n");

return;

}

fprintf(fp,"%s\n","产生式:");

for(i=0,p=formular;p->left!=NULL;p++,i++)

fprintf(fp,"%d%s%c%s%s\n",i,":",p->left,"->",p->right);

fprintf(fp,"%s\n","--------------------------------------------");

fprintf(fp,"%-10s\t%-10s\t%-10s\n","","first","follow");

for(i=0;no_terminal[i].no_ter!=NULL;i++){

fprintf(fp,"%-10c\t%-10s\t%-10s\n",no_terminal[i].no_ter,no_terminal[i].first,no_terminal[i].follow);

}

fprintf(fp,"%s\n","--------------------------------------------");

fprintf(fp,"%s\n","预测分析表如下:");

fprintf(fp,"%-10s","");

for(i=0;terminal[i].ter!=NULL;i++)

fprintf(fp,"%-10c",terminal[i].ter);

fprintf(fp,"\n");

for(i=0;i<t2;i++){

fprintf(fp,"%-10c",no_terminal[i]);

for(j=0;j<t1;j++){

if(analysis[i][j]==ERROR)

fprintf(fp,"%-10s","ERROR");

else

fprintf(fp,"%-10d",analysis[i][j]);

}

fprintf(fp,"\n");

}

fclose(fp);

}


友情链接

郑州大学软件学院 SpringWidgets-Blogger 徵信社 翻译公司 链接帮手网 行驶证字体 酷站目录 Friend Connectified