[编译原理实验] LR0语法分析

目录

0.作者:zzj  

1.实验要求:   

2.实现效果:

3.源代码:

4.代码下载:


0.作者:zzj  

   

1.实验要求:   

实验要求等内容看我前面那篇,这篇是我室友用C语言写的,发出来记录一下。

LR0语法分析实现(完整版)[编译原理实验]_younger77的博客-CSDN博客

2.实现效果:

[编译原理实验] LR0语法分析_第1张图片

[编译原理实验] LR0语法分析_第2张图片

 [编译原理实验] LR0语法分析_第3张图片

 [编译原理实验] LR0语法分析_第4张图片

 [编译原理实验] LR0语法分析_第5张图片

 

3.源代码:

#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;
    }
}

4.代码下载:

[编译原理实验]LR0语法分析C语言版.zip-其它文档类资源-CSDN下载

你可能感兴趣的:(c语言)