当前位置: 首页 > article >正文

scau编译原理综合性实验

一、题目要求

题目

选择部分C语言的语法成分,设计其词法分析程序、语法语义分析程序。

要求

设计并实现一个一遍扫描的词法语法语义分析程序,将部分C语言的语法成分(包含赋值语句、if语句、while循环语句)翻译成三地址代码,要求有一定的出错提示和错误恢复功能。

二、源码 

#include <stdio.h>
#include <string.h>
#include   <stdlib.h>

#define BUFFSIZE 5000
char prog[BUFFSIZE],token[8];
char ch,ch1;
int syn,p,q,m,n,sum,i=1,k=0,kk,flag=0;
char *rwtab[32]={"main","break","case","char","define","continue","default",
                 "do","double","else","what","extern","float","for","goto","if",
                 "int","long","stack","return","short","fopen","sizeof",
				 "static","struct","switch","typedef","enum","unsigned","void","fclose","while"};

int main()  /*主函数*/
{
  void scaner();
  int lrparser();
  FILE *fp;
  if((fp=fopen("test.txt","r"))==NULL)
    { printf("无法打开文件!\n");
      exit(1);
    }
  p=0;
  while(!feof(fp))
    {  prog[p++]=fgetc(fp);
       if(p>=5000)
       {  printf("缓冲区容量不够!\n");
          exit(1);
           }
    }/*把文件test中的内容存入数组prog中*/
  fclose(fp);
  printf("%s\n",prog);
  p=0;
printf("输出词法分析结果:\n");
	do
	{
		scaner();
		switch(syn)
		{
		case 34:printf("(%d,%d),",syn,sum);break;
		case -1:printf("error,");break;
		default:printf("(%d,%s),",syn,token);
		}
	}while(syn!=0);
	p=0;
	printf("\n语法语义的分析开始:\n");
  scaner();
  lrparser();
  system("pause");
  return 0;
}

