📄 yufafenxi.cpp
字号:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#define max 50
#define NULL 0
#define ERROR -1
int k=0;
int value=0;
int temp=0;
int flage0=1;
int flage1=0;
int flage2=0;
int count=-1;
int bdsNo=0;
struct Recode
{
char idname[20];
int idNo;
}id[20],newtemp[20];//标识符表结构
struct idtab
{
char name[20];
int type;//整型——2;字符型——1;
}bds[100];
//////////////////////////////////////////////栈//////////////////////////////////////////////////
struct stack
{
int *base;
int *top;
int stacksize;
};
void Initstack(struct stack *p)
{
p->base=(int*)malloc(max*sizeof(int));
p->top=p->base;
p->stacksize=max;
}//顺序表实现栈的初始化
void push(struct stack *p,int e)
{
if((p->top-p->base)>=max)
{
p->base=(int*)realloc(p->base,(p->stacksize+1)*sizeof(int));
p->top=p->base+p->stacksize;
p->stacksize+=1;
}
*p->top++=e;
}//顺序表实现进栈
int pop(struct stack *p)
{
int e;
if(p->top==p->base)
return(-1);
e=*--p->top;
return(e);
}//顺序表实现出栈
int Gettop(struct stack *s)
{
int e;
int *q;
if(s->top!=s->base)
{q=s->top;
e=*(q-1);}
return(e);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void Baoliuzi(char take[])
{
char *keyword[13]={"program","var","procedure","begin","end","if","then","else","while","do","call","integer","real"};
int i=0;
for(int j=0;j<13;j++)
{
if(strcmp(take,keyword[j])==0)
switch(j)
{
case 0:printf("program:(3,0)\n");flage0=0;break;
case 1:printf("var:(4,0)\n");flage0=0;break;
case 2:printf("procedure:(5,0)\n");flage0=0;break;
case 3:printf("begin:(6,0)\n");flage0=0;break;
case 4:printf("end:(7,0)\n");flage0=0;break;
case 5:printf("if:(8,0)\n");flage0=0;break;
case 6:printf("then:(9,0)\n");flage0=0;break;
case 7:printf("else:(10,0)\n");flage0=0;break;
case 8:printf("while:(11,0)\n");flage0=0;break;
case 9:printf("do:(12,0)\n");flage0=0;break;
case 10:printf("call:(13,0)\n");flage0=0;break;
case 11:printf("integer:(14,0)\n");flage0=0;break;
case 12:printf("real:(15,0)\n");flage0=0;break;
}//switch
}//for循环结束
if(flage0==1)
{
strcpy(id[temp].idname,take);
for(int x=0;x<temp;x++)
{
if(strcmp(id[x].idname,id[temp].idname)==0)
{
flage1=1;
flage2=x;
}
}
if(flage1==0)
{
value++;
id[temp].idNo=value;
printf("%s:(1,%d)\n",id[temp].idname,id[temp].idNo);
strcpy(bds[bdsNo].name,id[temp].idname);
bds[bdsNo].type=1;
temp++;bdsNo++;
}
else if(flage1==1)
{
printf("%s:(1,%d)\n",id[flage2].idname,id[flage2].idNo);
strcpy(bds[bdsNo].name,id[temp].idname);
bds[bdsNo].type=1;
bdsNo++;
}
}
flage0=1;
}
int Precede(int aa,int bb)
{
int cc;
if(bb==17&&aa!=33)
cc=-1;
else if(aa==17&&bb!=33)
cc=-1;
else if(bb==33&&aa!=17)
cc=1;
else if(aa==33&&bb!=17)
cc=1;
else if(aa==17&&bb==33)
cc=0;
else
{
if(aa>bb||aa==bb)cc=1;
if(aa<bb)cc=-1;
}
return(cc);
}
void ncount()
{
count--;
}
void bdshi ( )
{//OP为运算符集合。
struct stack optr;
struct stack opnd;
Initstack(&optr);
push (&optr,-1);
Initstack(&opnd);
int w=0;
//用其在bds[]中的序号来标记
while(w!=bdsNo||Gettop(&optr)!=-1)
{
if((bds[w].type==1)||(bds[w].type==2)) //判断W是否 是运算符
{
push(&opnd,w);w++;
} //不是运算符则进栈
else switch (Precede(bds[Gettop(&optr)].type, bds[w].type))
{
case -1:// 新输入的算符 w 优先级高,w 进栈
push(&optr, w ); w++; break;
case 0: // 去括号并接收下一字符
int x;x=pop(&optr);w++; break;
case 1: //新输入的算符优先级低,取栈顶算符 运算
int t;
t=pop(&optr);
int b;
b=pop(&opnd);
int a;
a=pop(&opnd);
ncount();
if(a<(-1)&&b>=0)
printf("(%s,T%d,%s,T%d)",bds[t].name,-a,bds[b].name,-count);
if(a>=0&&b<(-1))
printf("(%s,%s,T%d,T%d)",bds[t].name,bds[a].name,-b,-count);
if(a<(-1)&&b<(-1))
printf("(%s,T%d,T%d,T%d)",bds[t].name,-a,-b,-count);
if(a>=0&&b>=0)
printf("(%s,%s,%s,T%d)",bds[t].name,bds[a].name,bds[b].name,-count);
printf("\n");
push(&opnd,count);
break;
}
}
}
void main()
{
FILE *fp;
if((fp=fopen("input.txt","r"))==NULL)
{
printf("cannot open this file\n");
exit(0);
}
char s[500];
char token[20];
int i=0;
while(!feof(fp))
{
fread(&s[i],sizeof(char),1,fp);
i++;
}
s[i++]='\0';//把文件内容读到s数组中
char ch;
k=0;
ch=s[k];
while(ch!='\0')
{
int flage=1;
if(ch>='a'&&ch<='z')
{
int p=0;
while((ch>='a'&&ch<='z')&&(flage==1)||(ch>='0'&&ch<='9'))
{
token[p++]=ch;
ch=s[++k];
if(p==8)
{
int z=1;
do
{
k++;
ch=s[k];
if(ch!=' '||ch!='\n')
z=0;
}
while(z==1);
flage=0;
}
}
token[p++]='\0';
Baoliuzi(token);
if(ch==' ')
{
k++;ch=s[k];
}
}//保留字
else if(ch==' ')
{
k++;ch=s[k];
}//处理空格
else if(ch=='\n')
{
k++;ch=s[k];
}//处理回车
else if(ch>='0'&&ch<='9')
{
int No=0;
if(s[k+1]>='a'&&s[k+1]<='z')
{
int flag=1;
printf("**error(1)**\n");
do
{
k++;
ch=s[k];
if(ch!='\n'||ch!=' ')
flag=0;
}while(flag==1);
k++;ch=s[k];
}
else
{
int ei=0;
while(ch>='0'&&ch<='9')
{
No=No*10+(ch-'0');
bds[bdsNo].name[ei++]=(char)ch;
ch=s[++k];
}
printf("%d:(2,%d)\n",No,No);
bds[bdsNo].type=2;bdsNo++;
if(ch==' ')
{
k++;ch=s[k];
}
}
}//数字
else
{
switch(ch)
{
case '+':
{
printf("+:(17,0)\n");bds[bdsNo].name[0]='+';
bds[bdsNo].type=18;bdsNo++;break;
}
case '-':
{
printf("-:(18,0)\n");bds[bdsNo].name[0]='-';
bds[bdsNo].type=18;bdsNo++;break;
}
case '*':
{
printf("*:(19,0)\n");bds[bdsNo].name[0]='*';
bds[bdsNo].type=19;bdsNo++;break;
}
case '/':
{
char c;
c=s[k+1];
if(c!='*')
{
printf("/:(20,0)\n");bds[bdsNo].name[0]='/';
bds[bdsNo].type=19;bdsNo++;break;
}
else
{
k++;
ch=s[k];
int fl=1;
do
{
do
{
k++;
ch=s[k];
}while(ch!='*');
if(s[k+1]=='/')
{
k++;ch=s[k];fl=0;
}
else
{
do
{
k++;
ch=s[k];
}while(ch!='*');
if(s[k+1]=='/')
{
k++;ch=s[k];fl=0;
}
}
if(s[k+1]=='\0')
fl=0;
}while(fl==1);
break;
}
}
case '~':printf("~:(21,0)\n");break;
case '<':
{
char c;
c=s[k+1];
if(c!='=')
{
printf("<:(22,0)\n");
break;
}
else if(c=='>')
{
printf("<>:(27,0)\n");
break;
}
else {
printf("<=:(23,0)\n");
k++;ch=s[k];
break;
}
}
case '>':
{
char c;c=s[k+1];
if(c!='=')
{
printf(">:(24,0)\n");
break;
}
else
{
printf(">=:(25,0)\n");
k++;
ch=s[k];
break;
}
}
case '=':
{
printf("=:(16,0)\n");
bds[bdsNo].name[0]='=';
bds[bdsNo].type=16;
bdsNo++;break;
}
case ':':
{
char c;c=s[k+1];
if(c=='=')
{
printf(":=:(28,0)\n");
k++;ch=s[k];
break;
}
else
{
printf("::(34,0)\n");
break;
}
}
case ';':
{
printf(";:(29,0)\n");
break;
}
case '.':
{
printf(".:(30,0)\n");
break;
}
case ',':
{
printf(",:(31,0)\n");
break;
}
case '(':
{
printf("(:(32,0)\n");
bds[bdsNo].name[0]='(';
bds[bdsNo].type=17;
bdsNo++;break;
}
case ')':
{
printf("):(33,0)\n");
bds[bdsNo].name[0]=')';
bds[bdsNo].type=33;
bdsNo++;
break;
}
default:
{
if(s[k+1]!='\0'){
printf("**error(1)**\n");
break;
}
else break;
}
}//switch
k++;ch=s[k];
}//处理符号
}
printf("\n");
bdshi();
fclose(fp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -