www.pudn.com > express.rar > Expression.c
#include "stdio.h"
#include "ctype.h"
#define LEN sizeof(struct entry)
char Buffer[256];
int state = 0;
int lineno=1;
char token[128];
int index=0;
int flag=0; /*0代表字符串,1代表数字,2代表运算符*/
char* keyword[]={"int","float","short","char","long","break","case","const",
"switch","continue","default","do","while","double","else","enum",
"extern","for","goto","if","register","return","signed","sizeof",
"static","struct","typedef","union","unsigned","void","volatile",
"auto"};
FILE *out;
struct entry *headOfEntry;
/*符号表用链表*/
struct entry
{
int attr; /*记号*/
char *value; /*记号值*/
struct entry *next; /*指向下一结点指针*/
};
/*初始化符号链表*/
void entryinit()
{
headOfEntry=(struct entry *)malloc(LEN);
headOfEntry->next=NULL;
}
/*查询符号链表*/
int LookupEntry(char *c) /*字符串c是否存在于符号链表项中*/
{
/*若存在则返回1*/
struct entry *e; /*若不存在则返回0*/
int boolean=0;
e=headOfEntry->next;
while(e!=NULL)
{
if(strcmp(e->value,c)==0)
{
boolean=1;
printf("\nvalue is %s and c is %s\n",e->value,c);
return boolean;
}
e=e->next;
}
return boolean;
}
/*向符号链表中加入结点*/
void addToEntry(int f,char *symbol)
{
/*char *c;*/
struct entry *p;
struct entry *new;
p = headOfEntry;
new = (struct entry *)malloc(LEN);
if(f==0)
new->attr=0;
else if(f==1)
new->attr=1;
new->value=strdup(symbol);
new->next=NULL;
while(p->next!=NULL)
{
p = p->next;
}
p->next = new;
}
/*初始化输出文件*/
void outFile(char *outfile)
{
if((out=fopen(outfile,"w"))==NULL)
{
printf("\nCan not open output file!\n");
exit(0);
}
}
void output(int f)
{
int i;
char *rec;
rec=token;
if(f==0)
{
for(i=0;i<31;i++)
{
if(strcmp(keyword[i],rec)==0)
{
printf("Line %d : ",lineno);
fprintf(out,"Line %d : ",lineno);
printf("( IDN , %s )\n",rec);
fprintf(out,"( IDN , %s )\n",rec);
addToEntry(0,rec);
rec="";
return;
}
}
printf("Line %d : ",lineno);
fprintf(out,"Line %d : ",lineno);
printf("( id , %s )\n",token);
fprintf(out,"( id , %s )\n",token);
addToEntry(1,rec);
return;
}
else if(f==1)
{
printf("Line %d : ",lineno);
fprintf(out,"Line %d : ",lineno);
printf("( num , %s )\n",token);
fprintf(out,"( num , %s )\n",token);
}
else if(f==2)
{
printf("Line %d : ",lineno);
fprintf(out,"Line %d : ",lineno);
printf("( op , %s )\n",token);
fprintf(out,"( op , %s )\n",token);
}
}
void analyse(char *infile)
{
FILE *fp;
char recieve;
char ch='#';
int forward = -1;
int temp,temp1;
int pointer=0;
if((fp=fopen(infile,"r"))==NULL)
{
printf("\nCan not open output file!\n");
exit(0);
}
do
{
recieve = fgetc(fp);
Buffer[pointer] = recieve;
pointer++;
if(pointer==127)
{
Buffer[pointer] = EOF;
break;
}
}while(recieve!=EOF); /*初始装入第一部分*/
while(1)
{
forward = forward + 1;
if(Buffer[forward] == EOF)
{
if(forward==127)
{
/*重装第二部分*/
pointer = 128;
do
{
recieve = fgetc(fp);
Buffer[pointer] = recieve;
pointer++;
if(pointer==255)
{
Buffer[pointer] = EOF;
break;
}
}while(recieve!=EOF);
forward = forward + 1;
}
else if(forward==255)
{
/*重装第一部分*/
pointer = 0;
do
{
recieve = fgetc(fp);
Buffer[pointer] = recieve;
pointer++;
if(pointer==255)
{
Buffer[pointer] = EOF;
break;
}
}while(recieve!=EOF);
forward = 0;
}
else
{
/*终止词法分析*/
break;
}
}
switch(state)
{
case 0: ch = Buffer[forward];
if(ch==' '||ch=='\t')
state = 0;
else if(ch=='\n')
{
lineno++;
state = 0;
}
else if(isalpha(ch))
{
index=0;
token[index]=ch;
index++;
state=1;
}
else if(isdigit(ch))
{
index=0;
token[index]=ch;
index++;
state=2;
}
else if(ch=='#'||ch=='('||ch==')'||ch=='['||ch==']'||ch=='{'||ch=='}'||ch=='.'||ch=='\\'
||ch==';'||ch=='\''||ch=='?'||ch=='"'||ch=='%'||ch==','||ch==':')
{
index=0;
token[index]=ch;
index++;
flag=2;
token[index]='\0';
index++;
output(flag);
state=0;
}
else if(ch=='/')
{
state=3;
index=0;
token[index]=ch;
index++;
}
else if(ch=='+'||ch=='-'||ch=='*'||ch=='>'||ch=='<'||ch=='='||ch=='!')
{
state=5;
index=0;
token[index]=ch;
index++;
}
else if(ch=='|')
{
state=11;
index=0;
token[index]=ch;
index++;
}
else if(ch=='&')
{
state=12;
index=0;
token[index]=ch;
index++;
}
else
{
printf("Unprocessed char is %c\n",ch);
fprintf(out,"Unmatched char is %c\n",ch);
state = 0;
}
break;
case 1: ch = Buffer[forward];
if(isalnum(ch))
{
token[index]=ch;
index++;
state = 1;
}
else
{
state = 0;
token[index]='\0';
index++;
flag=0;
output(0);
forward = forward - 1;
}
break;
case 2: ch = Buffer[forward]; /*寻找常数*/
if(isdigit(ch))
{
token[index]=ch;
index++;
state=2;
}
else if(ch=='.')
{
state=6;
}
else{
state=0;
forward = forward - 1;
token[index]='\0';
index++;
flag=1;
output(flag);
}
break;
case 3: ch = Buffer[forward]; /*寻找注释符的前半部分*/
if(ch=='*')
{
state=4;
}
else if(ch=='=')
{
state=0;
token[index]=ch;
index++;
token[index]='\0';
index++;
flag=2;
output(flag);
}
else{
token[index]='\0';
index++;
flag=2;
output(flag);
state=0;
forward = forward - 1;
}
break;
case 4: ch = Buffer[forward];
temp = forward - 1;
if(ch!='/') /*寻找注释符后半部分*/
state=4;
else{
if(Buffer[temp]=='*')
state=0;
else{
printf("Remark symbol error!\n");
state=0;
}
}
break;
case 5: ch = Buffer[forward];
if(ch=='=')
{
state=0;
token[index]=ch;
index++;
token[index]='\0';
index++;
flag=2;
output(flag);
}
else if(ch=='+')
{
state=0;
token[index]=ch;
index++;
token[index]='\0';
index++;
flag=2;
output(flag);
}
else if(ch=='-')
{
state=0;
token[index]=ch;
index++;
token[index]='\0';
index++;
flag=2;
output(flag);
}
else{
token[index]='\0';
index++;
flag=2;
output(flag);
state=0;
forward = forward - 1;
}
break;
case 6: ch = Buffer[forward];
temp = forward - 1;
if(isdigit(ch))
{
token[index]=Buffer[temp]; /*将'.'放入token*/
index++;
token[index]=ch; /*将该数字放入token*/
index++;
state=7;
}
else{
token[index]='\0'; /*输出前面的数字*/
index++;
flag=1;
output(flag);
index=0; /*输出'.'*/
token[index]=Buffer[temp];
token[index]='\0';
index++;
flag=2;
output(flag);
forward = forward - 1;
state=0;
}
break;
case 7: ch = Buffer[forward];
if(isdigit(ch))
{
state=7;
token[index]=ch;
index++;
}
else if(ch=='E'||ch=='e'){ /*找到表示指数的E或e*/
state=8;
temp=forward; /*temp用于保存指向E或e的指针*/
}
else{
token[index]='\0';
index++;
flag=1;
output(flag);
state=0;
forward = forward - 1;
}
break;
case 8: ch = Buffer[forward];
/*temp1=q;*/
if(ch=='+'||ch=='-') /*如果E或e后面跟着+或-*/
{
temp1=forward; /*用temp1保存指向+或-的指针*/
state=9;
}
else if(isdigit(ch)){ /*如果E或e后面跟着一个数字*/
state=10;
token[index]=Buffer[temp]; /*将E或e放入token*/
index++;
token[index]=ch; /*将该数字放入token*/
index++;
}
else{ /*如果E或e后面跟着其他字符*/
token[index]='\0'; /*输出前面的数*/
index++;
flag=1;
output(flag);
index=0; /*将E或e放入token,回退字符,转入状态1*/
token[index]=Buffer[temp];
index++;
forward = forward - 1;
state=1; /*转入状态1,判断字符串*/
}
break;
case 9: ch = Buffer[forward];
if(isdigit(ch)) /*若E或e后面的+或-的后面跟一个数字*/
{
token[index]=Buffer[temp]; /*将E或e和+或-放入token*/
index++;
/*printf("\ntemp is %c\n",temp->ch);*/
token[index]=Buffer[temp1];
index++;
/*printf("\ntemp1 is %c\n",temp1->ch);*/
token[index]=ch; /*将该数字放入token*/
index++;
state=10; /*转入状态10*/
}
else{
token[index]='\0'; /*输出前面的数*/
index++;
flag=1;
output(flag);
index=0; /*输出E或e*/
token[index]=Buffer[temp];
index++;
token[index]='\0';
index++;
flag=0;
output(flag);
index=0;
token[index]=Buffer[temp1]; /*将+或-放入token*/
index++;
if(ch=='=') /*判断+=或-=*/
{
token[index]=ch;
index++;
token[index]='\0';
index++;
flag=2;
output(flag);
state=0;
}
else{
token[index]='\0';
index++;
flag=2;
output(flag);
forward = forward - 1;
state=0;
}
}
break;
case 10: ch = Buffer[forward];
if(isdigit(ch))
{
token[index]=ch;
index++;
state=10;
}
else{
token[index]='\0';
index++;
flag=1;
output(flag);
forward = forward - 1;
state=0;
}
break;
case 11: ch = Buffer[forward];
if(ch=='|')
{
token[index]=ch;
index++;
token[index]='\0';
index++;
flag=2;
output(flag);
state = 0;
}
else
{
token[index]='\0';
index++;
flag=1;
output(flag);
forward = forward - 1;
state=0;
}
break;
case 12: ch = Buffer[forward];
if(ch=='&')
{
token[index]=ch;
index++;
token[index]='\0';
index++;
flag=2;
output(flag);
state = 0;
}
else
{
token[index]='\0';
index++;
flag=1;
output(flag);
forward = forward - 1;
state=0;
}
break;
}
}
printf("\nThe end!\nThe number of lines in this source file is %d.\n",lineno-1);
fprintf(out,"\nThe end!\nThe number of lines in this source file is %d.\n",lineno-1);
fclose(fp);
}
void print()
{
struct entry *q;
q=headOfEntry;
printf("The followed is symbol list:\n");
fprintf(out,"The followed is symbol list:\n");
while(q->next!=NULL)
{
printf("(%d,%s)\n",q->next->attr,q->next->value);
fprintf(out,"(%d,%s)\n",q->next->attr,q->next->value);
q=q->next;
}
}
main()
{
char *in;
char *outf;
printf("Enter the name of Source file:\n");
scanf("%s",in);
printf("Enter the name of output file:\n");
scanf("%s",outf);
entryinit();
outFile(outf);
analyse(in);
print();
fclose(out);
getch();
}