(4)E->(A)
(5)A->d
(6)A->num
(7)B->{d=C}
(8)C->A+A
(9)C->A-A
(10)C->A*A
(11)C->A/A
(12)C->A
*////////////////////////////////////////
intlineno=1;
charch;
intanltable[22][22]={
/*S*/{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
/*if*/{0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*E*/{0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*then*/{0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
/*B*/{0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
/*else*/{0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
/*(*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*)*/{0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*>*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*<*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*=*/{0,0,0,0,0,0,0,0,0,0,0,1,1,1,3,0,0,0,0,0,0,0},
/*A*/{0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,0,2,3,3,3,3,0},
/*d*/{0,0,0,0,0,0,0,2,2,2,3,0,0,0,0,0,2,2,2,2,2,0},
/*num*/{0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,2,2,2,2,2,0},
/*C*/{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0},
/*{*/{0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0},
/*}*/{0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
/*+*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*_*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/***/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*/*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*#*/{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
};//0-error,1=<,2=>,3==
charallname[30][30];//单词全名
charout[30][30];//保存单词简称
intlength;
structatt
{//名字表类型
stringsname;
charselect;
charaddre;
};
attattname[40];//名字表
typedefstructSqStack
{
char*base;
char*top;
intstacksize;
}SqStack;//栈定义
voidInitStack(SqStack&S)
{//栈初始化
S.base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));//分配存储空间
if(!
S.base)
exit(OVERFLOW);//为栈S分配存储空间失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
intpush(SqStack&S,charch)//将元素e插入到栈S中,成为新的栈顶元素
{
if(S.top-S.base>S.stacksize)//判定栈是否满
{
S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT*sizeof(char)));
if(!
S.base)
{
printf("分配存储单元失败.\n");//存储单元分配失败
exit(OVERFLOW);
}
S.top=S.base+S.stacksize;//指明栈顶指针的基址
S.stacksize+=STACKINCREMENT;//指明栈的空间大小
}//endofif
*S.top++=ch;//先将e送入栈顶指针所指向的单元,再将栈顶指针加1
return(OK);
}//endofPush()subfunction
intpop(SqStack&S,char&ch)
{//栈顶元素出栈
if(S.top==S.base)
{
printf("溢出");
return(ERROR);
}
ch=*--S.top;
return(OK);
}
chargettop(SqStackS)
{//返回栈顶元素
if(S.top==S.base)cout<<"栈空,出错"<chare;
e=*(S.top-1);
returne;
}
intgetnum(charcc)
{//返回元素在优先表中的位置
switch(cc)
{
case'S':
return0;break;
case'i':
return1;break;
case'E':
return2;break;
case't':
return3;break;
case'B':
return4;break;
case'e':
return5;break;
case'(':
return6;break;
case')':
return7;break;
case'>':
return8;break;
case'<':
return9;break;
case'=':
return10;break;
case'A':
return11;break;
case'd':
return12;break;
case'n':
return13;break;
case'C':
return14;break;
case'{':
return15;break;
case'}':
return16;break;
case'+':
return17;break;
case'-':
return18;break;
case'*':
return19;break;
case'/':
return20;break;
case'#':
return21;break;
default:
return88;
}
}
intjudge(char*string)
{//判断是否是关键字
char*keywords[1000]={"if","then","else"};
for(inti=0;i<=2;i++)
{
if(!
strcmp(string,*(keywords+i)))
{
return1;
}
}
return0;
}
intanalysis(ifstream&fin,ofstream&fout)//词法分析程序,用引用传递参数
{
chartemp[10];//临时存放已读入但无法判断类型的字符
intj=0;
intou=0;
intna=0;
while(fin.get(ch))
{
if(ch=='\n'){lineno+=1;}
elseif(ch=='\t'||ch==''){}//排除制表、空格字符
elseif(isalpha(ch))//当前输入符为字母
{
while(isalpha(ch)||isdigit(ch))
{
temp[j]=ch;
j++;
fin.get(ch);
}
temp[j]='\0';//标志字符串结束
j=0;
if(judge(temp))//判断是否为关键字
{
memcpy(allname[na],temp,10);
attname[na].sname=allname[na];
attname[na].select=allname[na][0];
memcpy(out[ou],temp,10);ou++;
fout<<"("<na++;
}
else
{
memcpy(allname[na],temp,10);
attname[na].sname=allname[na];
attname[na].select='d';
memcpy(out[ou],temp,10);ou++;
fout<<"("<na++;
}
fin.seekg(-1,ios:
:
cur);//回退1个字符
}
elseif(isdigit(ch))
{
while(isdigit(ch))
{
temp[j]=ch;
j++;
fin.get(ch);
}
temp[j]='\0';//标志字符串结束
j=0;
memcpy(allname[na],temp,10);
attname[na].sname=allname[na];
attname[na].select='n';
memcpy(out[ou],temp,10);ou++;
fout<<"("<na++;
fin.seekg(-1,ios:
:
cur);//回退一个字符
}
elseif(ch=='=')
{
allname[na][0]=ch;
attname[na].sname=allname[na];
attname[na].select=ch;
memcpy(out[ou],"=",10);ou++;
fout<<"("<na++;
}
elseif(ch=='+')
{
allname[na][0]=ch;
attname[na].sname=allname[na];
attname[na].select=ch;
memcpy(out[ou],"+",10);ou++;
fout<<"("<na++;
}
elseif(ch=='-')
{
allname[na][0]=ch;
attname[na].sname=allname[na];
attname[na].select=ch;
memcpy(out[ou],"-",10);ou++;
fout<<"("<na++;
}
elseif(ch=='*')
{
allname[na][0]=ch;
attname[na].sname=allname[na];
attname[na].select=ch;
memcpy(out[ou],"*",10);ou++;
fout<<"("<na++;
}
elseif(ch=='/')
{
allname[na][0]=ch;
attname[na].sname=allname[na];
attname[na].select=ch;
memcpy(out[ou],"/",10);ou++;
fout<<"("<na++;
}
elseif(ch=='(')
{allname[na][0]=ch;attname[na].sname=allname[na];attname[na].select=ch;fout<<"("<elseif(ch==')')
{allname[na][0]=ch;attname[na].sname=allname[na];attname[na].select=ch;fout<<"("<elseif(ch=='{')
{allname[na][0]=ch;attname[na].sname=allname[na];attname[na].select=ch;fout<<"("<elseif(ch=='}')
{
allname[na][0]=ch;
attname[na].sname=allname[na];
attname[na].select=ch;
fout<<"("<na++;
}
elseif(ch=='<')
{
allname[na][0]=ch;
attname[na].sname=allname[na];
attname[na].select=ch;
memcpy(out[ou],"<",10);ou++;
fout<<"("<na++;
}
elseif(ch=='>')
{
allname[na][0]=ch;
attname[na].sname=allname[na];
attname[na].select=ch;
memcpy(out[ou],">",10);ou++;
fout<<"("<na++;
}
elseif(ch=='#')
{
out[ou][0]='#';ou++;
}
else
{
fout<<"无法识别字符"<<"\""<return0;
}
}
ch='\0';
attname[na].select='#';
out[ou][0]='#';ou++;
length=na;
return1;
}
voidprintstack(SqStack&S,intnaa,intty,ofstream&fout)
{
chartemp[40][20];
for(intk=0;k<40;k++)
{
for(intt=0;t<20;t++)
temp[k][t]=NULL;
}
intte=0;
inti=0,j=0;
intnu=0;
char*ku;
ku=S.base;
i=naa+1;
char*contrl;
contrl=S.base;
while(contrl!
=S.top)
{
if(*contrl!
='1')
{
if(*contrl=='i')
{fout<<"if";nu=nu+2;}
elseif(*contrl=='t')
{fout<<"then";nu=nu+4;}
elseif(*contrl=='e')
{fout<<"else";nu=nu+4;}
else
{fout<<*contrl;nu++;}
}
contrl++;
}
fout<<"\t\t\t";
for(i;i<=length;i++)
{
if(gettop(S)=='S')
fout<<"#";
else
fout<}
if(gettop(S)=='S')
fout<<"#";
else
fout<te++;
fout<}
intlaynax(ofstream&f)
{
SqStackS;
InitStack(S);
push(S,'#');
charcch,tempch;
intnaa=0,over=1,go;
intfront=0,last=0,choose=0;
while(over)
{
//getchar();
front=getnum(gettop(S));
last=getnum(attname[naa].select);
go=naa;
//cout<choose=anltable[front][last];
if(choose==1)
{
push(S,'1');
push(S,attname[naa].select);
printstack(S,go,1,f);
naa++;
}
elseif(choose==3)
{
push(S,attname[naa].select);
printstack(S,go,1,f);
naa++;
}
elseif(choose==2)
{
inta=0;
l1:
pop(S,cch);
if(cch=='1')
{
if(tempch=='i')
{
push(S,'S');
printstack(S,go,3,f);
over=0;
}
elseif(tempch=='(')
{
push(S,'E');
printstack(S,naa-1,3,f);
}
elseif(tempch=='d')
{
front=getnum(gettop(S));
last=getnum('A');
choose=anltable[front][last];
if(choose==1){push(S,'1');}
push(S,'A');
a=1;
printstack(S,naa-1,3,f);
}//cout<<"归约了A"<elseif(tempch=='n')
{
front=getnum(gettop(S));
last=getnum('A');
choose=anltable[front][last];
if(choose==1){push(S,'1');}
push(S,'A');
a=1;
printstack(S,naa-1,3,f);
}//cout<<"归约了A"<elseif(tempch=='{')
{
push(S,'B');
a=1;
printstack(S,go-1,3,f);
}//cout<<"归约了B"<elseif(tempch=='A')
{
push(S,'C');
a=1;
printstack(S,go-1,3,f);