用c实现的编译原理词法分析器

编译课的上机题,做了好长时间呢,和大家分享一下,o(∩_∩)o...

#include "conio.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define id 1
#define number 2
#define colon 7
#define assign 11
#define lpar 18
#define rpar 19
#define plus 20
#define multiply 21
#define EQ 22
#define LT 23
#define LE 24
#define GT 25
#define GE 26
#define NE 27
char character;

char str1[]="var:(class,value)/n";
char str2[]="num:(class,value)/n";
char str3[]="key:(class,value)/n";

char token[20];

typedef struct table
 {
 char str[20];
 int num;
 struct table *next;
 }table,*Ltable;

struct key_type
{
char name[10];
int c;
int v;
}key[10]={{"BEGIN",3,1},{"END",4,2},{"VAR",6,3},{"INTEGER",10,4},{"IF",12,5},{"THEN",13,6},{"ELSE",14,7},{"WHILE",15,8},{"DO",16,9},{"PROCEDURE",17,10}
};

enum boolean{false,true};

static int flag=0;//标识是否第一次从源文件读取数据

static FILE *fp;

static int value;//表示关键字的value值

static int i=0;//表示token数组将存放一个新单词,i为数组下标

typedef struct 
{
 Ltable head,tail;

}list;


void initlist(list &L)  //构造有头结点的链表
{

 Ltable head=(Ltable)malloc(sizeof(table));
 strcpy(head->str," ");
 head->num=0;
 head->next=NULL;
 L.tail=L.head;
}

void Getchar() 
{
 if(flag==0)
      
 { if((fp=fopen("1.txt","r"))==NULL)
  {
  printf("cannot open this file/n");
  exit(0);
  }
 }
 flag++;
 character=fgetc(fp);
 if(character==EOF)
  fclose(fp);
}

void Getbc()
{
 if(character==EOF)
  return;
 while(character==' '||character=='/n'||character=='/t')
  Getchar();
}

 

void Concatenation()
{
 

 if(i==0)
  {token[0]=character;
  token[1]='/0';
  i=1;
  }
 else
  {token[i]=character;
  i++;
  token[i]='/0';
  }
}

boolean Letter()
{
 if(((character>=65)&&(character<=90))||((character>=97)&&(character<=122)))
  return true;
 return false;

}

boolean Digit()
{
 if(character>=48&&character<=57)
  return true;
 return false;
}

int Reserve()  //查找接受的标识符是否为关键字
{
 int i=0;
 while(i<10)
  {
   if(strcmp(token,key[i].name)!=0)
    i++;
   else
   {
    value=key[i].v;
    return key[i].c;
    }
  }
 return 0;
}

void Retract()
{
 fseek(fp,-1,1);
 character='';
}

int Build(list &L)
{
 
 Ltable p;
 if(L.head!=L.tail)
        {
                 p=L.head->next;
   while((strcmp(p->str,token)!=0)&&(p!=NULL))
           p=p->next;
   if(p==NULL)
   {
   Ltable s=(Ltable)malloc(sizeof(table));       
          L.tail->next=s;
   s->next=NULL;
   strcpy(s->str,token);
   s->num=L.tail->num+1;
   L.tail=s;
   return s->num;
   }
   else
    return p->num;
        }
 else
        {
  Ltable s=(Ltable)malloc(sizeof(table));
  L.head->next=s;
  s->next=NULL;
  strcpy(s->str,token);
  s->num=1;
  L.tail=s;
  return 1;
        }

}
 
void Return(int c,int v)
{
   FILE *f;

   if((f=fopen("out.txt","a"))==NULL)
   {
 printf("cannot open this file./n");
 exit(0);
   }
      
   fputc('(',f);
   fprintf(f,"%d",c);
   fputc(',',f);
   fprintf(f,"%d",v);
   fputc(')',f);
   fputc('/n',f);
   fclose(f);
   i=0;

}


main()
{
 clrscr();
 int c,ff,i=0;
 FILE *f;
 Ltable p;
 list var,numberr;
 initlist(var);    
 initlist(numberr);
 
 do{
 Getchar();
 Getbc();
 if(Letter())//识别标识符和关键字
  {
  Concatenation();
  Getchar();
  while(Letter()||Digit())
  {
   Concatenation();Getchar();
  }
  Retract();
  c=Reserve();
  if(c==0)
  {ff=Build(var);
  Return(id,ff);
  }
  else Return(c,value);
  }
 else if(Digit())//识别常量
  {
  Concatenation();Getchar();
  while(Digit())  {Concatenation();Getchar();}
  Retract();
  ff=Build(numberr);
  Return(number,ff);
  }
 else if(character=='.')  Return(5,-1);
 else if(character==':')
  {Concatenation();Getchar();
  if(character=='=') Return(assign,-1);
  else    {Retract();
   Return(colon,-1);
   }
  }
 else if(character==';')  Return(8,-1);
 else if(character==',') Return(9,-1);
 else if(character=='(')  Return(lpar,-1);
 else if(character==')')  Return(rpar,-1);
 else if(character=='+')  Return(plus,-1);
 else if(character=='*')  Return(multiply,-1);
 else if(character=='=')  Return(colon,-1);
 else if(character=='<')
  {Concatenation();Getchar();
  if(character=='=') Return(LE,-1);
  else if(character=='>') Return(NE,-1);
  else Retract();
  Return(LT,-1);
  }
 else if(character=='>')
  {Concatenation();Getchar();
  if(character=='=') Return(EQ,-1);
  Retract();
  Return(GT,-1);
  }
 else if(character==EOF) break;
 else {printf("error");break;}
}
while(character!=EOF);
 if((f=fopen("out.txt","a"))==NULL)
  {
  printf("cannot open this file/n");
  exit(0);
  }
 
 fprintf(f,"%s",str1);//输出变量表
        p=var.head->next;
 while(p!=NULL)
  {
  fprintf(f,"%s",p->str);
  fputc('/t',f);
  fprintf(f,"%d",id);
  fputc('/t',f);
  fprintf(f,"%d",p->num);
  fputc('/n',f);
  p=p->next;
  }
       
 fprintf(f,"%s",str2); //输出常量表
 p=numberr.head->next;
 while(p!=NULL)
 {
  
  fprintf(f,"%s",p->str);
  fputc('/t',f);
  fprintf(f,"%d",number);
  fputc('/t',f);
  fprintf(f,"%d",p->num);
  fputc('/n',f);
  p=p->next;
 }
 fprintf(f,"%s",str3);//输出关键字表
 fputc('/n',f);
 while(i<10)
 {
  fprintf(f,"%s",key[i].name);
  fputc('/t',f);
  fprintf(f,"%d",key[i].c);
  fputc('/t',f);
  fprintf(f,"%d",key[i].v);
  fputc('/n',f);
  i++;
 }
 fclose(f);

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值