#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define NULL 0
#define LEN sizeof(struct project)
struct project /*存放代码的结构体*/
{char c;
struct project *next;
};
struct keyword /*存放保留字表*/
{char key[10];
char vc[7];
}stu[13]={{"program","(3,0)"},{"var","(4,0)"},{"procedure","(5,0)"},{"begin","(6,0)"},
{"end","(7,0)"},{"if","(8,0)"},{"then","(9,0)"},{"else","(10,0)"},{"while","(11,0)"},
{"do","(12,0)"},{"call","(13,0)"},{"integer","(14,0)"},{"real","(15,0)"}};
int n;
int j=1;/*记录标志符的个数*/
char TOKEN[20];
char DATA[10];
char identifler[100];
int time;
struct project * creat(void)/*初始化代码结构体*/
{struct project *head;
struct project *p1,*p2;
n=0;
p1=p2=(struct project *)malloc(LEN);
scanf("%c",&p1->c);
head=NULL;
while(p2->c!='#')
{n=n+1;
if(n==1) head=p1;
else p2->next=p1;
p2=p1;
p1=(struct project *)malloc(LEN);
p1->c=getchar();
}
p2->next=NULL;
return(head);
}
void lookup(void)/*查保留字表*/
{
int m=0;
while(m<13)
{
if(strcmp(stu[m].key,TOKEN)!=0) m++;
if(strcmp(stu[m].key,TOKEN)==0) {printf("%s:%s\t",stu[m].key,stu[m].vc);break;}
}
if(m>=13)
{
if(strlen(TOKEN)<10)
{
for(int t=0;TOKEN[t]!='\0';t++)
identifler[time++]=TOKEN[t];
identifler[time++]='\0';
}
else printf("***error***\t");
}
}
void main()
{
struct project *p,*p1;
int i,d;
printf("input the project:\n");
p=creat();
while(p!=NULL){
if(p->c==' ') p=p->next;
if(p->c=='\n') p=p->next;
if(p->c=='#') break;
if(p->c>='0'&&p->c<='9')
{
DATA[0]=p->c;
p=p->next;d=1;
while(p->c>='0'&&p->c<='9')
{
DATA[d]=p->c;d++;
p=p->next;
}
if((p->c>='a'&&p->c<='z')||(p->c>='A'&&p->c<='Z'))
{
printf("**error**\t");p=p->next;
while((p->c>='a'&&p->c<='z')||(p->c>='A'&&p->c<='Z')||(p->c>='0'&&p->c<='9'))
p=p->next;
}//如果数字后直接跟字母则为错误
else printf("%s:(2,%s)\t",DATA,DATA);
}
if((p->c>='a'&&p->c<='z')||(p->c>='A'&&p->c<='Z'))
{
TOKEN[0]=p->c;
p=p->next;i=1;
while((p->c>='a'&&p->c<='z')||(p->c>='A'&&p->c<='Z')||(p->c>='0'&&p->c<='9'))
{
TOKEN=p->c;i++;
p=p->next;
}
TOKEN='\0';
lookup();
}
else
switch(p->c)
{
case'<':p=p->next;
if(p->c=='=') {printf("<=:(24,0)\t");p=p->next;}
else if(p->c=='>') {printf("<>:(28,0)\t");p=p->next;}
else printf("<:(23,0)\t");
break;
case'=':printf("=:(27,0)\t");p=p->next;break;
case'>':p=p->next;
if(p->c=='=') {printf(">=:(26,0)\t");p=p->next;}
else printf(">:(25,0)\t");break;
case'+':printf("+:(16,0)\t");p=p->next;break;
case'-':printf("-:(17,0)\t");p=p->next;break;
case'*':printf("*:(18,0)\t");p=p->next;break;
case'/':p=p->next;
if(p->c=='*')
{
do{p1=p;p=p1->next;}while(p1->c!='*'||p->c!='/');
printf("/*注释*/\t");
p=p->next;
}
else printf("/:(19,0)\t");break;
case'~':printf("~:(20,0)\t");p=p->next;break;
case':':printf("::(21,0)\t");p=p->next;break;
case';':printf(";:(30,0)\t");p=p->next;break;
case'.':printf(".:(31,0)\t");p=p->next;break;
case',':printf(",:(32,0)\t");p=p->next;break;
case'(':printf("(:(33,0)\t");p=p->next;break;
case')':printf("):(34,0)\t");p=p->next;break;
default:printf("***error***\t");p=p->next;
}
}
printf("\n\n****************标识符表******************\n\n");
printf("序列\t名字\t地址\n");
int f=0;
int t=1;
while(f<time)
{
printf(" %d \t",t++);
while(identifler[f]!='\0')
{ printf("%c",identifler[f]);f++;}
f++;
printf("\t 0 \n");
}
}
上次还没完善的词法分析程序,这次基本上完善好了,达到老师的要求了!!!!!
也许还有不足的地方,希望大家所提意见。 |