日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

【C++实现】编译原理 免考小队 FIRSTVT集生成算法

發(fā)布時(shí)間:2023/12/8 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++实现】编译原理 免考小队 FIRSTVT集生成算法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景

期末考試免考,沖!

實(shí)驗(yàn)名稱

FIRSTVT集生成算法

實(shí)驗(yàn)時(shí)間

2020年6月3日 到 2020年6月9日

院系

信息科學(xué)與工程學(xué)院

組員姓名

Chocolate、kry2025、鐘先生、leo、小光

實(shí)驗(yàn)環(huán)境介紹

  • windows 10 操作系統(tǒng)
  • Eclipse 進(jìn)行 java 編程
  • CodeBlocks 進(jìn)行 C++ 編程

實(shí)驗(yàn)?zāi)康呐c要求

目的

  • 深刻理解FIRSTVT集生成算法
  • 掌握FIRSTVT集生成的過(guò)程
  • 加強(qiáng)團(tuán)隊(duì)合作能力
  • 提高自身的編程能力和解決問(wèn)題的能力

要求

  • 編程實(shí)現(xiàn)FIRSTVT集生成算法
  • 算法簡(jiǎn)潔,不冗余

解決問(wèn)題

Firstvt集的求法,有三條規(guī)則:
(1)A->a…,即以終結(jié)符開頭,該終結(jié)符入Firstvt
(2)A->B…,即以非終結(jié)符開頭,該非終結(jié)符的Firstvt入A的Firstvt
(3)A->Ba…,即先以非終結(jié)符開頭,緊跟終結(jié)符,則終結(jié)符入Firstvt

實(shí)驗(yàn)結(jié)果

源代碼

#include<bits/stdc++.h> #define endl '\n' #define mst(a,b) memset(a,b,sizeof(a)) using namespace std; const int maxn=1e3+5; class node{ public:string left;vector<string> right;node(const string& str){ //類似構(gòu)造函數(shù)left=str;right.clear();}void push(char str[]){ //放入產(chǎn)生式右部right.push_back(str);}void print(){ //打印產(chǎn)生式printf("%s->%s",left.c_str(),right[0].c_str());for(int i=1;i<right.size();i++)printf("|%s",right[i].c_str());puts("");} }; int n; char buf[maxn]; int used[maxn],vis[maxn]; vector<node> vnode; map<string,int> mp; vector<char> vt; set<char> firstVt[maxn]; //dfs搜索 void dfs(int x){if(vis[x]) return;vis[x]=1;string& left=vnode[x].left; //取出當(dāng)前產(chǎn)生式左部for(int i=0;i<vnode[x].right.size();i++){string& str=vnode[x].right[i]; //取出當(dāng)前產(chǎn)生式右部if(isupper(str[0])){ //如果產(chǎn)生式右部第一個(gè)為非終結(jié)符int y=mp[str.substr(0,1)]-1; //拿到對(duì)應(yīng)下標(biāo)if(str.length()>1 && !isupper(str[1])) //判斷第二個(gè)是否為終結(jié)符,是的話加入firstVt[x].insert(str[1]);dfs(y); //搜索當(dāng)前非終結(jié)符set<char>::iterator it = firstVt[y].begin();for(;it!=firstVt[y].end();it++) //加入非終結(jié)符y的firstVt集合firstVt[x].insert(*it);}else{firstVt[x].insert(str[0]); //如果是終結(jié)符,直接加入}} } void makeFirstVt(){memset(vis,0,sizeof(vis));for(int i=0;i<vnode.size();i++){if(vis[i]) continue;else dfs(i);}puts("------------FIRSTVT集-------------------");for(int i=0;i<vnode.size();i++){printf("%s : ",vnode[i].left.c_str() );set<char>::iterator it = firstVt[i].begin();for(;it!=firstVt[i].end();it++)printf("%c ",*it);puts("");} } //初始化工作,清空數(shù)組 void init(){memset(used,0,sizeof(used)); //初始化used數(shù)組,用于記錄VT集vt.clear(); //清空VT集合vnode.clear(); //清空產(chǎn)生式node集mp.clear(); //清空維護(hù)產(chǎn)生式下標(biāo)集for(int i=0;i<=maxn;i++) //清空輸出結(jié)果firstVt集firstVt[i].clear(); } int main(){while(cin>>n){init(); //初始化工作for(int i=0;i<n;i++){scanf("%s",buf); //輸入產(chǎn)生式int len=strlen(buf),j;for(j=0;j<len;j++)if(buf[j]=='-'){buf[j]=0;break;}string tmp=buf; //取產(chǎn)生式左部非終結(jié)符if(!mp[tmp]){vnode.push_back(node(tmp)); //去重操作mp[tmp]=vnode.size(); //維護(hù)下標(biāo)}int idx=mp[tmp]-1;vnode[idx].push(buf+j+2); //vnode加入產(chǎn)生式右部for(int k=0;k<j;k++){ //檢查產(chǎn)生式左部是否包含終結(jié)符if(!isupper(buf[k])){if(used[buf[k]]) continue;used[buf[k]]=1;vt.push_back(buf[k]);}}for(int k=j+2;k<len;k++){ //將產(chǎn)生式右部加入vt集合if(!isupper(buf[k])){if(used[buf[k]]) continue;vt.push_back(buf[k]);used[buf[k]]=vt.size();}}}puts("************VT集*******************");for(int i=0;i<vt.size();i++ )printf("%c ",vt[i]);puts("");cout<<endl;puts("*************產(chǎn)生式*****************");for(int i=0;i<vnode.size();i++)vnode[i].print();puts("************************************");cout<<endl;makeFirstVt(); //求FirstVt集}return 0; }

輸出結(jié)果

測(cè)試樣例

8 E->E+T E->T T->T*F T->F F->P^F F->P P->(E) P->i

參考文獻(xiàn)

參考:編譯原理(七) 算符優(yōu)先分析法(構(gòu)造算符優(yōu)先關(guān)系表算法及C++實(shí)現(xiàn))

總結(jié)

以上是生活随笔為你收集整理的【C++实现】编译原理 免考小队 FIRSTVT集生成算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。