编译原理实验源代码

时间:2021-09-01 03:53:35

1、词法分析

/*cifa fenxi chengxu*/

#include <stdio.h>

#include <ctype.h>

#include <alloc.h>

#include <stdlib.h>

#include <string.h>

#define NULL 0

 

FILE *fp;

char cbuffer;

char *key[8]={"if","else","for","while","do","return","break","continue"};

char *border[6]={",",";","{","}","(",")"};

char *arithmetic[4]={"+","-","*","/"};

char *relation[6]={"<","<=","=",">",">=","<>"};

char *consts[20];

char *label[20];

int constnum=0,labelnum=0;

 

int search(char searchchar[],int wordtype)

{

     int i=0;

     switch (wordtype) {

       case 1:for (i=0;i<=7;i++)

                {

                  if (strcmp(key[i],searchchar)==0)

                    return(i+1);

                }

       case 2:{for (i=0;i<=5;i++)

                {

                  if (strcmp(border[i],searchchar)==0)

                     return(i+1);

                }            return(0);

              }

 

       case 3:{for (i=0;i<=3;i++)

                {

                  if (strcmp(arithmetic[i],searchchar)==0)

                     {

                      return(i+1);

                     }

                }

              return(0);

              }

 

       case 4:{for (i=0;i<=5;i++)

                {

                  if (strcmp(relation[i],searchchar)==0)

                     {

                      return(i+1);

                     }

                }

               return(0);

              }

 

       case 5:{for (i=0;i<=constnum;i++)

                {

                  if (strcmp(consts[i],searchchar)==0)

                      {

                       return(i+1);

                      }

                }

              consts[i-1]=(char *)malloc(sizeof(searchchar));

              strcpy(consts[i-1],searchchar);

              constnum++;

              return(i);

              }

 

       case 6:{for (i=0;i<=labelnum;i++)

                {

                    if (strcmp(label[i],searchchar)==0)

                      {

                       return(i+1);

                      }

                }

              label[i-1]=(char *)malloc(sizeof(searchchar));

              strcpy(label[i-1],searchchar);

              labelnum++;

              return(i);

              }

 

      }

 

 

}

 

 

char alphaprocess(char buffer)

