编译课的上机题,做了好长时间呢,和大家分享一下,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);
}