📄 编译原理试验2.cpp
字号:
return 0;
}
else if(sentence[sen[sentencerec-1]].act=='r')
{
outputerror(6,"","repeat");
return 0;
}
}
else if(sentence[sen[sentencerec-2]].act=='b')
{
sentencerec-=2;
if(sentencerec==0)
{
searchchar(tow);
if(line[position]=='.')
{
position++;
if(searchchar(tow)==1)
{
output[outputrec].output1="sys";
output[outputrec].output2="-";
output[outputrec].output3="-";
output[outputrec].output4="-";
outputrec++;
return 1;
}
}
else return 0;
}
}
}
else
{
if(setvalue(tow,temp,sen)==0) return 0;//赋值表达式
if(sentence[sen[sentencerec-1]].act!='b')
{
sen[sentencerec]=100;
sentencerec++;
}
}//else
for(;;)//完成赋值语句后处理栈
{
if(sen[sentencerec-1]!=100||sentence[sen[sentencerec-2]].act=='r'
||sentence[sen[sentencerec-2]].act=='b')
break;
else if(sentencerec!=0)
{
switch(sentence[sen[sentencerec-2]].act)
{
case 't'://then
if(sentence[sen[sentencerec-3]].act!='i')
{
outputerror(6,"if","then");
return 0;
}
for(i=0;i<sentence[sen[sentencerec-3]].truesum;i++)
output[sentence[sen[sentencerec-3]].trueexit[i]].Tnum4=sentence[sen[sentencerec-2]].entry;
int k;
searchchar(tow);
for(k=position;!(line[k]=='e'&&line[k+1]=='l'&&line[k+2]=='s'&&line[k+3]=='e')&&k<2;k++);
for(i=1;i<sentencerec-3&&sentence[sen[i]].act!='w';i++);
if(i!=sentencerec-3&&k!=2)
{
output[outputrec].output1="j";
output[outputrec].output2="-";
output[outputrec].output3="-";
output[outputrec].output4="j";
output[outputrec].Tnum4=sentence[sen[i]].entry;
outputrec++;
}
if(k!=2)
{
if(i==sentencerec-3)//then的跳转
{
output[outputrec].output1="j";
output[outputrec].output2="-";
output[outputrec].output3="-";
output[outputrec].output4="j";
sentence[sen[sentencerec-3]].then=outputrec;//记下四元式号码,跳转到else块的后一句
outputrec++;
}
sentencerec-=2;
}
else
{
sen[sentencerec-3]=100;
sentencerec-=2;
}
break;
case 'l'://else
if(sentence[sen[sentencerec-3]].act!='i')
{
outputerror(6,"if","else");
return 0;
}
for(i=0;i<sentence[sen[sentencerec-3]].falsesum;i++)
output[sentence[sen[sentencerec-3]].falseexit[i]].Tnum4=sentence[sen[sentencerec-2]].entry;
if(sentence[sen[sentencerec-3]].then!=0)//then的跳转
{
output[sentence[sen[sentencerec-3]].then].Tnum4=outputrec;
}
sen[sentencerec-3]=100;
sentencerec-=2;
break;
case 'd'://do
for(i=0;i<sentence[sen[sentencerec-3]].truesum;i++)
output[sentence[sen[sentencerec-3]].trueexit[i]].Tnum4=sentence[sen[sentencerec-2]].entry;
output[outputrec].output1="j";
output[outputrec].output2="-";
output[outputrec].output3="-";
output[outputrec].output4="j";
output[outputrec].Tnum4=sentence[sen[sentencerec-3]].entry;
outputrec++;
for(i=1;i<(sentencerec-3)&&sentence[sen[i]].act!='w';i++);
if(i!=sentencerec-3)
{
for(k=0;k<sentence[sen[sentencerec-3]].falsesum;k++)
output[sentence[sen[sentencerec-3]].falseexit[k]].Tnum4=sentence[sen[i]].entry;
}
else
{
for(i=0;i<sentence[sen[sentencerec-3]].falsesum;i++)
output[sentence[sen[sentencerec-3]].falseexit[i]].Tnum4=outputrec;
}
sen[sentencerec-3]=100;
sentencerec-=2;
break;
default:cout<<"编译错误。\n";
}//switch
}//for
}
}//for
}//begin_end
int setvalue(ifstream & tow,char temp[],int sen[])
{
int j;
for(j=1;strcmp(temp,record[j].content)!=0&&j<record1;j++);
if(j==record1)//标识符是关键字
{
outputerror(11,"repeat","until");
return 0;
}
else if(record[j].define==0)
{
outputerror(2,"","");
return 0;
}
if(record[j].type==1||record[j].type==2) //当变量为字符型或布尔型时
{
outputerror(5,"","");
return 0;
}
searchchar(tow);
if(!(line[position]==':'&&line[position+1]=='='))
{
outputerror(10,"","");
return 0;
}
position+=2;
searchchar(tow);
if(!((line[position]>=65&&line[position]<=90||line[position]>=97&&line[position]<=122)||
(line[position]>=48&&line[position]<=57)))
{
outputerror(10,"","");
return 0;
}
char str[30];
j=0;
for(;;)
{
for(;(line[position]>=65&&line[position]<=90||line[position]>=97&&line[position]<=122)||
(line[position]>=48&&line[position]<=57);j++,position++)
{
str[j]=line[position];
}
searchchar(tow);
if(line[position]==';')
{
if(sentence[sen[sentencerec-1]].act=='b')break;
else
{
outputerror(10,"","");
return 0;
}
}
else if(line[position]=='*'||line[position]=='/'||line[position]=='+'
||line[position]=='-'||line[position]=='('||line[position]==')')
{
str[j]=line[position];
j++;
position++;
for(;line[position]==' ';position++);
if(line[position]=='\0'||str[j-1]==')'&&(line[position]>=65&&line[position]<=90||line[position]>=97&&line[position]<=122))
break;
}
else if(line[position]>=65&&line[position]<=90||line[position]>=97&&line[position]<=122)break;
else
{
outputerror(10,"","");
return 0;
}
}//for
if(sentence[sen[sentencerec-1]].act=='b'&&line[position]!=';')
{
outputerror(2,"lack_sym",";");
return 0;
}
else if(line[position]==';')position++;
str[j]='\0';
if(numberexpression(str)==0)return 0;
output[outputrec].output1=":=";
if(single.compare("")==0)
{
output[outputrec].output2="T";
output[outputrec].Tnum2=output[outputrec-1].Tnum4;
}
else
{
output[outputrec].output2.assign(single);
}
output[outputrec].output3="-";
output[outputrec].output4.assign(temp);
outputrec++;
return 1;
}
bool cifafenxi(const char * filename)
{
char* table[35]={//sinple语言单词编码
"and","array","begin","bool","call",
"case","char","constant","dim","do",
"else","end","false","for","if",
"input","integer","not","of","or",
"output","procedure","program", "read","real",
"repeat","set", "stop", "then","to",
"true", "until", "var", "while", "write"};
ifstream inf(filename,ios::in);
char s[80];
int row=1;
if (inf!=NULL)
{
while(!inf.eof())
{
inf.getline(s,80);
cifaline(s,table,row);
row++;
}
inf.close();
return true;
}
else
{
cout<<"The file you input doesn't exit!"<<endl;
return false;
}
}
void cifaline(char s[80],char* table[35],int & row)//处理一行程序
{
int i,j,n;
for(i=0;s[i]!='\0'&&i<80;)
{
if(s[i]!=' '&&!(s[i]>=65&&s[i]<=90||s[i]>=97&&s[i]<=122)//非法字符
&&!(s[i]>=48&&s[i]<=57)
&&!(s[i]>=39&&s[i]<=47||s[i]>=58&&s[i]<=62||s[i]=='['||s[i]==']'))
{
outputerror(2,"no_sym","");
return;
}
if(s[i]>=65&&s[i]<=90||s[i]>=97&&s[i]<=122)//当单词开头字符为字母时
{
record[record1].content[0]=s[i];
i++;
for(n=1;(s[i]>=65&&s[i]<=90||s[i]>=97&&s[i]<=122)||
(s[i]>=48&&s[i]<=57);i++,n++)//吸收字符,直到那个字符不是字母或数字
{
record[record1].content[n]=s[i];
}
record[record1].content[n]='\0';
for(j=0;strcmp(record[record1].content,table[j])!=0&&j<=34;j++);
if(j==35)//这时record[record1].content是标识符
{
record[record1].define=0;
record[record1].attribution=36;
for(n=1;strcmp(record[record1].content,record[n].content)!=0&&n<record1;n++);
if(n==record1)record1++;//当标识符没重复时,record1++
}
continue;
}//if,当单词开头字符为字母时
if(s[i]>=48&&s[i]<=57)//当单词开头字符为数字时
{
record[record1].content[0]=s[i];
i++;
for(n=1;s[i]>=48&&s[i]<=57;i++,n++)//吸收字符,直到那个字符不是数字
{
record[record1].content[n]=s[i];
}
if(s[i]>=65&&s[i]<=90||s[i]>=97&&s[i]<=122)//如果数字后面紧跟的是字母
{
outputerror(11,"no_sym","");
return;
}
record[record1].content[n]='\0';
record[record1].define=0;
record[record1].attribution=37;
for(n=1;strcmp(record[record1].content,record[n].content)!=0&&n<record1;n++);
if(n==record1)record1++;
continue;
}//if,当单词开头字符为数字时
if(s[i]>=39&&s[i]<=47||s[i]>=58&&s[i]<=62||s[i]=='['||s[i]==']')
//当单词开头字符为单界符时
{
if(s[i]=='\'')
{
for(i=i+1,n=0;s[i]!='\''&&s[i]!='\0';i++,n++)
{
record[record1].content[n]=s[i];
}
if(s[i]=='\0')
{
outputerror(3,"no_sym","");
return;
}
else
{
record[record1].define=0;
record[record1].attribution=38;
for(n=1;strcmp(record[record1].content,record[n].content)!=0&&n<record1;n++);
if(n==record1) record1++;
i++;
}
}//if(s[i]==''')
else if(s[i]=='/'&&s[i+1]=='*')
{
for(j=i+2;!(s[j]=='*'&&s[j+1]=='/')&&s[j+1]!='\0';j++);
if(s[j+1]=='\0')
{
outputerror(4,"no_sym","");
return;
}
i=j+2;//字符移位
}
else if(s[i]=='*'&&s[i+1]=='/')
{
outputerror(4,"no_sym","");
return;
}
else if((s[i]=='<'&&(s[i+1]=='>'||s[i+1]=='='))
||(s[i]=='>'&&s[i+1]=='=')
||(s[i]==':'&&s[i+1]=='=')
||(s[i]=='.'&&s[i+1]=='.'))
{
i+=2;
}
else i++;
}//if,当单词开头字符为单界符时
for(;s[i]==' ';i++);
}//for
}//cifaline处理一行语句的词法分析
int chartoint(char a)//从字符转换成为数字
{
if(a=='(')return 0;
if(a==')')return 1;
if(a=='*')return 2;
if(a=='/')return 3;
if(a=='+')return 4;
if(a=='-')return 5;
if(a=='d')return 6;
if(a=='e')return 7;
if(a=='#')return 8;
else return -1;
}
int numberexpression(char * a)//算术表达式是否合法判断
{
int relation[9][9]={{-1,0,-1,-1,-1,-1,-1,-1,2}, {2,1,1,1,1,1,2,2,1},{-1,1,1,1,1,1,-1,-1,1},
{-1,1,1,1,1,1,-1,-1,1},{-1,1,-1,-1,1,1,-1,-1,1},{-1,1,-1,-1,1,1,-1,-1,1},
{2,1,1,1,1,1,2,2,1},{2,1,1,1,1,1,2,2,1},{-1,2,-1,-1,-1,-1,-1,-1,0}};//‘0’表示算符相等
//-1表示小于,1表示大于,2表示不存在关系
int i,j,k,m,stackrec;
char stack[30],temp[20];
string value[30];//把标识符与整数存储起来,它们的数组位置与stack数组的一样
stack[0]='#';
for(i=0,stackrec=1;a[i]!='\0';stackrec++)
{
for(;a[i]==' ';i++);//去空格
if(a[i]=='\0')break;
if(a[i]>=65&&a[i]<=90||a[i]>=97&&a[i]<=122)//标识符
{
for(k=0;(a[i]>=65&&a[i]<=90||a[i]>=97&&a[i]<=122)||(a[i]>=48&&a[i]<=57);i++,k++)
temp[k]=a[i];
temp[k]='\0';
for(m=1;strcmp(temp,record[m].content)!=0&&m<record1;m++);
if(m==record1)
{
outputerror(2,"false","");
return 0;
}
if(record[m].define==0)//标识符没有定义
{
outputerror(2,"","");
return 0;
}
else if(record[m].type!=0)
{
outputerror(12,"","");
return 0;
}
value[stackrec].assign(temp);
stack[stackrec]='d';
}//标识符
else if(a[i]>=48&&a[i]<=57)//整数
{
for(k=0;(a[i]>=48&&a[i]<=57);i++,k++)temp[k]=a[i];
temp[k]='\0';
stack[stackrec]='e';
value[stackrec].assign(temp);
}//整数
else if(a[i]=='*'||a[i]=='/'||a[i]=='+'||a[i]=='-'||a[i]=='('||a[i]==')')
{
stack[stackrec]=a[i];
i++;
}
else
{
outputerror(14,"",temp);
return 0;
}
}
stack[stackrec]='#';
char st[20];
int NTrec[20]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
string de[20];
int rec;
st[0]='#';
for(i=1,rec=1;i<=stackrec;i++)
{
if(stack[i]=='-'&&(st[rec-1]=='#'||st[rec-1]=='+'||st[rec-1]=='-'
||st[rec-1]=='*'||st[rec-1]=='/'||st[rec-1]=='('))
{
st[rec]='-';
rec++;
}
else if(st[rec-1]=='N'&&st[rec-2]=='-'&&(st[rec-3]=='*'||
st[rec-3]=='/'||st[rec-3]=='+'||st[rec-3]=='-'||st[rec-3]=='#'||st[rec-3]=='('))//把--...号去掉
{
if(NTrec[rec-1]<0)//归约-N
{
output[outputrec].output1="-";
output[outputrec].output2.assign(de[rec-1]);
output[outputrec].output3="-";
output[outputrec].output4="T";
output[outputrec].Tnum4=Trec;
NTrec[rec-2]=Trec;
outputrec++;
Trec++;
}
else
{
output[outputrec].output1="-";
output[outputrec].output2="T";
output[outputrec].output3="-";
output[outputrec].output4="T";
output[outputrec].Tnum2=NTrec[rec-1];
output[outputrec].Tnum4=Trec;
NTrec[rec-2]=Trec;
outputrec++;
Trec++;
NTrec[rec-1]=-1;
}
st[rec-2]='N';
rec=rec-1;
i--;
}
else
{
if(st[rec-1]=='N')j=rec-2;
else j=rec-1;
if(relation[chartoint(st[j])][chartoint(stack[i])]==-1)
{
st[rec]=stack[i];
rec++;
}
else if(relation[chartoint(st[j])][chartoint(stack[i])]==0)
{
if(j==rec-1)
{
outputerror(14,"",temp);
return 0;
}
if(st[j]=='#')
{
st[rec]=stack[i];
rec++;
}
if(st[j]=='(')
{ //归约(N)
NTrec[rec-2]=NTrec[rec-1];//因为有归约所以NT移位
NTrec[rec-1]=-1;
de[rec-2].assign(de[rec-1]);
st[rec-2]='N';
rec=rec-1;
}//等于"("
}//relation==0
else if(relation[chartoint(st[j])][chartoint(stack[i])]==1)//归约
{
if(st[rec-1]=='d'||st[rec-1]=='e')
{
de[rec-1].assign(value[i-1]);////////*********important
st[rec-1]='N';
}//归约N
else if(st[rec-3]=='N'&&st[rec-1]=='N')//归约N*N,N/N,N+N,N-N
{
char suanfu[2];
suanfu[0]=st[rec-2];
suanfu[1]='\0';
if(NTrec[rec-1]<0&&NTrec[rec-3]<0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -