编译原理语义分析(文本输入)源程序

#include<stdio.h>
#include<string.h>
#include<conio.h> 
#include<malloc.h>
#include<STDLIB.H>
struct quad

     char result[12]; 
     char ag1[12]; 
     char op[12];
     char ag2[12]; 
}; 
struct quad quad[30]; 
int count=0;
char *expression(void);
char prog[200],token[9];//function长度为8,加上'\0',所以数组最小大小应该为9
char ch; 
int syn,p,m,n,sum=0;
int kk=0,k=0;
char *rwtab[6]={"function","if","then","while","do","endfunc"}; 
//数据单位:eg:123,ad,(,*,+,a1;
void scaner()

      m=0;
 ch=prog[p++];//ch为读入第一个数据(一个新的字符串中第一个数据,并不代表整个文本第一个数据)
      for(n=0;n<8;n++)//初始化token数组
         token[n]='\0';
      while(ch==' ')
         ch=prog[p++]; //跳过空格
      if((ch>='a' && ch<='z')||(ch>='A' && ch<='Z'))//如果读入的第一个数据为字符 (字符串先存放在token数组中)
 { 
          while((ch>='a' && ch<='z')||(ch>='A' && ch<='Z')||(ch>='0'&&ch<='9')) 
 { 
              token[m++]=ch;//暂时存放在token数组中 
              ch=prog[p++];
 }//字符串
          token[m++]='\0';
          p--;//使得prog[p]被ch读入的最后一个字符
          syn=10;//用来区分输入数据类型
          for(n=0;n<6;n++)
 { 
             if(strcmp(token,rwtab[n])==0)//判断读入字符串是否为程序中定义的特殊字符串

                 syn=n+1;//function:1,if:2,then:3,while:4,do:5,endfunc:6
break;
}
 }
 } 
      else if(ch>='0' && ch<='9')//读入第一个数据为数字(读入为数字,直接经过sum运算,结果存放在sum中)
 { 
         sum=0; 
         while(ch>='0' && ch<='9') 

            sum=sum*10+ch-'0';//将输入数字转换成10进制数
            ch=prog[p++];
}
         p--;//使得prog[p]被ch读入的最后一个数字
         syn=11;//若为数字,则,syn为11
 } 
      else switch(ch)//读入第一个数据为运算符(运算符先存放在token数组中)
 { 
            case '<':
         m=0;token[m++]=ch;//token[0]='<',m=1
                      ch=prog[++p];//ch取下一个数据
                      if(ch=='=')//<=
 { 
                          syn=22; 
 //token[m+1]=ch;这一句的意思是token[2]=ch,错误,修改如下
 token[m++]=ch;//token[1]='='
 } 
                      else//<
 { 
                          syn=20; 
 ch=prog[--p];//ch='<'
 }
                      break; 
            case '>':
         m=0;token[m++]=ch;
                      ch=prog[++p]; 
                      if(ch=='=') 
 { 
                          syn=24; token[m++]=ch;
 } 
                      else 
 { 
                          syn=23; ch=prog[--p]; 
 } 
                      break;
            case '=':
     m=0;token[m++]=ch;
                      ch=prog[++p]; 
                      if(ch=='=')
 {
                         syn=25; token[m++]=ch;
 } 
                      else
 { 
                         syn=18; ch=prog[--p];
 } 
                      break;
            case '!':
     m=0;token[m++]=ch;
                      ch=prog[++p];
                      if(ch=='=')
 { 
                         syn=22; token[m++]=ch; 
 } 
                      else syn=-1;
                      break;
            case '+':syn=13;token[0]=ch;break;
            case '-':syn=14;token[0]=ch;break; 
            case '*':syn=15;token[0]=ch;break; 
            case '/':syn=16;token[0]=ch;break;
            case ';':syn=26;token[0]=ch;break; 
            case '(':syn=27;token[0]=ch;break; 
            case ')':syn=28;token[0]=ch;break; 
            case '#':syn=0;token[0]=ch;break; 
            default:syn=-1;
 }
 }
/*该函数的功能是生成一个三地址语句送到四元式表中。*/
void emit(char *result,char *ag1,char *op,char *ag2)

         strcpy(quad[count].result,result); 
         strcpy(quad[count].ag1,ag1);
         strcpy(quad[count].op,op); 
         strcpy(quad[count].ag2,ag2);
         count++; 
         return;
}
/*该函数回送一个新的临时变量名,临时变量名产生的顺序为t1,t2,…*/ 
char *newtemp()

 //k初值为0
      char *p; char m[8];
      p=(char *)malloc(8);
      k++;//假设第一次调用该函数,此时k=1;
      itoa(k,m,10);//m=1;
      strcpy(p+1,m);//把m的值复制到p指针指向的地址后面一个字节开始的内存中,p[1]=1
      p[0]='t';
      return(p); 

/*factor函数,检查是否标识符,如果是,调用scaner函数,
如果不是,检查是否是数值,
如果是,调用scaner函数,
如果不是,检查是否是'(',
如果不是,进行出错处理,
如果是,调用scaner函数,再调用expression()函数,返回后检查是否是')',
如果不是,进行出错处理,如果是,调用scaner函数,返回*/
char *factor(void)
{
     char *fplace;
     fplace=(char *)malloc(12);
     strcpy(fplace," ");//初始化fplace
     if(syn==10)//该数据单位为字符串
     {
         strcpy(fplace,token);//将该字符串赋值给fplace
         scaner();//获取下一个数据单位
     } 
    else if(syn==11)//该数据单位为数字
    { 
       itoa(sum,fplace,10);//将sum的值以10进制的形式存放在fplace中
       scaner();//获取下一个数据单位
    }
    else if(syn==27)//该数据单位为(

       scaner();//获取下一个数据单位
       fplace=expression();//调用expression(其实就是获取完下一个数据单位后,在factor函数中对其分析,当下一个数据单位不为(,获取下一个数据单位,且执行下一句)
       if(syn==28)//如果下一个数据单位为')'
          scaner();//直接获取下一个数据单位
       else 
  { 
          printf("\n')'错误");
          kk=1; //标志
  } 

    else

          printf("\n')'错误"); 
          kk=1; 

    return (fplace);//返回数据单位的内容,如果是(,则返回(后面一个数据单位的内容
}
/*term()函数的作用是判断输入的是否是由'*''/'连接成的因式,并将对应的四元式保存并输出*/
char *term(void) 

     char *tp,*ep2,*eplace,*tt;
     tp=(char *)malloc(12);
     ep2=(char *)malloc(12); 
     eplace=(char *)malloc(12); 
     tt=(char *)malloc(12);
     strcpy(eplace,factor());//调用factor,eplace为上一个数据单位的内容
     while(syn==15||syn==16)//该数据单位为'*'或者'/'

        if(syn==15)//如果为'*' 

            tt[0]='*'; tt[1]='\0';//tt存放该数据单位的内容
        }  
        else if(syn==16)//如果为'/'
{
            tt[0]='/'; tt[1]='\0';//tt存放该数据单位的内容

        scaner();//获取下一个数据单位 
        strcpy(ep2,factor());//调用factor()函数,并将函数返回值赋值给ep2(字符串,数字,'(',出错)
        strcpy(tp,newtemp());//调用newtemp()函数,将该函数返回值赋值给tp,tp为临时变量名
        emit(tp,eplace,tt,ep2);//调用emit函数,生成一个三地址语句存放在四元式表中
        strcpy(eplace,tp);//eplace为四元式
}
     return(eplace);
}
char *expression(void) 

     char *tp,*ep2,*eplace,*tt;
     tp=(char *)malloc(12);
     ep2=(char *)malloc(12);
     eplace=(char *)malloc(12); 
     tt=(char *)malloc(12); 
     strcpy(eplace,term());//调用term函数,将四元式的内容赋值给eplace
     while(syn ==13 || syn==14) //当它不为*或者/时,接着判断是否为+或者-
     {
           if(syn==13) 
          { 
               tt[0]='+'; 
               tt[1]='\0';
           } 
           else if(syn==14) 
           {
             tt[0]='-'; tt[1]='\0';
           } 
           scaner(); 
           strcpy(ep2,term());
           strcpy(tp,newtemp());
           emit(tp,eplace,tt,ep2);
           strcpy(eplace,tp);
     } 
     return(eplace);//返回对应四元式的值