void scaner()
{
  for(n=0;n<8;n++) token[n]=NULL;
  m=0;
  sum=0;
  ch=prog[p];
  while(ch==' '||ch=='\n')
  { p++;
    ch=prog[p];
      }/*读下一个字符*/

  if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'))
  { while((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9'))
    { token[m]=ch;
      m++;p++;
      ch=prog[p];
        }

  token[m++]='\0';
  syn=33;
  for(n=0;n<32;n++)
     if(strcmp(token,rwtab[n])==0)
     { syn=n+1;
       break;
         }
  }/*判断输入字符是否为标识符或者关键字的情况*/

  else
      if(ch>='0'&&ch<='9')
      { while(ch>='0'&&ch<='9')
        { sum=sum*10+ch-'0';
          p++;
          ch=prog[p];
            }
        syn=34;
    }/*判断输入字符是否为整型常数的情况*/

  else
      switch(ch)
      {
       case '<':token[m]=ch;
                p++;
                ch=prog[p];
                if(ch=='>')
                { syn=42;
                  m++;
                  token[m]=ch;
                  p++;
                }/*出现<>的情况*/
                else if(ch=='=')
                { syn=43;
                  m++;
                  token[m]=ch;
                  p++;
                }/*出现<=的情况*/
                else
                { syn=41;}
                break;

       case '>':token[m]=ch;
                p++;
                ch=prog[p];
                if(ch=='=')
                { syn=45;
                  m++;
                  token[m]=ch;
                  p++;
                }/*出现>=的情况*/
                else
                {syn=44;}
                break;

       case ':':token[m]=ch;
                p++;
                ch=prog[p];
                if(ch=='=')
                { syn=40;
                  m++;
                  token[m]=ch;
                  p++;
                }/*出现:=的情况*/
                else
                {syn=39;}
                break;

       case '/':token[m]=ch;
                p++;
                ch=prog[p];
                if(ch=='*')
                { syn=51;
                  q=0;
                  m++;
                  token[m]=ch;
                  p++;
                  q=p+1;
                  while(prog[p]!='*'||prog[q]!='/')
                  {p++;q++;}
                    }/*出现注释'/*'的情况*/
                else
                {syn=38;}
                break;

       case '*':token[m]=ch;
                p++;
                ch=prog[p];
                if(ch=='/')
                { syn=52;
                  m++;
                  token[m]=ch;
                  p++;
                }
                else
                {syn=37;}
                break;

       case '+':syn=35;token[0]=ch;p++;break;
       case '-':syn=36;token[0]=ch;p++;break;
       case '=':syn=46;token[0]=ch;p++;break;
       case ';':syn=47;token[0]=ch;p++;break;
       case '(':syn=48;token[0]=ch;p++;break;
       case ')':syn=49;token[0]=ch;p++;break;
       case '%':syn=50;token[0]=ch;p++;break;
       case '{':syn=53;token[0]=ch;p++;break;
       case '}':syn=54;token[0]=ch;p++;break;
       case ',':syn=55;token[0]=ch;p++;break;
       case '#':syn=0;token[0]=ch;p++;break;
       default:syn=-1;
          }

}

void emit(char *result,char *ag1,char *op,char *ag2)
{
    printf("(%d) %s=%s%s%s\n",i,result,ag1,op,ag2);
    i++;
    return;
}

char *newtemp(void)
{
    char *p;
    char m[8];
    p=(char *)malloc(8);
    k++;
    itoa(k,m,10);
    strcpy(p+1,m);
    p[0]='t';
    return(p);
}

int lrparser()
{   int yucu();
    int schain=0;
    kk=0;
    if(syn!=1)
	{
	printf("缺main错误!!\n");
    flag++;
	}
    scaner();
    if(syn!=48)
	{
    printf("main后缺(括号!!\n");
    flag++;
	}
    else scaner();
    if(syn!=49)
	{
    printf("main后缺)括号!!\n");
    flag++;
	}
    else scaner();
    if(syn!=53)
	{
	printf("main后缺{括号!!\n");
    flag++;
	}
    else scaner();
      schain=yucu();
      if(syn==54)
      { scaner();
        if(syn==0&&kk==0&&flag==0)/*kk是用来记录其他错误的标识*/
        printf("语法与语义分析结束。分析结果为:success\n");
		else
			printf("程序存在着%d个错误\n",flag);
      }
      else
      {if(kk!=1)
       printf("缺}错误!!");
       kk=1;
      }
   return(schain);
}

int yucu()
{
  int statement();
  int schain=0;
  schain=statement();
  while(syn==47)
  { scaner();
    schain=statement();
      }
  return(schain);
}

int statement()
{
    char *expression();
    char tt[8],eplace[8];
    int schain=0;
    switch(syn)
    { case 33:

             strcpy(tt,token);
             scaner();
             if(syn==46)
               { scaner();
                 strcpy(eplace,expression());
                 emit(tt,eplace," "," ");
                 schain=0;
               }
             else{printf("赋值号=错误!!");kk=1;}
      return(schain);
      break;
    }
}

char *expression(void)
{ char *term();
  char *tp,*ep2,*eplace,*tt;
  tp=(char *)malloc(12);
  ep2=(char *)malloc(12);
  eplace=(char *)malloc(12);
  tt=(char *)malloc(12);
  strcpy(eplace,term());
  while(syn==35||(syn==36))
  {   strcpy(tt,token);
      scaner();
      strcpy(ep2,term());
      strcpy(tp,newtemp());
      emit(tp,eplace,tt,ep2);
      strcpy(eplace,tp);
      }
  return(eplace);
}

char *term(void)
{
  char *factor();
  char *tp,*ep2,*eplace,*tt;
  tp=(char *)malloc(12);
  ep2=(char *)malloc(12);
  eplace=(char *)malloc(12);
  tt=(char *)malloc(12);
  strcpy(eplace,factor());
  while(syn==37||(syn==38))
  {   strcpy(tt,token);
      scaner();
      strcpy(ep2,factor());
      strcpy(tp,newtemp());
      emit(tp,eplace,tt,ep2);
      strcpy(eplace,tp);
      }
  return(eplace);
}

char *factor(void)
{
    char *fplace;
    fplace=(char *)malloc(12);
    strcpy(fplace," ");

    if(syn==33)
    {
       strcpy(fplace,token);
       scaner();
    }
    else if(syn==34)
    {
       itoa(sum,fplace,10);
       scaner();
    }
    else if(syn==48)
     {
         scaner();
        fplace=expression();
        if(syn==49)
        scaner();
        else{printf("缺‘)’错误!!\n");kk=1;flag++;}
     }

     else{printf("表达式错误!!\n");kk=1;flag++;}
     return(fplace);
}
















http://www.kler.cn/a/408342.html

相关文章:

  • MariaDB面试题及参考答案
  • 用 Python 从零开始创建神经网络(九):反向传播(Backpropagation)
  • 【Linux】安装cuda
  • 09 —— Webpack搭建开发环境
  • 【电源专题】BUCK电源SW电压的平均值为什么等于输出电压?
  • mq 消费慢处理方式,rocketmq消费慢如何处理,mq如何处理消费端消费速率慢。rocketmq优化
  • 【数据结构】链表重难点突破
  • CTF之密码学(键盘加密)
  • Linux(2)
  • 16.C++STL 3(string类的模拟,深浅拷贝问题)
  • 〔 MySQL 〕中三种重要的日志类型
  • Java网络编程 - cookiesession
  • Vulnhub靶场 Jangow: 1.0.1 练习
  • C语言超详细教程
  • 挂壁式空气净化器哪个品牌的质量好?排名top3优秀产品测评分析
  • 网络性能及IO性能测试工具
  • golang实现TCP服务器与客户端的断线自动重连功能
  • 优先算法 —— 双指针系列 - 复写零
  • 青训营刷题笔记17
  • [自动化]获取每次翻页后的页面 URL
  • Java核心特性解析:方法、Stream流、文件与IO详解
  • 每日OJ_牛客_合唱队形_DP_C++_Java
  • 数据库连接池(二)
  • Vue v-if 与 v-for 使用指南:优先级、注意事项及常见错误防范
  • Independent Component Analysis
  • 如何利用ros搭建虚拟场景通过仿真机器人完成一次简单的SLAM建图、导航规划(超简单)?——学习来源:机器人工匠阿杰