算符優先分析過程只考慮算符(終結符)之間的優先關係,分析掃描每個規約式的算符間優先關係。
根據龍書闡述,算符優先分析逐漸淘汰了。orz
但仍然實現之。
示例語法如下:
D->#E#
E->E+T|T
T->T*F|F
F->P$F|P
P->(E)|i
main.cpp
#include <iostream>
#include <vector>
#include "grammerin.h"
#include "calculatepriortable.h"
#include "analy.h"
using namespace std;
int main()
{
vector<vector<char> > sign;
cout<<"讀入語法規則:"<<endl;
sign=readGrammer();
/*
for(int i=0;i<2;++i)
{
for(int j=0;j<sign[i].size();++j)
cout<<sign[i][j]<<" ";
cout<<endl;
}
*/
vector<vector<vector<char> > > vvvc;
vvvc = createfirstandfollow(sign);
vector<vector<char> > priortable;
priortable=createtable(vvvc);
while(true)
{
cout<<endl<<"input: ";
string s;
cin>>s;
inStringAnalyze(s,priortable);
}
return 0;
}
grammerin.cpp:
#ifndef GRMMERIN_H
#define GRMMERIN_H
#include <vector>
using namespace std;
vector< vector<char> > readGrammer();
vector< vector<char> > readGrammerWithNoPrint();
vector<string> getgrammer();
#endif
grammerin.h:
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <cctype>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <ctime>
using namespace std;
vector< vector<char> > readGrammer()
{
vector<char> terminatesign,unterminatesign;
string s,grammer;
ifstream in("C:\\Users\\lsy\\Desktop\\grammer1.txt");
if (! in.is_open())
{ cout << "Error opening file"; exit (1); }
while (!in.eof() )
{
char lin[100];
//in.getline(buffer);
in.getline(lin,100);
s+=lin;
grammer+=s+"\n";
//cout <<s<< endl;
int k=s.find_first_of("->");
for(int i=0;i<k;++i)
{
//cout<<s[i]<<endl;
vector<char>::iterator result = find(unterminatesign.begin(),unterminatesign.end(),s[i]);
if(result==unterminatesign.end())
unterminatesign.push_back(s[i]);
}
for(int i=k+2;i<s.size();++i)
{
//cout<<s[i]<<endl;
if((s[i]>='A'&&s[i]<='Z')||s[i]==' '||s[i]=='|')
;
else
{
vector<char>::iterator result = find(terminatesign.begin(),terminatesign.end(),s[i]);
if(result==terminatesign.end())
terminatesign.push_back(s[i]);
}
}
s="";
}
cout<<grammer;
cout<<endl<<"·ÇÖÕ½á·û£º"<<endl;
for(int i=0;i<unterminatesign.size();++i)
cout<<unterminatesign[i]<<" ";
cout<<endl;
cout<<"ÖÕ½á·û£º"<<endl;
for(int i=0;i<terminatesign.size();++i)
cout<<terminatesign[i]<<" ";
cout<<endl;
vector<vector<char> > returnvector;
returnvector.push_back(unterminatesign);
returnvector.push_back(terminatesign);
return returnvector;
}
vector< vector<char> > readGrammerWithNoPrint()
{
//system("chcp 65001");
vector<char> terminatesign,unterminatesign;
string s,grammer;
ifstream in("C:\\Users\\lsy\\Desktop\\grammer1.txt");
if (! in.is_open())
{ cout << "Error opening file"; exit (1); }
while (!in.eof() )
{
char lin[100];
//in.getline(buffer);
in.getline(lin,100);
s+=lin;
grammer+=s+"\n";
//cout <<s<< endl;
int k=s.find_first_of("->");
for(int i=0;i<k;++i)
{
//cout<<s[i]<<endl;
vector<char>::iterator result = find(unterminatesign.begin(),unterminatesign.end(),s[i]);
if(result==unterminatesign.end())
unterminatesign.push_back(s[i]);
}
for(int i=k+2;i<s.size();++i)
{
//cout<<s[i]<<endl;
if((s[i]>='A'&&s[i]<='Z')||s[i]==' '||s[i]=='|')
;
else
{
vector<char>::iterator result = find(terminatesign.begin(),terminatesign.end(),s[i]);
if(result==terminatesign.end())
terminatesign.push_back(s[i]);
}
}
s="";
}
vector<vector<char> > returnvector;
returnvector.push_back(unterminatesign);
returnvector.push_back(terminatesign);
return returnvector;
}
vector<string> getgrammer()
{
string s;
vector<string> vv;
ifstream in("C:\\Users\\lsy\\Desktop\\grammer1.txt");
if (! in.is_open())
{ cout << "Error opening file"; exit (1); }
while (!in.eof() )
{
char lin[100];
//in.getline(buffer);
in.getline(lin,100);
s+=lin;
//cout<<s.find_first_of("|")<<" "<<s.size()<<endl;
while(s.find_first_of("|")<=s.size()&&s.find_first_of("|")>=0)
{
//cout<<s.find_first_of("|")<<" "<<s.size()<<" "<<s<<endl;
int a=s.find_first_of("->");
int b=s.find_first_of("|");
//cout<<a<<" "<<b<<" "<<s<<endl;
string ss="";
ss+=s[0];
ss+="->";
ss+=s.substr(a+2,b-a-2);
//cout<<ss<<" "<<s<<endl;
s.erase(a+2,b-a-1);
//cout<<ss<<" "<<s<<endl;
vv.push_back(ss);
}
vv.push_back(s);
s="";
}
/*
cout<<endl;
for(int i=0;i<vv.size();++i)
{
cout<<vv[i]<<endl;
}
*/
return vv;
}
calculatepriortable.h
#ifndef CALCULATEPRIORTABLE_H
#define CALCULATEPRIORTABLE_H
#include <vector>
using namespace std;
vector<vector<vector<char> > > createfirstandfollow(vector< vector<char> > sign);
vector<vector<char> > createtable(vector<vector<vector<char> > > vvvc);
#endif
calculatepriortable.cpp
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <cctype>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include "grammerin.h"
using namespace std;
vector<char> findUnterminateSignsFirstav(char c,vector<string> grammer,vector<char>& result)
{
for(int i=0;i<grammer.size();++i)
{
if(grammer[i][0]==c)
{
int a=grammer[i].find_first_of("->");
a+=2;
if(grammer[i][a]>='A'&&grammer[i][a]<='Z')
findUnterminateSignsFirstav(c,grammer,result);
else
{
vector<char>::iterator res = find(result.begin(),result.end(),grammer[i][a]);
if(res==result.end())
result.push_back(grammer[i][a]);
else
;
}
}
}
}
vector<vector<vector<char> > > createfirstandfollow(vector< vector<char> > sign)
{
/*
cout<<sign.size()<<endl;
for(int i=0;i<2;++i)
{
for(int j=0;j<sign[i].size();++j)
cout<<sign[i][j]<<" ";
cout<<endl;
}
*/
vector<vector<char> > signtable;
vector<char> v;
for(int i=0;i<20;++i)
v.push_back(' ');
for(int i=0;i<20;++i)
signtable.push_back(v);
vector<string> grammer;
grammer=getgrammer();
cout<<endl<<"讀入語法:"<<endl;
for(int i=0;i<grammer.size();++i)
cout<<grammer[i]<<endl;
cout<<endl;
vector<vector<char> > firstav,followav;
map<char,set<char> > ufirstav,ufollowav;
//構造firstav數組
for(int i=0;i<grammer.size();++i)
{
char c=grammer[i][0];
int a=grammer[i].find_first_of("->");
a+=2;
//cout<<grammer[i]<<" "<<grammer[i][a]<<endl;
if(grammer[i][a]>='A'&&grammer[i][a]<='Z')
{
int flag3=0;
for(int j=0;j<firstav.size();++j)
{
if(firstav[j][0]==c)
{
flag3=1;
break;
}
}
if(flag3==0)
{
vector<char> v;
v.push_back(c);
if((a+1)<grammer[i].size())
{
if(grammer[i][a+1]>='A'&&grammer[i][a+1]<='Z')
;
else
v.push_back(grammer[i][a+1]);
}
//v.push_back(grammer[i][a]);
firstav.push_back(v);
}
/*
vector<char> result;
findUnterminateSignsFirstav(c,grammer,result);
cout<<"---"<<endl;
for(int i=0;i<result.size();++i)
cout<<result[i]<<" ";
cout<<"---"<<endl;
*/
map<char,set<char> >::iterator iter = ufirstav.find(c);
if(iter!=ufirstav.end())
{
ufirstav[c].insert(grammer[i][a]);
}
else
{
set<char> sc;
sc.insert(grammer[i][a]);
ufirstav[c]=sc;
}
}
else
{
int k=1;
for(int j=0;j<firstav.size();++j)
{
//cout<<"---"<<endl;
if(firstav[j][0]==c)
{
firstav[j].push_back(grammer[i][a]);
--k;
break;
}
}
if(k)
{
vector<char> v;
v.push_back(c);
v.push_back(grammer[i][a]);
firstav.push_back(v);
}
}
}
int flag;
L1:
flag=1;
//從非終結符集合向終結符集合加入元素
for(map<char,set<char> >::iterator iter=ufirstav.begin();iter!=ufirstav.end();++iter)
{
char c=iter->first;
//cout<<endl<<c<<endl;
int csite;
int ssite;
//找到目的位置
for(int i=0;i<firstav.size();++i)
{
if(c==firstav[i][0])
{
csite=i;
break;
}
}
for(set<char>::iterator itera=(iter->second).begin();itera!=(iter->second).end();++itera)
{
//找到源位置
for(int i=0;i<firstav.size();++i)
{
if((*itera)==firstav[i][0])
{
ssite=i;
break;
}
}//cout<<"------------"<<endl;
//源數組掃描
for(int i=1;i<firstav[ssite].size();++i)
{
int flag2=1;
//比較源數組某一位和目的數組各位是否有相同元素
for(int j=1;j<firstav[csite].size();++j)
{
if(firstav[ssite][i]==firstav[csite][j])
{
flag2=0;
break;
}
}
if(flag2)
{
firstav[csite].push_back(firstav[ssite][i]);
flag=0;
}
}
}
}
if(flag==0)
goto L1;
/*
cout<<endl;
for(int i=0;i<firstav.size();++i)
{
cout<<firstav[i][0]<<" : ";
for(int j=1;j<firstav[i].size();++j)
{
cout<<firstav[i][j]<<" ";
}
cout<<endl;
}
*/
cout<<"firstav: "<<endl;
for(int i=0;i<firstav.size();++i)
{
cout<<firstav[i][0]<<" : ";
for(int j=1;j<firstav[i].size();++j)
{
cout<<firstav[i][j]<<" ";
}
cout<<endl;
}
/*
cout<<endl<<"U:"<<endl;
//map<char,set<char> >::iterator iter;
for(map<char,set<char> >::iterator iter=ufirstav.begin();iter!=ufirstav.end();++iter)
{
cout<<(iter->first)<<" : ";
for(set<char>::iterator itera=(iter->second).begin();itera!=(iter->second).end();++itera)
{
cout<<*itera<<" ";
}
cout<<endl;
}
*/
//構造followav數組
for(int i=0;i<grammer.size();++i)
{
char c=grammer[i][0];
//cout<<c<<" "<<grammer[i][grammer[i].size()-1]<<endl;
if(grammer[i][grammer[i].size()-1]>='A'&&grammer[i][grammer[i].size()-1]<='Z')
{
int flag3=0;
for(int j=0;j<followav.size();++j)
{
if(followav[j][0]==c)
{
flag3=1;
break;
}
}
if(flag3==0)
{
vector<char> v;
v.push_back(c);
if(grammer[i][grammer[i].size()-2]>='A'&&grammer[i][grammer[i].size()-2]<='Z')
;
else
{
int y=grammer[i].find_first_of("->");
y+=2;
if((grammer[i].size()-2)>=y)
v.push_back(grammer[i][grammer[i].size()-2]);
}
followav.push_back(v);
}
/*
for(int o=0;o<v.size();++o)
cout<<"---"<<v[o];
cout<<endl;
*/
map<char,set<char> >::iterator iter = ufollowav.find(c);
//cout<<endl<<grammer[i];
if(iter!=ufollowav.end())
{
//cout<<c<<" - - "<<grammer[i][grammer[i].size()-1]<<endl;
ufollowav[c].insert(grammer[i][grammer[i].size()-1]);
}
else
{
//cout<<c<<" -- -- "<<grammer[i][grammer[i].size()-1]<<endl;
set<char> sc;
sc.insert(grammer[i][grammer[i].size()-1]);
ufollowav[c]=sc;
}
}
else
{
int k=1;
for(int j=0;j<followav.size();++j)
{
//cout<<"---"<<endl;
if(followav[j][0]==c)
{
followav[j].push_back(grammer[i][grammer[i].size()-1]);
--k;
break;
}
}
if(k)
{
vector<char> v;
v.push_back(c);
v.push_back(grammer[i][grammer[i].size()-1]);
followav.push_back(v);
}
}
}
L2:
flag=1;
//從非終結符集合向終結符集合加入元素
for(map<char,set<char> >::iterator iter=ufollowav.begin();iter!=ufollowav.end();++iter)
{
char c=iter->first;
//cout<<endl<<c<<endl;
int csite;
int ssite;
//找到目的位置
for(int i=0;i<followav.size();++i)
{
if(c==followav[i][0])
{
csite=i;
break;
}
}
for(set<char>::iterator itera=(iter->second).begin();itera!=(iter->second).end();++itera)
{
//找到源位置
for(int i=0;i<followav.size();++i)
{
if((*itera)==followav[i][0])
{
ssite=i;
break;
}
}
//源數組掃描
for(int i=1;i<followav[ssite].size();++i)
{
int flag2=1;
//比較源數組某一位和目的數組各位是否有相同元素
for(int j=1;j<followav[csite].size();++j)
{
if(followav[ssite][i]==followav[csite][j])
{
flag2=0;
break;
}
}
if(flag2)
{
followav[csite].push_back(followav[ssite][i]);
flag=0;
}
}
}
}
if(flag==0)
goto L2;
cout<<endl<<"followav: "<<endl;
for(int i=0;i<followav.size();++i)
{
cout<<followav[i][0]<<" : ";
for(int j=1;j<followav[i].size();++j)
{
cout<<followav[i][j]<<" ";
}
cout<<endl;
}
/*
cout<<endl<<"U:"<<endl;
//map<char,set<char> >::iterator iter;
for(map<char,set<char> >::iterator iter=ufollowav.begin();iter!=ufollowav.end();++iter)
{
cout<<(iter->first)<<" : ";
for(set<char>::iterator itera=(iter->second).begin();itera!=(iter->second).end();++itera)
{
cout<<*itera<<" ";
}
cout<<endl;
}
*/
vector<vector<vector<char> > > ret;
ret.push_back(firstav);
ret.push_back(followav);
return ret;
}
vector<vector<char> > createtable(vector<vector<vector<char> > > vvvc)
{
vector<vector<char> > firstav,followav;
firstav=vvvc[0];
followav=vvvc[1];
/*
cout<<"firstav: "<<endl;
for(int i=0;i<firstav.size();++i)
{
cout<<firstav[i][0]<<" : ";
for(int j=1;j<firstav[i].size();++j)
{
cout<<firstav[i][j]<<" ";
}
cout<<endl;
}
cout<<endl<<"followav: "<<endl;
for(int i=0;i<followav.size();++i)
{
cout<<followav[i][0]<<" : ";
for(int j=1;j<followav[i].size();++j)
{
cout<<followav[i][j]<<" ";
}
cout<<endl;
}
*/
vector<char> terminatesign= readGrammerWithNoPrint()[1];
/*
for(int i=0;i<terminatesign.size();++i)
cout<<terminatesign[i]<<" ";
cout<<endl;
*/
map<char,int> mapTerminateSignCharToInt;
for(int i=0;i<terminatesign.size();++i)
mapTerminateSignCharToInt[terminatesign[i]]=i;
/*
map<char,int>::iterator iter;
for(iter=mapTerminateSignCharToInt.begin();iter!=mapTerminateSignCharToInt.end();++iter)
{
cout<<iter->first<<" "<<iter->second<<endl;
}
*/
vector<vector<char> > priortable;
vector<char> vc;
for(int i=0;i<terminatesign.size();++i)
vc.push_back(' ');
for(int i=0;i<terminatesign.size();++i)
priortable.push_back(vc);
/*
for(int i=0;i<priortable.size();++i)
{
for(int j=0;j<priortable[i].size();++j)
{
cout<<priortable[i][j];
}
cout<<endl;
}
*/
vector<string> grammer;
grammer=getgrammer();
for(int i=0;i<grammer.size();++i)
{
int arrowcite=grammer[i].find_first_of("->");
arrowcite+=2;
//cout<<grammer[i].substr(arrowcite)<<endl;
for(int j=arrowcite;j<grammer[i].size()-1;++j)
{
for(int k=j+1;k<grammer[i].size();++k)
{
if( (!(isupper(grammer[i][j]))) && (!(isupper(grammer[i][k]))) )
{
//cout<<j<<" "<<k<<" "<<grammer[i]<<endl;
priortable[mapTerminateSignCharToInt[grammer[i][j]]][mapTerminateSignCharToInt[grammer[i][k]]] = '=';
//priortable[mapTerminateSignCharToInt[grammer[i][k]]][mapTerminateSignCharToInt[grammer[i][j]]] = '=';
}
else if( (!(isupper(grammer[i][j]))) && ((isupper(grammer[i][k]))) )
{//cout<<"here----------"<<endl;
for(int l=0;l<firstav.size();++l)
{
if(firstav[l][0]==grammer[i][k])
{
for(int m=1;m<firstav[l].size();++m)
{
priortable[mapTerminateSignCharToInt[grammer[i][j]]][mapTerminateSignCharToInt[firstav[l][m]]] = '<';
}
break;
}
}
}
else if( ((isupper(grammer[i][j]))) && (!(isupper(grammer[i][k]))) )
{
for(int l=0;l<followav.size();++l)
{
if(followav[l][0]==grammer[i][j])
{
for(int m=1;m<followav[l].size();++m)
{
priortable[mapTerminateSignCharToInt[followav[l][m]]][mapTerminateSignCharToInt[grammer[i][k]]] = '>';
//cout<<i<<" "<<j<<" "<<k<<" "<<followav[l][m]<<" "<<grammer[i][k]<<endl;
}
break;
}
}
}
}
}
}
cout<<endl<<"優先關係表:"<<endl<<' ';
for(int i=0;i<terminatesign.size();++i)
cout<<terminatesign[i];
cout<<endl;
for(int i=0;i<priortable.size();++i)
{
cout<<terminatesign[i];
for(int j=0;j<priortable[i].size();++j)
{
cout<<priortable[i][j];
}
cout<<endl;
}
return priortable;
}
analy.h
#ifndef ANALY_H
#define ANALY_H
#include <vector>
using namespace std;
void inStringAnalyze(string s,vector<vector<char> > priortable);
#endif
analy.cpp
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <cctype>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include "grammerin.h"
using namespace std;
void createRightToLeftMapping()
{
vector<string> grammer=getgrammer();
for(int i=0;i<grammer.size();++i)
cout<<grammer[i]<<endl;
map<string,char> leftToRight;
for(int i=0;i<grammer.size();++i)
{
int c=grammer[i].find_first_of("->");
c+=2;
string left=grammer[i].substr(c);
//out<<left<<endl;
leftToRight[left]=grammer[i][0]; //此處假設產生式右部無重複
}
}
//#i+i#
void inStringAnalyze(string s,vector<vector<char> > priortable)
{
vector<char> terminatesign= readGrammerWithNoPrint()[1];
/*
for(int i=0;i<terminatesign.size();++i)
cout<<terminatesign[i]<<" ";
cout<<endl;
*/
map<char,int> mapTerminateSignCharToInt;
for(int i=0;i<terminatesign.size();++i)
mapTerminateSignCharToInt[terminatesign[i]]=i;
createRightToLeftMapping();
string analystack="";
analystack+=s[0];
cout<<analystack<<endl;
cout<<s[0]<<endl;
int analystackpoint=0;
string inputstring=s.substr(1);
//cout<<s<<endl;
cout<<" "<<"分析棧 "<<"優先關係 "<<"輸入串"<<endl;
int num=0;
int sign=0;
int presign=-1;
int numg=0;
while(true)
{
cout<<(num++)<<" "<<analystack<<" ";
//cout<<endl<<analystack[analystackpoint]<<" "<<s[0]<<endl;
cout<<analystack[analystackpoint];
cout<<priortable[mapTerminateSignCharToInt[analystack[analystackpoint]]][mapTerminateSignCharToInt[inputstring[0]]];
cout<<inputstring[0]<<" "<<inputstring<<endl;
//cout<<(num++)<<" "<<analystack[analystackpoint]<<" ";
//cout<<priortable[analystack[analystackpoint]][s[0]]<<" "<<s[0]<<" "<<s<<endl;
if(priortable[mapTerminateSignCharToInt[analystack[analystackpoint]]][mapTerminateSignCharToInt[inputstring[0]]]=='=')
sign=0;
else if(priortable[mapTerminateSignCharToInt[analystack[analystackpoint]]][mapTerminateSignCharToInt[inputstring[0]]]=='<')
sign=1;
else if(priortable[mapTerminateSignCharToInt[analystack[analystackpoint]]][mapTerminateSignCharToInt[inputstring[0]]]=='>')
sign=2;
else
{
cout<<"grammer error!"<<endl;
break;
}
if(presign==1&&sign==2)
{
cout<<numg<<endl;;//規約
string dis;
dis=analystack.substr(analystackpoint,analystackpoint+numg);
cout<<dis<<endl;
}
else
{
numg++;
analystack+=inputstring[0];
++analystackpoint;
//cout<<endl<<analystack<<endl;
inputstring=inputstring.substr(1);
presign=1;
}
//cout<<endl<<analystackpoint<<endl;
if(num>5)
break;
}
}