目录
0.作者:zzj
1.实验要求:
2.实现效果:
3.源代码:
4.代码下载:
实验要求等内容看我前面那篇,这篇是我室友用C语言写的,发出来记录一下。
LR0语法分析实现(完整版)[编译原理实验]_younger77的博客-CSDN博客
#include
#include
#include
#include
#define num 20
typedef struct link_Procn
{
char left; //产生式左部
char right[6]; //产生式右部
struct link_Procn *next;//指向下一个带.的产生式
}Procn;
typedef struct link_Projt
{
int state;//状态名
Procn *headn;//存放一个状态项目集闭包
struct link_Projt *next;//指向下一个项目集规范族
}Projt;
typedef struct link_transfm
{
Projt *left,*right;//表示left状态通过字符t转换到状态right
char t;
struct link_transfm *next;
}transfm;
typedef struct action
{
char tran;//转换符号
Projt *sta;//转换目标状态
struct action *next;
}act;
Procn p[num];
int p_len=0;
transfm *tfm = NULL;
void create_procn();//手动输入文法函数
void create_procn1();//txt文件输入文法函数
Projt *getproject();//计算项目集闭包
Procn *getprocn(Procn *);
void exchange(char *,int);
Projt *ishas(Projt *,Projt *);//查找目标项目是否存在
void display(Projt *);
void Action(act *,act *,int,Projt *);
void dis_stack(char *,int );
void output(int a[],int );
void analy_pro(act *,act *);
void dis_stack1(char *,int );
int main()
{
Projt *head;
create_procn1();
head = getproject();
Projt *h = head;
while(h->next)
h = h->next;
int a = h->state;
act atn[a+1];
act gto[a+1];
Action(atn,gto,a+1,head);
analy_pro(atn,gto);
//create_procn();
display(head);
return 0;
}
void dis_stack(char *a,int i)
{
int b = i;
while(a[i] != '\0')
{
printf("%c",a[i]);
i++;
}
if((i-b) < 8)
printf("\t\t");
else
printf("\t");
}
void dis_stack1(char *a,int b)
{
int i,x = 0;
for(i=0;i=10 && a[i] < 100)
x += 2;
else if(a[i] >= 100 && a[i] <1000)
x += 3;
}
if(x < 8)
printf("\t\t");
else
printf("\t");
}
void analy_pro(act *atn,act *gto)
{
//符号栈
char str[num] = {'\0'};
str[0] = '$';
int str_top=1;
//状态栈
int state[num] = {'\0'};
state[0] = 0;
int sta_top=1;
//输入串
char strx[num]={'\0'};
printf("请输入测试串($结束):");
gets(strx);
int i=0;
printf("状态栈\t\t符号栈\t\t输入串\t\tACTION\t\tGOTO\n");
while(strx[i])
{
output(state,sta_top);
dis_stack1(str,str_top);
dis_stack(strx,i);
//printf("\t\t");
act *ha = atn[state[sta_top-1]].next;
if(atn[state[sta_top-1]].tran == 'r')//开始归约
{
Projt *ht = atn[state[sta_top-1]].sta;
Procn *hn = ht->headn;
int len = strlen(hn->right);
//puts(hn->right);
//printf("[%d]",len);
str_top = str_top-len+1;
str[str_top] = '\0';
sta_top = sta_top-len+1;
str[str_top++] = hn->left;
//goto
int flag =0;
act *ho = gto[state[sta_top-1]].next;
while(ho)
{
if(ho->tran == str[str_top-1])
{
ht = ho->sta;
flag =1;
break;
}
ho = ho->next;
}
if(flag)
{
state[sta_top++] = ht->state;
printf("\t\t%d\n",ht->state);
}
else
{
printf("匹配失败\n");
break;
}
}
else if(atn[state[sta_top-1]].tran == 'Y' && strx[i] == '$')
{
printf("匹配成功!\n");
break;
}
else if(strx[i] != '$')
{
int flag = 0;
while(ha)
{
if(ha->tran == strx[i])
{
flag = 1;
break;
}
ha = ha->next;
}
if(flag)
{
Projt *ht = ha->sta;
state[sta_top++] = ht->state;
str[str_top++] = strx[i];
printf("S%d\n",ht->state);
i++;
}
else
{
printf("匹配失败!\n");
break;
}
}
else
{
printf("匹配失败!\n");
break;
}
}
}
void Action(act *atn,act *gto,int length,Projt *head)
{
int i;
transfm *fm = tfm;
act *ax;
for(i=0;ileft;
if(left->state == i)
{
Projt *right = fm->right;
ax = (act*)malloc(sizeof(act));
ax->tran = fm->t;
ax->sta = right;
ax->next = NULL;
if(fm->t >= 'A' && fm->t <= 'Z')
{
if(gto[i].next == NULL)
gto[i].next = ax;
else
{
ax->next = gto[i].next;
gto[i].next = ax;
}
}
else
{
if(atn[i].next == NULL)
atn[i].next = ax;
else
{
ax->next = atn[i].next;
atn[i].next = ax;
}
}
}
else if(i < left->state)
{
int j;
for(j=i+1;jstate;j++)
{
if(j == 1)
{
atn[j].tran = 'Y';
}
else
{
atn[j].tran = 'r';
Projt *hj = head;
while(hj)
{
if(hj->state == j)
break;
hj = hj->next;
}
//printf("%d\n",hj->state);
atn[j].sta = hj;
}
}
i = j-1;
break;
}
fm = fm->next;
}
if(fm == NULL && istate == j)
break;
hj = hj->next;
}
//printf("%d\n",hj->state);
atn[j].sta = hj;
}
i = j-1;
}
}
}
}
Projt *ishas(Projt *head,Projt *curren)
{
Projt *h = head;
while(h)
{
Procn *p = h->headn;
Procn *p1 = curren->headn;
int f = 1;
while(p != NULL || p1 != NULL)
{
//int f = 1;
if(p->left != p1->left || strcmp(p->right,p1->right)!=0)
{
f = 0;
break;
}
p = p->next;
p1 = p1->next;
}
if(f && (p == NULL && p1 == NULL))
return h;
h = h->next;
}
return NULL;
}
void exchange(char *a,int i)
{
char temp;
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
Procn *getprocn(Procn *a)
{
int i=0;
Procn *head,*tall,*x;
head=tall=NULL;
while(a->right[i] != '.')
{
i++;
}
if(a->right[i+1] >= 'A' && a->right[i+1] <= 'Z')
{
int j;
for(j = 0;j < p_len;j++)
{
if(p[j].left == a->right[i+1])
{
x = (Procn*)malloc(sizeof(Procn));
x->left = a->right[i+1];
x->right[0] = '.';
x->right[1] = '\0';
x->next = NULL;
strcat(x->right,p[j].right);
if(head == NULL)
{
head=tall=x;
}
else
{
tall->next = x;
tall = x;
}
}
}
Procn *h=head;
while(h!=NULL)
{
if(h->left == h->right[1])
{
h = h->next;
continue;
}
Procn *end;
end = getprocn(h);
if(end != NULL)
{
tall->next = end;
while(end->next)
end = end->next;
tall = end;
}
h=h->next;
}
return head;
}
else
return NULL;
}
Projt *getproject()
{
int I=0;
transfm *f,*tallf;//为创建转换函数做准备
Projt *headt,*tallt,*x;
Procn *p1,*talln;//
headt=tallt=NULL;
p1 = (Procn*)malloc(sizeof(Procn));
p1->left = p[0].left;//创建第一个项目
p1->right[0] = '.';
p1->right[1] = '\0';
strcat(p1->right,p[0].right);
x = (Projt *)malloc(sizeof(Projt));//创建第一个项目集规范族
x->headn = p1;
x->state = I++;
x->next = NULL;
headt=tallt=x;
talln = p1;
talln->next = getprocn(p1);
Projt *t = headt;
while(t != NULL)
{
Procn *h = t->headn;
int a[10] = {0};
int i=0;
while(h != NULL)
{
int k=0;
while(h->right[k] != '.')//找到每个项目·的位置
k++;
if(a[i] || h->right[k+1] == '\0')//判断当前项目是否已经规约或者该项目为归约项目
{
h = h->next;
i++;
continue;
}
x = (Projt*)malloc(sizeof(Projt));//创建一个项目集族
x->state = I++;
x->headn = NULL;
x->next = NULL;
int j=i;
Procn *h1 = h;
while(h1 != NULL)
{
if(a[j])//判断当前项目是否已经规约
{
h1 = h1->next;
j++;
continue;
}
int m=0;
while(h1->right[m] != '.')//找到每个项目·的位置
m++;
if(h->right[k+1] == h1->right[m+1])
{
a[j] = 1;
p1 = (Procn*)malloc(sizeof(Procn));
p1->left = h1->left;
p1->right[0] = '\0';
p1->next = NULL;
strcat(p1->right,h1->right);
exchange(p1->right,m);
if(x->headn == NULL)
{
x->headn =talln = p1;
talln->next = getprocn(p1);
while(talln->next)
talln = talln->next;
}
else
{
talln->next = p1;
talln = p1;
talln->next = getprocn(p1);
while(talln->next)
talln = talln->next;
}
}
j++;
h1 = h1->next;
}
Projt *curren = ishas(headt,x);
if(curren == NULL)
{
tallt->next = x;
tallt = x;
f = (transfm*)malloc(sizeof(transfm));
f->left = t;
f->right = x;
f->t = h->right[k+1];
f->next = NULL;
}
else
{
f = (transfm*)malloc(sizeof(transfm));
f->left = t;
f->right = curren;
f->t = h->right[k+1];
f->next = NULL;
free(x);
I--;
}
if(tfm == NULL)
tfm = tallf = f;
else
{
tallf->next = f;//尾插法
tallf = f;
}
i++;
h = h->next;
}
t = t->next;
}
return headt;
}
void create_procn()
{
printf("输入文法:\n\n");
printf("左部\t右部\n\n");
while(1)
{
p[p_len].left=_getch();
if(p[p_len].left == '#')
{
printf("#\n");
break;
}
else if(p[p_len].left >= 'A' && p[p_len].left <= 'Z')
{
printf("%3c -> ",p[p_len].left);
scanf("%s",&p[p_len].right);
p_len++;
}
else
printf("输入错误,重新输入\n");
}
}
void create_procn1()
{
char ch;
int i =0,na=0;
FILE *fp;
fp = fopen("A.txt","r");
while(!feof(fp))
{
ch = fgetc(fp);
if(!i)
{
if(ch == ' ')
{
i = 1;
}
else
p[p_len].left = ch;
}
else if(i)
{
if(ch == '\n')
{
na = 0;
i = 0;
p_len++;
}
else
p[p_len].right[na++] = ch;
}
}
fclose(fp);
}
void display(Projt *head)
{
int i=0;
printf("输出文法:\n\n");
printf("左部\t右部\n\n");
while(i < p_len)
{
printf("%3c -> %s\n",p[i].left,p[i].right);
i++;
}
printf("\n\n--------输出项目集族--------\n\n");
Projt *ht = head;
while(ht)
{
Procn *hn = ht->headn;
printf("\t-----------\n");
printf("状态%d",ht->state);
while(hn)
{
printf("\t%c -> %s\n",hn->left,hn->right);
hn = hn->next;
}
printf("\t-----------\n");
ht = ht->next;
}
printf("\n\n-------输出转换函数--------\n\n");
transfm *fm = tfm;
while(fm)
{
Projt *left = fm->left;
Projt *right = fm->right;
printf("\tf(%d,%c)=%d\n",left->state,fm->t,right->state);
fm = fm->next;
}
}
[编译原理实验]LR0语法分析C语言版.zip-其它文档类资源-CSDN下载