int statement() 

       char tt[8],eplace[8];
       int schain=0; 
       switch(syn) 
       { 
            case 10: strcpy(tt,token);//若第二个数据单位的syn为10,即字符串(as1),将第二个数据单位的内容复制给tt 
            scaner();//再取下一个数据单位,并获得该数据单位的syn
            if(syn==18)//第三个数据单位为'='

                scaner();//再取下一个数据单位,并获得该数据单位的syn(第四个数据单位)
                strcpy(eplace,expression());//调用expression,如果为+或者-,返回对应四元式的值,如果为*或者/,则返回其四元式的值
                emit(tt,eplace," "," "); 
                schain=0;
            } 
            else 

                printf("\n缺少赋值句\n"); kk=1; 

            break; 
  } 
       return(schain);

int yucu() 

     int schain=0; 
     schain=statement();//调用statement()函数,
     while(syn==26)//该数据单位为; 

        scaner();
        schain=statement(); 
     } 
     return(schain); 

int lrparser()

      int schain=0; kk=0; 
      if(syn==1)//输入数据为function
 { 
         scaner();//因为p停留在上一次扫描结束的地方,所以再次调用该函数ch可以获取下一个数据单位,得到该数据单位的syn
         schain=yucu();//调用yucu()函数
         if(syn==6)//endfunc 

            scaner(); 
            if(syn==0 && kk==0)//#
            printf("\n语法,语义分析成功!");
}
         else 

            if(kk!=1) 

                printf("\n缺endfunc\n"); kk=1;

}
 } 
      else 
 {
          printf("\n缺少function\n");
          kk=1;
 } 
      return(schain); 

void main() 

int i; p=0; 
FILE *fp;
//if((fp=fopen("D:\\6.txt","r"))==NULL)
if((fp=fopen("E:\\编译原理期末代码\\36.txt","r"))==NULL)
{
        printf("\n 文件打开失败:\n");
   exit(0);
}
do{ 
ch=fgetc(fp);
        prog[p++]=ch;
    }while(ch!='#'); //将输入字符串赋值到prog数组
    p=0; //使得ch从第一个字符开始获取
    printf("种别码 单词符号\n"); 
    do{ 
         scaner(); //扫描输入的数据,并作出类型判断(以字符串为单位)
         switch(syn) 

              case 11: printf("%-3d %d\n",syn,sum); break; //输入为数字,打印出它的syn与大小
              case -1: printf("词法分析失败,程序终止!\n"); return; //输入数据不正确
              default: printf("%-3d %s\n",syn,token); //字符串,运算符

}while(syn!=0);//读入所有输入的数据(只是判断输入数据是否正确,并没有进行语法,语义分析操作)
    printf("词法分析成功,按任意键进行语法、语义分析"); 
    getch();//按任意键,程序往下执行
    p=0;//词法分析后,重新对ch赋值,使得ch从第一个字符开始获取
    scaner();//扫描第一个单位,判断其类型 
    lrparser();//将将第一个输入字符串翻译为四元式
    if(kk!=0) 
    { 
        printf("语法分析失败,程序终止!");
        return; 
    }
    printf("\n三地址指令如下:\n"); 
    for(i=0;i<count;i++) 
    { 
           printf("%s=",quad[i].result); 
           printf("%s",quad[i].ag1); 
           printf("%s",quad[i].op); 
           printf("%s\n",quad[i].ag2); 
     } 
     getch(); 
     return;
 }


 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值