一、实验目的:
了解掌握算符优先分析的基本方法、内容;
学会科学思考并解决问题,提高程序设计能力。
二、实验内容与要求:
用算符优先分析方法设计一个分析解释程序,对输入的赋值语句、输出语句、清除语句进行词法分析、语法分析、表达式求值并存储于指定变量中;若存在错误,提示错误相关信息。
三、文法表示:
S→v=E|E?|clear
E→E+T|E-T|T
T→T*F|T/F|F
F→ (E)|v|c
四、设计思路:
(1) 设计存储数据结构
char *VN=0,*VT=0;//非终结符和终结符数组
char firstvt[N][N],lastvt[N][N],table[N][N];
typedef struct //符号对(P,a)
{
char Vn;
char Vt;
} VN_VT;
typedef struct //栈
{
VN_VT *top;
VN_VT*bollow;
int size;
}stack;
(2) 根据文法求FIRSTVT集和LASTVT集
(3) 构造算符优先分析表
(4) 构造总控程序
五、程序代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<cctype>
#defineMAX507
#define_CRT_SECURE_NO_WARNINGScode
usingnamespacestd;
classWF
{
public:
stringleft;
vector<string>right;
WF(conststring&str)
{
left=str;
}
voidinsert(charstr[])
{
right.push_back(str);
}
voidprint()
{
printf("%s->%s",left.c_str(),right[0].c_str());
for(inti=1;i<right.size();i++)
printf("|%s",right[i].c_str());
puts("");
}
};
charrelation[MAX][MAX];
vector<char>VT;
vector<WF>VN_set;
map<string,int>VN_dic;
set<char>first[MAX];
set<char>last[MAX];
intused[MAX];
intvis[MAX];
voiddfs(intx)
{
if(vis[x])return;
vis[x]=1;
string&left=VN_set[x].left;
for(inti=0;i<VN_set[x].right.size();i++)
{
string&str=VN_set[x].right[i];
if(isupper(str[0]))
{
inty=VN_dic[str.substr(0,1)]-1;
if(str.length()>1&&!isupper(str[1]))
first[x].insert(str[1]);
dfs(y);
set<char>::iteratorit=first[y].begin();
for(;it!=first[y].end();it++)
first[x].insert(*it);
}
else
first[x].insert(str[0]);
}
}
voidmake_first()
{
memset(vis,0,sizeof(vis));
for(inti=0;i<VN_set.size();i++)
if(vis[i])continue;
elsedfs(i);
#defineDEBUG
#ifdefDEBUG
puts("------------FIRSTVT集-------------------");
for(inti=0;i<VN_set.size();i++)
{
printf("%s : ",VN_set[i].left.c_str());
set<char>::iteratorit=first[i].begin();
for(;it!=first[i].end();it++)
printf("%c ",*it);
puts("");
}
#endif
}
voiddfs1(intx)
{
if(vis[x])return;
vis[x]=1;
string&left=VN_set[x].left;
for(inti=0;i<VN_set[x].right.size();i++)
{
string&str=VN_set[x].right[i];
intn=str.length()-1;
if(isupper(str[n]))
{
inty=VN_dic[str.substr(n,1)]-1;
if(str.length()>1&&!isupper(str[n-1]))
last[x].insert(str[1]);
dfs1(y);
set<char>::iteratorit=last[y].begin();
for(;it!=last[y].end();it++)
last[x].insert(*it);
}
else
last[x].insert(str[n]);
}
}
voidmake_last()
{
memset(vis,0,sizeof(vis));
for(inti=0;i<VN_set.size();i++)
if(vis[i])continue;
elsedfs1(i);
#defineDEBUG
#ifdefDEBUG
puts("--------------LASTVT集---------------------");
for(inti=0;i<VN_set.size();i++)
{
printf("%s : ",VN_set[i].left.c_str());
set<char>::iteratorit=last[i].begin();
for(;it!=last[i].end();it++)
printf("%c ",*it);
puts("");
}
#endif
}
voidmake_table()
{
for(inti=0;i<MAX;i++)
for(intj=0;j<MAX;j++)
relation[i][j]=' ';
for(inti=0;i<VN_set.size();i++)
for(intj=0;j<VN_set[i].right.size();j++)
{
string&str=VN_set[i].right[j];
for(intk=0;k<str.length()-1;k++)
{
if(!isupper(str[k])&&!isupper(str[k+1]))
relation[str[k]][str[k+1]]='=';
if(!isupper(str[k])&&isupper(str[k+1]))
{
intx=VN_dic[str.substr(k+1,1)]-1;
set<char>::iteratorit=first[x].begin();
for(;it!=first[x].end();it++)
relation[str[k]][*it]='<';
}
if(isupper(str[k])&&!isupper(str[k+1]))
{
intx=VN_dic[str.substr(k,1)]-1;
set<char>::iteratorit=last[x].begin();
for(;it!=last[x].end();it++)
relation[*it][str[k+1]]='>';
}
if(k>str.length()-2)continue;
if(!isupper(str[k])&&!isupper(str[k+2])&&isupper(str[k+1]))
relation[str[k]][str[k+2]]='=';
}
}
#defineDEBUG
#ifdefDEBUG
for(inti=0;i<VT.size()*5;i++)
printf("-");
printf("算符优先关系表");
for(inti=0;i<VT.size()*5;i++)
printf("-");
puts("");
printf("|%8s|","");
for(inti=0;i<VT.size();i++)
printf("%5c%5s",VT[i],"|");
puts("");
for(inti=0;i<(VT.size()+1)*10;i++)
printf("-");
puts("");
for(inti=0;i<VT.size();i++)
{
printf("|%4c%5s",VT[i],"|");
for(intj=0;j<VT.size();j++)
printf("%5c%5s",relation[VT[i]][VT[j]],"|");
puts("");
for(inti=0;i<(VT.size()+1)*10;i++)
printf("-");
puts("");
}
#endif
}
intmain()
{
intn;
chars[MAX];
while(~scanf("%d",&n))
{
memset(used,0,sizeof(used));
for(inti=0;i<n;i++)
{
scanf("%s",s);
intlen=strlen(s),j;
for(j=0;j<len;j++)
if(s[j]=='-')
break;
s[j]=0;
if(!VN_dic[s])
{
VN_set.push_back(WF(s));
VN_dic[s]=VN_set.size();
}
intx=VN_dic[s]-1;
VN_set[x].insert(s+j+2);
for(intk=0;k<j;k++)
if(!isupper(s[k]))
{
if(used[s[k]])continue;
used[s[k]]=1;
VT.push_back(s[k]);
}
for(intk=j+2;k<len;k++)
if(!isupper(s[k]))
{
if(used[s[k]])continue;
VT.push_back(s[k]);
used[s[k]]=VT.size();
}
}
#defineDEBUG
#ifdefDEBUG
puts("************VT集*******************");
for(inti=0;i<VT.size();i++)
printf("%c ",VT[i]);
puts("");
puts("*************产生式*****************");
for(inti=0;i<VN_set.size();i++)
VN_set[i].print();
puts("************************************");
#endif
make_first();
make_last();
make_table();
}
}