?? graph.cpp
字號:
#include<iostream>
#include<map>
#include<set>
#include "declarant.h"
#include "Graph.h"
using namespace std;
/********直接由初態(tài)里加一條邊到終態(tài),比如說加{,}等****/
int Graph::add_wedge(const char& c,const string& returnid)
{
wedge* p =new wedge;
p->c = c;
p->state = ++statenum;
p->next = G[1] ;
G[1] = p;
Gend.insert(statenum);
MAP[statenum]=returnid;
return 0;
}
/****從文件中輸入圖,并進行合并****/
int Graph::inputG(char* path,const string& s)
{
FILE* fp= fopen(path,"r");
if(fp==NULL)
{
cout<<"open error"<<endl;
exit(1);
}
else
{
int num = 0; //這次輸入的圖的狀態(tài)數(shù)
fscanf(fp,"%d",&num);
// cout<<num<<endl;
int start = 0; //初態(tài)
fscanf(fp,"%d",&start);
// cout<<start<<endl;
Gstart.insert(start+statenum); //加入初態(tài)
// 輸入終態(tài)
int end;
fscanf(fp,"%s",buff);
char* p=buff;
while(*p)
{
sscanf(p,"%d,",&end);
// cout<<end<<endl;
p+=2;
MAP.insert(pair< int,string >(end+statenum,s)); //每個終態(tài)對應(yīng)的類型
Gend.insert(end+statenum);
}
// 輸入圖
int first=0;
while(fscanf(fp,"%d",&first)!=EOF)
{
fscanf(fp,"%s",buff);
// printf("%s\n",buff);
p=buff;
first+=statenum;
while(*p)
{
wedge* s1 = new wedge;
sscanf(p,"%c,%d,",&s1->c,&s1->state);
// cout<<s1->c<<" "<<s1->state<<endl;
s1->state+=statenum;
p+=4;
wedge* temp=G[first];
G[first]=s1;
s1->next=temp;
}
}
statenum+=num; // 總狀態(tài)數(shù)增加
}
return 0;
}
/*****釋放圖資源*****/
int Graph::freeG()
{
map<int,wedge* > :: iterator it;
for(it=G.begin(); it!=G.end();it++)
{
for(wedge* p=it->second; p; p = it->second)
{
it->second = p->next;
delete p;
}
}
return 0;
}
/****輸出圖****/
int Graph::dispalyG()
{
FILE* fp=fopen("Graph.txt","w");
//先輸出總共有幾個狀態(tài)
fprintf(fp,"%d\n",statenum);
// 先輸出初態(tài),初態(tài)一行
set<int>::iterator it;
for(it=Gstart.begin();it!=Gstart.end();it++)
fprintf(fp,"%d,",*it);
fprintf(fp,"\n");
// 輸出終態(tài),終態(tài)一行
for(set<int>::iterator it=Gend.begin(); it!=Gend.end();it++)
{
fprintf(fp,"%d,",*it);
}
fprintf(fp,"\n");
// 輸出鄰接表
map<int, wedge* >:: iterator m_iter;
for(m_iter=G.begin();m_iter!= G.end(); m_iter++)
{ //沒有出度的表頭不輸出
if(m_iter->second)
fprintf(fp,"%d\n",m_iter->first);
for(wedge* p=m_iter->second; p!=NULL; p=p->next)
{
fprintf(fp,"%c,%d,",p->c,p->state);
}
fprintf(fp,"\n");
}
fclose(fp);
return 0;
}
/*****輸入源代碼******/
int Graph::input_code(char* filename)
{
FILE* fp;
if((fp=fopen(filename,"r"))==NULL)
{
perror("打開文件錯誤\n");
exit(1);
}
else
{
while(fgets(buff, 1000, fp ))
{
//puts(buff);
linenum++;
// cout<<linenum<<endl;
match();
}
display_token();
}
return 0;
}
/*****定義該類對象時必須執(zhí)行的*****/
int Graph::run()
{
Graph::inputG("relop.txt","relop");
Graph::inputG("num.txt","num");
Graph::inputG("id.txt","id");
add_wedge('=',"=");
add_wedge('{',"{");
add_wedge(';',";");
add_wedge(',',",");
add_wedge('(',"(");
add_wedge('}',"}");
add_wedge(')',")");
add_wedge('+',"+");
add_wedge('-',"-");
add_wedge('*',"*");
token.insert(pair<string,vector<string> >("relop",vector<string>())); //關(guān)系運算符
token.insert(pair<string,vector<string> >("num",vector<string>())); // 正整數(shù)
token.insert(pair<string,vector<string> >("id",vector<string>())); //標(biāo)識符
token.insert(pair<string,vector<string> >("reserve",vector<string>())); //關(guān)鍵字
token.insert(pair<string,vector<string> >("invalid",vector<string>())); //非法字符
token.insert(pair<string,vector<string> >("{",vector<string>()));
token.insert(pair<string,vector<string> >("}",vector<string>()));
token.insert(pair<string,vector<string> >("(",vector<string>()));
token.insert(pair<string,vector<string> >(")",vector<string>()));
token.insert(pair<string,vector<string> >("+",vector<string>()));
token.insert(pair<string,vector<string> >("-",vector<string>()));
token.insert(pair<string,vector<string> >("*",vector<string>()));
token.insert(pair<string,vector<string> >("=",vector<string>()));
// 以下是輸入關(guān)鍵字
isReserve.insert("int");
isReserve.insert("printf");
isReserve.insert("return");
isReserve.insert("if");
isReserve.insert("else");
isReserve.insert("long");
isReserve.insert("switch");
isReserve.insert("case");
isReserve.insert("break");
isReserve.insert("for");
isReserve.insert("char");
isReserve.insert("return");
isReserve.insert("continue");
isReserve.insert("default");
isReserve.insert("do");
isReserve.insert("while");
isReserve.insert("short");
isReserve.insert("main");
isReserve.insert("include");
input_code("coder.txt");
return 0;
}
/****輸出關(guān)鍵字的集合*****/
int Graph::display_set()
{
set<string> :: iterator it = isReserve.begin();
for(;it!=isReserve.end();it++)
cout<<*it<<endl;
}
/***獲得token通過字符串的起點和終點下標(biāo)和終態(tài)位置******/
int Graph::getToken(int last_ac_state,int start,int end,int flag)
{
FILE* fp=fopen("token.txt","a");
char temp[50];
if(end-start==0||end-start==1)
{
memcpy(temp,buff+start,end-start+1);
temp[end-start+1] = '\0';
}
else
{
memcpy(temp,buff+start,end-start);
temp[end-start] = '\0';
}
string s = temp; //匹配出來的那個串
cout<<s<<endl;
if(flag) //合法字符
{
if( isReserve.find(s) != isReserve.end() ) // 表示找到的是關(guān)鍵字
{
vector<string>& t = token["reserve"];
for(int i=0;i<t.size();i++)
if(t[i]== s) //以經(jīng)存在了
{
fclose(fp);
return 0;
}
//否則加入
t.push_back(s);
fclose(fp);
return 0;
}
//不是關(guān)鍵字就在 MAP是找,
map<int, string>::iterator it = MAP.find(last_ac_state);
if(it == MAP.end() )
{
perror("did find");
fclose(fp);
return 1;
}
else
{ //it->second是last_ac_state屬于什么類別
vector<string>& t=token[it->second];
for(int i=0;i<t.size();i++)
if(t[i]==s) //以經(jīng)存在了
{
fclose(fp);
return 0;
}
t.push_back(s);
}
}
else //非法字符
{
cout<<s<<" is invalid in line"<<linenum<<endl;
fprintf(fp,"%s is invalid in line %d \n",s.c_str(),linenum);
vector<string>& t=token["invalid"];
for(int i=0;i<t.size();i++)
if(t[i]==s) //以經(jīng)存在了
{
fclose(fp);
return 0;
}
t.push_back(s);
}
fclose(fp);
return 0;
}
/***看start經(jīng)過c能否到達一個狀態(tài),
能 返回到達的那個狀態(tài),不能返回 0****/
int Graph::isok(const char& c,int start)
{
for(wedge* p = G[start]; p ; p=p->next)
if(p->c == c) return p->state;
return 0;
}
/*****對輸入串進行匹配,關(guān)鍵字先按標(biāo)示符處理*****/
int Graph::match()
{
int advance=0; //向前讀的指針
int last_ac_state=0; //匹配中的最后一個終態(tài)
int last_ac_char_position=0; //匹配中的最后一個字符
int flag=0; //表示未能匹配成功
for(int i=0; buff[i]; i=++advance)
{
if(buff[i]==' '||buff[i]=='\n')continue; //濾出空格和回車
last_ac_state=0; //匹配中的最后一個終態(tài)
last_ac_char_position=0; //匹配中的最后一個字符
flag=0; //表示未能匹配成功
for(set<int>::iterator myset=Gstart.begin(); myset!=Gstart.end()&&!flag; myset++)
{//開始結(jié)點遍歷,
int stateA = *myset; //前一個狀態(tài)
int stateB=0; //后一個狀態(tài),
for(int j=i;buff[j];j++) //串在移動
{
stateB= isok(buff[j],stateA);
advance=j;
if(Gend.find(stateA) != Gend.end()) //stateA是終態(tài)的話
{
last_ac_state=stateA;
last_ac_char_position=j;
flag=1; //表示以找到匹配的了
}
if(stateB==0) //表示走不下去了
break;
else
stateA=stateB; //往前走了一步
}
}
if(last_ac_state)
{
getToken(last_ac_state,i,last_ac_char_position,flag);
advance = last_ac_char_position ;
}
if(flag) //匹配成功的時候要返回退一格
advance--;
else
getToken(last_ac_state,i,advance,flag);
}
return 0;
}
/*****輸出token****/
int Graph::display_token()
{
FILE* fp=fopen("token.txt","a");
map<string , vector<string> >:: iterator it=token.begin();
for(;it!=token.end();it++)
{// cout<<it->first<<endl;
int len=it->second.size();
vector<string>& v=it->second;
for(int i=0;i<len;i++)
{
// cout<<v[i]<<" ------------------ "<<it->first<<endl;
fprintf(fp,"%s -------------------- %s\n",v[i].c_str(),it->first.c_str());
}
}
fclose(fp);
return 0;
}
/****析構(gòu)函數(shù)****/
Graph::~Graph()
{
Graph::freeG();
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -