semantic.c

#include
#include
#include
#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 write_stat();
int read_stat();
int declaration_stat();
int declaration_list();
int statement_list();
int compound_list();
int name_def(char *name);
char token[20],token1[40];/*token保存单词符号,token1保存单词组*/
extern char Scanout[300],Codeout[300];/*保存词法分析输出文件名*/
FILE *fp,*fout;/*用于指向输入输出文件的指针*/
struct /*定义符号表结构*/
{
 char name[8];
 int address;
}vartable[maxvartablep];/*改符号表最多容纳maxvartablep个记录*/
int vartablep=0,labelp=0,datap=0;/*插入符号表动作@name-def!n,t的程序如下*/
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;/*22表示变量重复声明*/
   break;
  }
 }
 if(es>0) return(es);
 strcpy(vartable[vartablep],name,name);
 vartable[vartablep].address=datap;
 printf("@\n");
 printf("  %s  %d\n",vartable[vartablep].name,vartable[vartablep].address);
 printf("@\n");
 datap++;/*分配一个单元,数据区指针加1*/
 vartablep++;
 return(es);
}
/*查询符号表返回地址*/
int lookup(char *name,int *paddress)
{
 int i,es=0;
 for(i=0;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 open%serror!\n",Scanout);
  es=10;
  return(es);
 }
 printf("qing shu ru mu biao wen jian(bao kuo lu jing):");
 scanf("%s",Codeout);
 if((fout=fopen(Codeout,"w"))==NULL)
 {
  printf("\n create%serror!\n",Codeout);
  es=10;
  return(es);
 }
 if(es==0) es=program();
 printf("==yu fa\yu yi fen xi ji dai ma sheng cheng cheng xu jie guo==\n");/*语法、语义分析及代码生成程序结果*/
 switch(es)
 {
  case 0:printf("yu fa\yu yi fen xi cheng gong bing chou xiang ji hui bian sheng cheng dai ma!\n");break;/*语法、语义分析成功并抽象机汇编生成代码!*/
  case 10:printf("open text%serror!\n",Scanout);break;
  case 1:printf("lack of{!\n");break;
  case 2:printf("lack of}!\n");break;
  case 3:printf("lack of biao shi fu!\n");break;
  case 4:printf("lack of fen hao!\n");break;
  case 5:printf("lack of(!\n");break;
  case 6:printf("lack of)!\n");break;
  case 7:printf("lack of cao zuo shu!\n");break;
  case 21:printf("fu hao biao yi chu!\n");break;/*符号表溢出*/
  case 22:printf("bian liang chong fu ding yi!\n");break;/*变量重复定义*/
  case 23:printf("bian liang wei sheng ming!\n");break;/*变量未声明*/
 }
 fclose(fp);
 fclose(fout);
 return(es);
}
/*::={}*/
/*program::={}*/
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("  fu hao biao\n");
 printf("  name  address");
 for(i=0;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*/
/*!vartablep,datap,codep->int  if(strcmp(token,"ID")) return(es=3);/*不是标识符*/
 es=name_def(token1);/*插入标识符*/
 if(es>0) return(es);
 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 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();
 /*可在此处添加do语句调用*/
 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);
}
/*::=if()[else]*/
/*::=if()[else]*/
/*if()@BRF!label1@BR!label2@SETlabel!label1[else]@SETlabel!label2
if()@BRF!label1@BR!label2@SETlabel!label1[else]@SETlabel!label2
其中动作符号的含义如下:
@BRF!label1:输出BRFlabel1
@BR!label2:输出BRlabel2
@SETlabel!label1:设置标号label1
@SETlabel!label2:设置标号label2*/
int if_stat()
{
 int es=0,label1,label2;/*if*/
 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);/*少右括号*/
 label1=labelp++;/*用label1记住条件为假时要转向的标号*/
 fprintf(fout,"  BRF LABEL%d\n",label1);/*输出假转移指令*/
 fscanf(fp,"%s%s\n",&token,&token1);printf("%s%s\n",token,token1);
 es=statement();
 if(es>0) return(es);
 label2=labelp++;/*用label2记住要转向的标号*/
 fprintf(fout,"  BR LABEL%d\n",label2);/*输出无条件转移指令*/
 fprintf(fout,"LABEL%d:\n",label1);/*设置label1记住的标号*/
 if(strcmp(token,"else")==0)/*else部分处理*/
 {
  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",label2);/*设置label2记住的标号*/
 return(es);
}
/*::=while()*/
/*::=while()*/
/*::=while@SETlabel!label1()@BRF!label2@BR!label@SETlabel!label2
动作解释:
@SETlabel!label1:设置标号label1
@BRF!label2:输出BRFlabel2
@BR!label1:输出BRlabel1
@SETlabel!label2:设置标号label2*/
int while_stat()
{
 int es=0,label1,label2;
 label1=labelp++;
 fprintf(fout,"LABEL%d:\n",label1);/*设置label1记住的标号*/
 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);/*少右括号*/
 label2=labelp++;
 fprintf(fout,"  BRF LABEL%d\n",label2);/*输出无条件转移指令*/
 fscanf(fp,"%s%s\n",&token,&token1);printf("%s%s\n",token,token1);
 es=statement();
 if(es>0) return(es);
 fprintf(fout,"  BR LABEL%d\n",label1);/*输出假转移指令*/
 fprintf(fout,"LABEL%d:\n",label2);/*设置label2记住的标号*/
 return(es);
}
/*::=for(,,)*/
/*::=for(;
 @SETlabel!label1@BRF!label2@BR!label3;
 @SETlabel!label4@BR!label)
 @SETlabel!label3@BR!label4@SETlabel!label2
动作解释:
1,@SETlabel!label1:设置标号label1
2,@BRF!label2:输出BRFlabel2
3,@BR!label3:输出BRlabel3
4,@SETlabel!label4:设置标号label4
5,@BR!label1:输出BRlabel1
6,@SETlabel!label3:设置标号label3
7,@BR!label4:输出BRlabel4
8,@SETlabel!label2:设置标号label2*/
int for_stat()
{
 int es=0,label1,label2,label3,label4;
 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);/*少分号*/
 label1=labelp++;
 fprintf(fout,"LABEL%d:\n",label1);/*设置label1标号*/
 fscanf(fp,"%s%s\n",&token,&token1);printf("%s%s\n",token,token1);
 es=expression();
 if(es>0) return(es);
 label2=labelp++;
 fprintf(fout,"  BRF LABEL%d\n",label2);/*输出无条件转移指令*/
 label3=labelp++;
 fprintf(fout,"  BR LABEL%d\n",label3);/*输出无条件转移指令*/
 if(strcmp(token,";")) return(es=4);/*少分号*/
 label4=labelp++;
 fprintf(fout,"LABEL%d:\n",label4);/*设置label4标号*/
 fscanf(fp,"%s%s\n",&token,&token1);printf("%s%s\n",token,token1);
 es=expression();
 if(es>0) return(es);
 fprintf(fout,"  BR LABEL%d\n",label1);/*输出无条件转移指令*/
 if(strcmp(token,")")) return(es=6);/*少右括号*/
 fprintf(fout,"LABEL%d:\n",label3);/*设置label3标号*/
 fscanf(fp,"%s%s\n",&token,&token1);printf("%s%s\n",token,token1);
 es=statement();
 if(es>0) return(es);
 fprintf(fout,"  BR LABEL%d\n",label4);/*输出无条件转移指令*/
 fprintf(fout,"LABEL%d:\n",label2);/*设置label2标号*/
 return(es);
}
/*::=write*/
/*::=write@OUT*/
/*动作解释:
@OUT:输出OUT*/
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);
}
/*::=read ID*/
/*::=read ID!n
/*动作解释
@LOOK!n!d查符号表n,给出变量地址d;没有,变量没定义
@IN:输出IN
@STI!d:输出指令代码STI d*/
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[30];
 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);
}
/*::=|(>|=|<=|==|!=)*/
/*::=
|>@GT
|<@LES
|>=@GE
|<=@LE
|==@EQ
|!=@NOTEQ*/
int bool_expr()
{
 int es=0;
 es=additive_expr();
 if(es>0) return(es);
 if(strcmp(token,">")==0||strcmp(token,">=")==0||strcmp(token," {
  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,"  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);
}
/*::={(+|-)}*/
/*::={(+@ADD|-@SUB)}*/
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);
}
/*::={(*|/)}*/
/*::={(*@MULT|/@DIV)}*/
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,"  MULT\n");
  if(strcmp(token2,"/")==0) fprintf(fout,"  DIV\n");
 }
 return(es);
}
/*::=()|ID|NUM*/
/*::=()|ID!n@LOOK!n!d@LOAD!d|NUM!i@LOAD!i*/
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,"  LOADI%d\n",token1);
   fscanf(fp,"%s%s\n",&token,&token1);printf("%s%s\n",token,token1);
   return(es);
  }
  else
  {
   es=7;/*缺少操作数*/
   return(es);
  }
 }
 return(es);
}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12993749/viewspace-353264/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12993749/viewspace-353264/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值