{

      int atype;

      int i=-1;

      char alphatp[20];

      while ((isalpha(buffer))||(isdigit(buffer)))

            {

            alphatp[++i]=buffer;

            buffer=fgetc(fp);

            }

      alphatp[i+1]='"0';

      if (atype=search(alphatp,1))

         printf("%s (1,%d)"n",alphatp,atype-1);

      else

         {

         atype=search(alphatp,6);

         printf("%s (6,%d)"n",alphatp,atype-1);

         }

      return(buffer);

}

 

char digitprocess(char buffer)

{

      int i=-1;

      char digittp[20];

      int dtype;

      while ((isdigit(buffer)))

            {

            digittp[++i]=buffer;

            buffer=fgetc(fp);

            }

      digittp[i+1]='"0';

      dtype=search(digittp,5);

      printf("%s (5,%d)"n",digittp,dtype-1);

      return(buffer);

}

 

char otherprocess(char buffer)

{

 

      int i=-1;

      char othertp[20];

      int otype,otypetp;

      othertp[0]=buffer;

      othertp[1]='"0';

      if (otype=search(othertp,3))

         {

         printf("%s (3,%d)"n",othertp,otype-1);

         buffer=fgetc(fp);

         goto out;

         }

 

      if (otype=search(othertp,4))

              {

              buffer=fgetc(fp);

              othertp[1]=buffer;

              othertp[2]='"0';

              if (otypetp=search(othertp,4))

                {

                printf("%s (4,%d)"n",othertp,otypetp-1);

                goto out;

                }

              else

                othertp[1]='"0';

                printf("%s (4,%d)"n",othertp,otype-1);

                goto out;

              }

 

      if (buffer==':')

              {

              buffer=fgetc(fp);

              if (buffer=='=')

                printf(":= (2,2)"n");

                buffer=fgetc(fp);

                goto out;

              }

           else

              {

              if (otype=search(othertp,2))

                {

                printf("%s (2,%d)"n",othertp,otype-1);

                buffer=fgetc(fp);

                goto out;

                }

              }

 

         if ((buffer!='"n')&&(buffer!=' '))

                printf("%c error,not a word"n",buffer);

         buffer=fgetc(fp);

out:      return(buffer);

}

 

 

 

void main()

{

     int i;

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

         {

           label[i]=NULL;

           consts[i]=NULL;

         };

      if ((fp=fopen("example.c","r"))==NULL)

         printf("error");

      else

        {

        cbuffer = fgetc(fp);

        while (cbuffer!=EOF)

         {

         if (isalpha(cbuffer))

             cbuffer=alphaprocess(cbuffer);

         else if (isdigit(cbuffer))

             cbuffer=digitprocess(cbuffer);

         else cbuffer=otherprocess(cbuffer);

         }

         printf("over"n");

         getchar();

         }

}

 

2LL1

/*LL(1)分析法源程序,只能在VC++中运行 */

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<dos.h>

char A[20];/*分析栈*/

char B[20];/*剩余串*/

char v1[20]={'i','+','*','(',')','#'};/*终结符 */

char v2[20]={'E','G','T','S','F'};/*非终结符   */

 

int j=0,b=0,top=0,l;/*L为输入串长度 */

 

typedef struct type/*产生式类型定义      */

{

        char origin;/*大写字符 */

        char array[5];/*产生式右边字符 */

        int length;/*字符个数      */

}type;

 

type e,t,g,g1,s,s1,f,f1;/*结构体变量 */

type C[10][10];/*预测分析表      */

 

void print()/*输出分析栈 */

{

        int a;/*指针*/

        for(a=0;a<=top+1;a++)

               printf("%c",A[a]);

        printf(""t"t");

}/*print*/

 

void print1()/*输出剩余串*/

{

        int j;

        for(j=0;j<b;j++)/*输出对齐符*/

               printf(" ");

        for(j=b;j<=l;j++)

               printf("%c",B[j]);

        printf(""t"t"t");

}/*print1*/

 

void main()

{

        int m,n,k=0,flag=0,finish=0;

        char ch,x;

        type cha;/*用来接受C[m][n]*/

        /*把文法产生式赋值结构体*/

        e.origin='E';

        strcpy(e.array,"TG");

        e.length=2;

        t.origin='T';

        strcpy(t.array,"FS");

        t.length=2;

        g.origin='G';

        strcpy(g.array,"+TG");

        g.length=3;

        g1.origin='G';

        g1.array[0]='^';

        g1.length=1;

    s.origin='S';

        strcpy(s.array,"*FS");

        s.length=3;

        s1.origin='S';

        s1.array[0]='^';

        s1.length=1;

        f.origin='F';

        strcpy(f.array,"(E)");

        f.length=3;

        f1.origin='F';

        f1.array[0]='i';

        f1.length=1;

 

        for(m=0;m<=4;m++)/*初始化分析表*/

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

                       C[m][n].origin='N';/*全部赋为空*/

   /*填充分析表*/

   C[0][0]=e;C[0][3]=e;

   C[1][1]=g;C[1][4]=g1;C[1][5]=g1;

   C[2][0]=t;C[2][3]=t;

   C[3][1]=s1;C[3][2]=s;C[3][4]=C[3][5]=s1;

   C[4][0]=f1;C[4][3]=f;

   printf("提示:本程序只能对由'i','+','*','(',')'构成的以'#'结束的字符串进行分析,"n");

   printf("请输入要分析的字符串:");

   do/*读入分析串*/

   {

           scanf("%c",&ch);

           if ((ch!='i') &&(ch!='+') &&(ch!='*')&&(ch!='(')&&(ch!=')')&&(ch!='#'))

           {

                  printf("输入串中有非法字符"n");

                  exit(1);

           }

           B[j]=ch;

           j++;

   }while(ch!='#');

   l=j;/*分析串长度*/

   ch=B[0];/*当前分析字符*/

   A[top]='#'; A[++top]='E';/*'#','E'进栈*/

   printf("步骤"t"t分析栈 "t"t剩余字符 "t"t所用产生式 "n");

   do

   {

         x=A[top--];/*x为当前栈顶字符*/

      printf("%d",k++);

      printf(""t"t");

      for(j=0;j<=5;j++)/*判断是否为终结符*/

                if(x==v1[j])

                {

                        flag=1;

                        break;

                }

                if(flag==1)/*如果是终结符*/

                {

                        if(x=='#')

                        {

                                finish=1;/*结束标记*/

                                printf("acc!"n");/*接受 */

                                getchar();

                                getchar();

                                exit(1);

                        }/*if*/

                        if(x==ch)

                        {

                                print();

                                print1();

                                printf("%c匹配"n",ch);

                                ch=B[++b];/*下一个输入字符*/

                                flag=0;/*恢复标记*/

                        }/*if*/

                        else/*出错处理*/

                        {

                                print();

                                print1();

                                printf("%c出错"n",ch);/*输出出错终结符*/

                                exit(1);

                        }/*else*/

                }/*if*/

                else/*非终结符处理*/

                {

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

                               if(x==v2[j])

                               {

                                      m=j;/*行号*/

                                      break;

                               }

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

                               if(ch==v1[j])

                               {

                                      n=j;/*列号*/

                                      break;

                               }

                        cha=C[m][n];

                        if(cha.origin!='N')/*判断是否为空*/

                        {

                               print();

                               print1();

                               printf("%c->",cha.origin);/*输出产生式*/

                               for(j=0;j<cha.length;j++)

               printf("%c",cha.array[j]);

                               printf(""n");

              for(j=(cha.length-1);j =0;j--)/*产生式逆序入栈*/

                                                                            A[++top]=cha.array[j];

                               if(A[top]=='^')/*为空则不进栈*/

                                      top--;

                       }/*if*/

                       else/*出错处理*/

                       {

                               print();

                               print1();

                               printf("%c出错"n",x);/*输出出错非终结符*/

                               exit(1);

                       }/*else*/

               }/*else*/

   }while(finish==0);

}/*main*/

 

 

 

 

3LR(1)

#include<stdio.h>

#include<string.h>

 

char *action[10][3]={"S3#","S4#",NULL,            /*ACTION*/

                      NULL,NULL,"acc",

                                       "S6#","S7#",NULL,

                                       "S3#","S4#",NULL,

                                       "r3#","r3#",NULL,

                                       NULL,NULL,"r1#",

                                       "S6#","S7#",NULL,

                                       NULL,NULL,"r3#",

                                       "r2#","r2#",NULL,

                                       NULL,NULL,"r2#"};

int goto1[10][2]={1,2,                          /*QOTO*/

                  0,0,

                                0,5,

                                0,8,

                                0,0,

                                0,0,

                                0,9,

                                0,0,

                                0,0,

                                0,0};

char vt[3]={'a','b','#'};                       /*存放非终结符*/

char vn[2]={'S','B'};                           /*存放终结符*/

char *LR[4]={"E->S#","S->BB#","B->aB#","B->b#"};/*存放产生式*/

 

int a[10];

char b[10],c[10],c1;

int top1,top2,top3,top,m,n;

 

void main(){

        int g,h,i,j,k,l,p,y,z,count;

        char x,copy[10],copy1[10];

        top1=0;top2=0;top3=0;top=0;

        a[0]=0;y=a[0];b[0]='#';

        count=0;z=0;

        printf("请输入表达式"n");

        do{

               scanf("%c",&c1);

               c[top3]=c1;

               top3=top3+1;

        }while(c1!='#');

        printf("步骤"t状态栈"t"t符号栈"t"t输入串"t"tACTION"tGOTO"n");

        do{

               y=z;m=0;n=0;                      /*y,z指向状态栈栈顶*/

               g=top;j=0;k=0;

               x=c[top];

               count++;

               printf("%d"t",count);

               while(m<=top1){                    /*输出状态栈*/

                       printf("%d",a[m]);

            m=m+1;

               }

               printf(""t"t");

               while(n<=top2){                    /*输出符号栈*/

                       printf("%c",b[n]);

            n=n+1;

               }

               printf(""t"t");

               while(g<=top3){                    /*输出输入串*/

                       printf("%c",c[g]);

            g=g+1;

               }

               printf(""t"t");

               while(x!=vt[j]&&j<=2) j++;

               if(j==2&&x!=vt[j]){

                       printf("error"n");

                   return;

               }

        if(action[y][j]==NULL){

                       printf("error"n");

                       return;

               }

               else

                       strcpy(copy,action[y][j]);

               if(copy[0]=='S'){                      /*处理移进*/

                       z=copy[1]-'0';

            top1=top1+1;

                       top2=top2+1;

                       a[top1]=z;

                       b[top2]=x;

                       top=top+1;

                       i=0;

                       while(copy[i]!='#'){

                              printf("%c",copy[i]);

                               i++;

                       }

                       printf(""n");

               }

               if(copy[0]=='r'){                      /*处理归约*/

                       i=0;

                       while(copy[i]!='#'){

                               printf("%c",copy[i]);

                               i++;

                       }

                       h=copy[1]-'0';

 

                       strcpy(copy1,LR[h]);

                       while(copy1[0]!=vn[k]) k++;

                       l=strlen(LR[h])-4;

                       top1=top1-l+1;

                       top2=top2-l+1;

                       y=a[top1-1];

                       p=goto1[y][k];

                       a[top1]=p;

                       b[top2]=copy1[0];

                       z=p;

                       printf(""t");

                       printf("%d"n",p);

               }

        }while(action[y][j]!="acc");

        printf("acc"n");

}

 

4、逆波兰式

include<stdio.h>

#include<math.h>

#define max 100

char ex[max];       /*存储后缀表达式*/

void trans(){        /*将算术表达式转化为后缀表达式*/

        char str[max];   /*存储原算术表达式*/

        char stack[max];       /*作为栈使用*/

        char ch;

        int sum,i,j,t,top=0;

        printf("*****************************************"n");

        printf("*输入一个求值的表达式,以#结束。*"n");

        printf("******************************************"n");

        printf("算数表达式:");

        i=0;                      /*获取用户输入的表达式*/

        do{

               i++;

               scanf("%c",&str[i]);

        }while(str[i]!='#' && i!=max);

    sum=i;

        t=1;i=1;

        ch=str[i];i++;

        while(ch!='#'){

               switch(ch){

               case '(':                 /*判定为左括号*/

                       top++;stack[top]=ch;

                            break;

        case ')':                 /*判定为右括号*/

                       while(stack[top]!='('){

                ex[t]=stack[top];top--;t++;

                       }

                       top--;

                       break;

        case '+':                 /*判定为加减号*/

               case '-':      

                       while(top!=0&&stack[top]!='('){

                               ex[t]=stack[top];top--;t++;

                       }

                       top++;stack[top]=ch;

                       break;

               case '*':                  /*判定为乘除号*/

        case '/':

                       while(stack[top]=='*'||stack[top]=='/'){

                               ex[t]=stack[top];top--;t++;

                       }

                       top++;stack[top]=ch;

                       break;

               case ' ':break;

               default:while(ch>='0'&&ch<='9'){                 /*判定为数字*/

                       ex[t]=ch;t++;

                       ch=str[i];i++;

                               }

                       i--;

                       ex[t]='#';t++;

               }

               ch=str[i];i++;

        }

        while(top!=0){

               ex[t]=stack[top];t++;top--;

        }

        ex[t]='#';

        printf(""n"t原来表达式:");

        for(j=1;j<sum;j++)

               printf("%c",str[j]);

    printf(""n"t后缀表达式:",ex);

        for(j=1;j<t;j++)

               printf("%c",ex[j]);

}

void compvalue(){                                 /*计算后缀表达式的值*/

        float stack[max],d;                    /*作为栈使用*/

        char ch;

        int t=1,top=0;                  /*tex下标,topstack下标*/

        ch=ex[t];t++;

    while(ch!='#'){

               switch(ch){

                case '+':

                        stack[top-1]=stack[top-1]+stack[top];

                        top--;

                        break;

          case '-':

                        stack[top-1]=stack[top-1]-stack[top];

                        top--;

                        break;

          case '*':

                        stack[top-1]=stack[top-1]*stack[top];

                        top--;

                        break;

 

          case '/':

                  if(stack[top]!=0)

                           stack[top-1]=stack[top-1]/stack[top];

                  else{

                         printf(""n"t除零错误!"n");

                         exit(0);                   /*异常退出*/

                        }

                        top--;

                        break;

                default:

                        d=0;

                        while(ch>='0'&&ch<='9'){

                                d=10*d+ch-'0';               /*将数字字符转化为对应的数值*/   

                                ch=ex[t];t++;

                        }

                        top++;

                        stack[top]=d;

               }

               ch=ex[t];t++;

        }

        printf(""n"t计算结果:%g"n",stack[top]);

}

 

main(){

        trans();

        compvalue();

}