语义分析课程设计

 
一.  语义分析和代码生成程序的功能和目的
主义分析的功能 : 语义分析主要借助符号表记录的信息来实现语义分析动作 . 在语法分析中,严格按照文法来检查语句的语法是否正确,但有些语句,单看语法结构并没有错误,但和该语句所处的上下文联系考虑就有错误,那么,把这种错误就称为语义错误。语义分析就是处理这种语义错误 .
代码生成程序的功能和目的 : 中间代码是在编译程序将高级语言程序翻译为汇编语言或机器代码的过程中产生的,在编译过程中起着桥梁的作用 .
二.  所实现的语义分析和代码生成程序能处理什么语句
(1). 简单变量的声明语句
(2). 表达式语句
(3).if 语句 .
(4)while 语句
(5)for 语句
(6)write 语句
(7)read 语句
(8)do 语句 .
(9) 处理过程调用和返回
. 语义分析代码生成程序生的目标代码及好处
语义分析代码生成程序生成一种作为源程序中间形式的抽象机的代码。而该抽象机的指令应当尽可能模仿所编译的源语言的结构,且具备下列两个特点:可移植性和可适应性。这种代码的好处是提高可读性和简化代码生成过程,开发出可移植又适用的编译程序。同时降低移植的开销,使得程序很容易进行修改,满足不同用户和系统的需求 .
. 该程序的错误处理方法
为了简化起见,在 TEST 编译程序中没有进行复杂的错误处理。在语法和语义分析中,一旦遇到语法或语义错误,则停止编译,立即返回,并报告发生的错误。
. 实验过程
. 首先用 VC++ 编辑、编译和运行教材 P231~245 的语义及代码生成程序。步骤如下:先编辑主程序文件 TESTmain.c(P244) 、词法分析程序 TESTscan.c(P218-220) 和语法、语义及代码生成程序 TESTparse.c P231-245 )这三个文件,然后新建一个工程 , 接下来,将上述三个文件加入到该工程中,编译后运行即可。
. 下一步为了能使程序分析 do 语句 , 修改词法分析程序 TESTscan.c 和语法语 , 义及代码生成程序 TESTparse.c 这二个文件 , 使该程序能分析 do 语句 .( 其实这一步在第二次实验时就已经修改了词法分析程序 , 在这次实验中我们首先分析在没有 do 语句时程序运行会出什么错误 , 在对词法分析程序添加 do 关键字 , 进行分析带有 do 的源程序 .)
首先起先上面第一步的语义分析 , 在这里编写一个
 {
int i;
 int j;
 if(i<10)
 i=9;
 else
 i=11;
 if(j>10)
 j=12;
 else
 j=8;
}

文件,以文件名A.T保存在D盘中.然后用语义分析程序进行语义分析,如图:

 

 

至此,语义分析成功!
B.T文件中的内容如下:
{      {
int     int
ID    i
;       ;
int     int
ID    j
;       ;
if      if
(       (
ID    i
<      <
NUM       10
)       )
ID    i
=      =
NUM       9
;       ;
else else
ID    i
=      =
NUM       11
;       ;
if      if
(       (
ID    j
>      >
NUM       10
)       )
ID    j
=      =
NUM       12
;       ;
else else
ID    j
=      =
NUM       8
;       ;
}      }
C.T文件内容如下:
       LOAD0
     LAODI10
       LES
       BRF LABLE0
     LAODI9
     STO0
       BR LABLE1
LABEL0:
     LAODI11
     STO0
LABLE1:
       LOAD1
     LAODI10
      GT
       BRF LABLE2
     LAODI12
     STO1
       BR LABLE3
LABEL2:
     LAODI8
     STO1
LABLE3:
     STOP
至于第二步关于添加 do 语句时的运行情况这里就不再详细介绍了 .
. 实验体会
这次实验让我学到了更多的编译知识 , 从对词法 , 到语义分析上有了理深一步了解 , 实验中 , 也遇到了不少问题 , 比如输入程序就是个很大的问题了 . 但总体上对实验的理解还是能了解实验要我们完成的目的 . 日后还要花时间慢慢体会编译原理这一门课程 .
 
附件 :( 只提供两个源代码 )
 // 主程序 TESTmain
#include <stdio.h>
#include <ctype.h>
extern int TESTscan();
extern int TESTparse();
char Scanin[300],Scanout[300],Errorfile[300],Codeout[300];
FILE *fin,*fout;
void main(){
      int es=0;
      es=TESTscan();
      if(es>0) printf(" 词法分析有错,编译停止! ");
      else printf(" 词法分析成功! /n");
      if(es==0){
                es=TESTparse();
                if(es==0) printf(" 语法、语义分析并生成代码成功! /n");
                else printf(" 语法、语义分析并生成代码失败! /n");
        }
              }
 //TESTparse
#include<stdio.h>
#include<ctype.h>
#include<conio.h>
#define maxvartablep 500
int TESTparse();
int program();
int compound_stat();
int statement();
int expression_stat();
int expression();
int bool_expr();
int additive_expr();
int term();
int factor();
int if_stat();
int while_stat();
int for_stat();
int do_stat();
int write_stat();
int read_stat();
int declaration_stat();
int declaration_list();
int statement_list();
int compound_stat();
int name_def(char * name);
char token[20],token1[40];
extern char Scanout[300],Codeout[300];
FILE *fp,* fout;
struct{
       char name[8];
       int address;
       }vartable[maxvartablep];
int vartablep=0,lablep=0,datap=0;
 
int name_def(char * name)
    {
     int i ,es=0;
     if(vartablep>=maxvartablep) return(21);
     for(i=vartablep-1;i==0;i--)
         {
           if(strcmp(vartable[i].name,name)==0)
              {es=22;
               break;
              }
          }
         if(es>0) return(es);
         strcpy(vartable[vartablep].name,name);
         vartable[vartablep].address=datap;
        datap++;
        vartablep++;
        return(es);
      }
int lookup(char *name,int *paddress)
{
 int i, es=0;
 for(i=0;i<vartablep;i++)
    {
     if(strcmp(vartable[i].name,name)==0)
        {
          *paddress=vartable[i].address;
          return(es);
         }
      }
 es=23;
 return(es);
 }
 
 
 
int TESTparse()
 {
    int es=0;
    if((fp=fopen(Scanout,"r"))==NULL)
      {
       printf("/n 打开%错误!/n",Scanout);
       es=10;
       return(es);
       }
      printf("请输入目标文件名(包括路径):");
      scanf("%s",Codeout);
      if((fout=fopen(Codeout,"w"))==NULL)
         {
          printf("/n创建%错误!/n",Codeout);
          es=10;
          return(es);
          }
      if(es==0) es=program();
      printf("==语法、语义分析及代码生成程序结果==/n");
      switch(es){
                 case 0 :printf("语法、语义分析成功并抽象机汇编生成代码!/n");break;
                 case 10 :printf("打开文件%失败!/n",Scanout);break;
                 case 1 :printf("缺少{!/n");break;
                 case 2 :printf("缺少}!/n");break;
                 case 3 :printf("缺少标识符!/n");break;
                 case 4:printf("缺少分号!/n");break;
                 case 5 :printf("缺少(!/n");break;
                 case 6 :printf("缺少)!/n");break;
                 case 7 :printf("缺少操作数!/n");break;
                 case 21 :printf("符号表溢出!/n");break;
                 case 22 :printf("变量重复定义!/n");break;
                 case 23 :printf("变量未声明!/n");break;
                 }
       fclose(fp);
        fclose(fout);
       return(es);
      }
   
 
int program()
     {
      int es=0,i;
      fscanf(fp,"%s%s/n",token,token1);
      printf("%s%s/n",token,token1);
      if(strcmp(token,"{"))
      {
       es=1;
       return(es);
       }
      fscanf(fp,"%s%s/n",&token,&token1);
      printf("%s%s/n",token,token1);
      es=declaration_list();
      if(es>0) return(es);
      printf("    符号表/n");
      printf("     名字       地址/n");
      for(i=0;i<vartablep;i++)
         printf("      %s      %d/n",vartable[i].name,vartable[i].address);
      es=statement_list();
      if(es>0) return(es);
      if(strcmp(token,"}"))
        {es=2;
         return(es);
         }
      fprintf(fout,"     STOP/n");
       return(es);
       }
 
 
int declaration_list()
     {
      int es=0;
      while(strcmp(token,"int")==0)
      {
       es=declaration_stat();
       if(es>0)return(es);
      }
      return(es);
      }
 
 
int declaration_stat()
    {
     int es=0;
     fscanf(fp,"%s%s/n",&token,&token1); printf("%s%s/n",token,token1);
     if(strcmp(token,"ID")) return(es=3);
        es=name_def(token1);
        if(es>0)return(es);
     fscanf(fp,"%s%s",&token,&token1); printf("%s%s/n",token,token1);
     if(strcmp(token,";")) return(es=4);
     fscanf(fp,"%s%s/n",&token,&token1); printf("%s%s/n",token,token1);
     return(es);
     }
 
int statement_list()
     {
      int es=0;
      while(strcmp(token,"}"))
      {
       es=statement();
       if(es>0)return(es);
       }
       return(es);
      }
 
 
int statement()
    {
     int es=0;
     if(es==0&&strcmp(token,"if")==0)es=if_stat();
     if(es==0&&strcmp(token,"while")==0)es=while_stat();
     if(es==0&&strcmp(token,"for")==0)es=for_stat();
     if(es==0&&strcmp(token,"do")==0)es=do_stat();
     if(es==0&&strcmp(token,"read")==0)es=read_stat();
     if(es==0&&strcmp(token,"write")==0)es=write_stat();
     if(es==0&&strcmp(token,"{")==0)es=compound_stat();
     if(es==0&&(strcmp(token,"ID")==0||strcmp(token,"NUM")==0))es=expression_stat();
     return(es);
     }
 
 
int if_stat()
    {
     int es=0,lable1,lable2;
     fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     if(strcmp(token,"(")) return(es=5);
     fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     es=expression();
     if(es>0) return(es);
     if(strcmp(token,")")) return(es=6);
     lable1=lablep++;
     fprintf(fout,"       BRF LABLE%d/n",lable1);
     fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     es=statement();
     if(es>0)return(es);
     lable2=lablep++;
     fprintf(fout,"       BR LABLE%d/n",lable2);
     fprintf(fout,"LABEL%d:/n",lable1);
     if(strcmp(token,"else")==0)
        {
        fscanf(fp,"%s%s/n",&token,&token1);
        printf("%s%s/n",token,token1);
         es=statement();
        if(es>0)return(es);
         }
     fprintf(fout,"LABLE%d:/n",lable2);
     return(es);
     }
 
int while_stat()
    {  
     int es=0,lable1,lable2;
     lable1=lablep++;
     fprintf(fout,"LABLE%d:/n",lable1);
     fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     if(strcmp(token,"(")) return(es=5);
     fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     es=expression();
     if(es>0)return(es);
     if(strcmp(token,")")) return(es=6);
     lable2=lablep++;
     fprintf(fout,"       BRF LABLE%d/n",lable2);
      fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     es=statement();
     if(es>0)return(es);
     fprintf(fout,"       BR LABLE%d/n",lable1);
     fprintf(fout,"LABEL%d:/n",lable2);
     return(es);
    }
int do_stat()
    {
     int es=0,lable1,lable2;
     fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     if(strcmp(token,"(")) return(es=5);
     fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     es=expression();
     if(es>0) return(es);
     if(strcmp(token,")")) return(es=6);
     lable1=lablep++;
     fprintf(fout,"       BRF LABLE%d/n",lable2);
     fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     es=statement();
     if(es>0)return(es);
     fprintf(fout,"LABEL%d:/n",lable1);
        if(strcmp(token,"while")==0)
        {
        fscanf(fp,"%s%s/n",&token,&token1);
        printf("%s%s/n",token,token1);
         es=statement();
        if(es>0)return(es);
         }
     fprintf(fout,"LABLE%d:/n",lable2);
     return(es);
     }
 
 
 
int for_stat()
    {
     int es=0,lable1,lable2,lable3,lable4;
     fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     if(strcmp(token,"(")) return(es=5);
     fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     es=expression();
     if(es>0)return(es);
     if(strcmp(token,";"))return(es=4);
     lable1=lablep++;
     fprintf(fout,"LABLE%d:/n",lable1);
      fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     es=expression();
     if(es>0)return(es);
     lable2=lablep++;
      fprintf(fout,"       BRF LABLE%d/n",lable2);
     lable3=lablep++;
     fprintf(fout,"       BR LABLE%d/n",lable3);
     if(strcmp(token,";"))return(es=4);
     lable4=lablep++;
      fprintf(fout,"LABLE%d:/n",lable4);
      fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
     es=expression();
      if(es>0)return(es);
      fprintf(fout,"       BR LABLE%d/n",lable1);
      if(strcmp(token,")")) return(es=6);
      fprintf(fout,"LABLE%d:/n",lable3);
      fscanf(fp,"%s%s/n",&token,&token1);
     printf("%s%s/n",token,token1);
      es=statement();
      if(es>0)return(es);
      fprintf(fout,"       BR LABLE%d/n",lable4);
      fprintf(fout,"LABLE%d:/n",lable2);
      return(es);
     }
 
 
 
int write_stat()
     {
      int es=0;
       fscanf(fp,"%s%s/n",&token,&token1);
       printf("%s%s/n",token,token1);
       es=expression();
          if(es>0)return(es);
        if(strcmp(token,";"))return(es=4);
        fprintf(fout,"      OUT/n");
       fscanf(fp,"%s%s/n",&token,&token1);
       printf("%s%s/n",token,token1);
       return(es);
       }
 
 
 
 
int read_stat()
     {
      int es=0,address;
      fscanf(fp,"%s%s/n",&token,&token1);
       printf("%s%s/n",token,token1);
      if(strcmp(token,"ID"))return(es=3);
      es=lookup(token1,&address);
      if(es>0)return(es);
      fprintf(fout,"     IN    %d/n",address);
      fscanf(fp,"%s%s/n",&token,&token1);
       printf("%s%s/n",token,token1);
       if(strcmp(token,";"))return(es=4);
       fscanf(fp,"%s%s/n",&token,&token1);
       printf("%s%s/n",token,token1);
       return(es);
      }
 
 
int compound_stat()
    {
     int es=0;
     fscanf(fp,"%s%s/n",&token,&token1);
       printf("%s%s/n",token,token1);
     es=statement_list();
     return(es);
     }
 
 
 
 
 
int    expression_stat()
     {
      int es=0;
      if(strcmp(token,";")==0)
        {
          fscanf(fp,"%s%s/n",&token,&token1);
          printf("%s%s/n",token,token1);
          return(es);
        }
       es=expression();
       if(es>0)return(es);
       if(strcmp(token,";")==0)
        {
          fscanf(fp,"%s%s/n",&token,&token1);
          printf("%s%s/n",token,token1);
          return(es);
        }else
        {
         es=4;
         return(es);
         }
       }
 
 
 
int expression()
    {
     int es=0,fileadd;
     char token2[20],token3[40];
     if(strcmp(token,"ID")==0)
       {
        fileadd=ftell(fp);
         fscanf(fp,"%s%s/n",&token2,&token3);
          printf("%s%s/n",token2,token3);
       if(strcmp(token2,"=")==0)
         {
          int address;
          es=lookup(token1,&address);
          if(es>0)return(es);
          fscanf(fp,"%s%s/n",&token,&token1);
          printf("%s%s/n",token,token1);
          es=bool_expr();
          if(es>0)return(es);
          fprintf(fout,"     STO%d/n",address);
 
        }else
        {
         fseek(fp,fileadd,0);
         printf("%s%s/n",token,token1);
         es=bool_expr();
         if(es>0)return(es);
         }
        }
     return(es);
   }
 
 
int bool_expr()
     {
      int es=0;
      es=additive_expr();
      if(es>0)return(es);
      if(strcmp(token,">")==0||strcmp(token,">=")==0
        ||strcmp(token,"<")==0||strcmp(token,"<=")==0
        ||strcmp(token,"==")==0||strcmp(token,"!=")==0)
        {
         char token2[20];
         strcpy(token2,token);
         fscanf(fp,"%s%s/n",&token,&token1);
          printf("%s%s/n",token,token1);
         es=additive_expr();
         if(es>0)return(es);
         if(strcmp(token2,">")==0) fprintf(fout ,"     GT /n");
          if(strcmp(token2,">=")==0) fprintf(fout ,"      GE /n");
           if(strcmp(token2,"<")==0) fprintf(fout ,"       LES/n");
         if(strcmp(token2,"<=")==0) fprintf(fout ,"       LE/n");
          if(strcmp(token2,"==")==0) fprintf(fout ,"       EQ/n");
           if(strcmp(token2,"!=")==0) fprintf(fout ,"      NOTEQ /n");
         }
      return(es);
     
      }
 
 
 
 
int additive_expr()
      {
       int es=0;
       es=term();
       if(es>0)return(es);
       while(strcmp(token,"+")==0||strcmp(token,"-")==0)
          {
            char token2[20];
            strcpy(token2,token);
           fscanf(fp,"%s%s/n",&token,&token1);
          printf("%s%s/n",token,token1);
          es=term();
          if(es>0) return(es);
          if(strcmp(token2,"+")==0)fprintf(fout,"      ADD/n");
           if(strcmp(token2,"-")==0)fprintf(fout,"      SUB/n");
          }
        return(es);
      }
 
 
int term()
    {
     int es=0;
     es=factor();
     if(es>0)return(es);
     while(strcmp(token,"*")==0||strcmp(token,"/")==0)
          {
           char token2[20];
           strcpy(token2,token);
            fscanf(fp,"%s%s/n",&token,&token1);
          printf("%s%s/n",token,token1);
         es=factor();
         if(es>0)return(es);
         if(strcmp(token2,"*")==0)fprintf(fout,"       NULT/n");
           if(strcmp(token2,"/")==0)fprintf(fout,"       DIV/n");
         }
       return(es);
     }
 
 
 
int factor()
     {
      int es=0;
      if(strcmp(token,"(")==0)
        {
          fscanf(fp,"%s%s/n",&token,&token1);
          printf("%s%s/n",token,token1);
          es=expression();
         if(es>0)return(es);
         if(strcmp(token,")"))   return(es=6);
         fscanf(fp,"%s%s/n",&token,&token1);
          printf("%s%s/n",token,token1);
        }else
      {
        if(strcmp(token,"ID")==0)
          {
           int address;
           es=lookup(token1,&address);
          if(es>0)return(es);
          fprintf(fout,"       LOAD%d/n",address);
          fscanf(fp,"%s%s/n",&token,&token1);
          printf("%s%s/n",token,token1);
          return(es);
          }
              if(strcmp(token,"NUM")==0)
              {
                      fprintf(fout,"     LAODI%s/n",token1);
                      fscanf(fp,"%s%s/n",&token,&token1);
                      printf("%s%s/n",token,token1);
                      return(es);
              }else
          {
           es=7;
           return(es);
           }
       }return(es);
}
 
 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值