编译原理LR0分析表的构造
#include #include #include #include #include #include using namespace std; multimap m;//类似图的一个关联性容器 map inSignInt; //输入符映射关系,由于状态转移图行列需用整数形式表示,将字符映射到数字 vector status;//一个状态 vector> que; //状态队列 char endd[20];//终结符集合 char nend[20];//非终结符集合 string rule[10];//产生式数组 int n;//产生式的个数 int ne;//终结符号个数 int nne;//非终结符个数 int order;//找到此状态在哪里已经存在过了 int gys;//第几条产生式规约; string stateMap[101][101];//状态转移图构造 char sign[10];//存储终结符和非终结符的数组 int choose(char t, char e[], char ne[]); string insert2(string s);//在产生式某个位置插入. int toint(string s)//获得goto表中具体哪一个状态,如S11返回11 { int num = 0; int i = 0; if (s.length() > 1) { if (s[0] == 's' || s[0] == 'r') { i = 1; while (s[i] != ' ') { num = num * 10 + s[i] - '0'; i++; } } else { int i = 0; while (s[i] != ' ') { num = num * 10 + s[i] - '0'; i++; } } } else { num = num * 10 + s[0] - '0'; } return num; } //寻找用第几条产生式规约 int guiyuej(vector a) { int flag = 0; for (int i = 0; i < a.size(); i++) { for (int j = 0; j < n; j++) { if (!a[i].compare(insert2(rule[j]))) { flag = 1; gys = j; break; } } return flag; } } //将状态号转换成对应的R操作 string gyc(int x) { string s; s = to_string(x); s.insert(0, "R"); return s; } //将状态号转换成对应的S操作 string zhuanhuan(int x,char t) { string s; //如果是非终结符 if (choose(t, endd, nend)) { s = to_string(x); } //如果是终结符 else { s = to_string(x); s.insert(0, "S"); } return s; } //交换某个产生式.与.后符号的位置 string swap(string a, int x, int y) { char t; t = a[y]; a[y] = a[x]; a[x] = t; return a; } //在某个位置插入. string insert(string s) { //cout << s< b) { int flag = true; for (int i = 0; i < b.size(); i++) { if (j == b[i]) { flag = false; } } return flag; } //判断当前字符是终结符还是非终结符 int choose(char t, char e[], char ne[]) { int flag = -1; for (int i=0;i < 10; i++) { if (e[i] == t)//如果是终结符 { flag = 0; break; } else if (ne[i] == t)//如果是非终结符 { flag = 1; break; } } return flag; } //判断产生式在某个状态中是否存在过了 int panduan(vector& a, string st1) { int flag = 1; for (int i = 0; i < a.size(); i++) {//若两个字符串相等 string s = insert(st1); //cout << a[i] << " " << s<& a, vector& b) { int flag=0; int m = 0; if (a.size() == b.size())//若两个状态大小一样才比较 { for (int i = 0; i < a.size(); i++) { for (int j = 0; j < b.size(); j++) { if (!a[i].compare(b[j])) { m++;//找到一条匹配的产生式 } } } } //全部匹配若 if (m == a.size()) { flag = 1; } return flag; } //判断当前状态是否在状态集合中已经存在过 int common(vector>& a, vector& b) { int flag = 1; for (int i = 0; i < a.size(); i++) { if (ssjungle(a[i], b))//若在当前集合当中找到了相同状态 { order = i; flag = 0;//状态已经存在过了 break; } } return flag; } void closure(vector &a)//求某一个产生式的闭包 { int t = a.size(); for (int i = 0;i < a.size(); i++) {//如果.后是非终结符号 char c = a[i].find('.') + 1; if (choose(a[i][c],endd,nend)) { for (int j = 0; j < n; j++) { if (rule[j][0] == a[i][c]&&panduan(a,rule[j])) { a.push_back(insert(rule[j]));//将第一条产生式入栈 //cout << insert(rule[j]) <> n; cout << "请输入产生式:" << endl; for (int i = 0; i < n; i++) { cin >> rule[i]; } cout << "请输入终结符的个数:" << endl; cin >> ne; cout << "请输入终结符:" << endl; for (int i = 0; i < ne; i++) { cin >> endd[i]; } cout << "请输入非终结符的个数:" << endl; cin >> nne; cout << "请输入非终结符:" << endl; for (int i = 0; i < nne; i++) { cin >> nend[i]; } for (int k = 0; k < ne + nne; k++) { if (k < ne) { sign[k] = endd[k]; } else { sign[k] = nend[k - ne]; } } for(int i=0;i a; vector b; int t; for (int q = 0; q < que[i].size(); q++) { t = que[i][q].find("."); if (t != que[i][q].length() - 1)//该产生式可以扩展 { m.insert(make_pair(que[i][q][t+1],q));//第q条产生式可扩展的非终结符 } } for (int x = 0; x < ne + nne; x++) { if (m.count(sign[x]) > 1)//有两条及以上具有相同非终结符扩展的产生式 { multimap::iterator mIter = m.find(sign[x]); for (int k = 0; k < m.count(sign[x]); k++, ++mIter) { a.push_back(mIter->second);//将集合SIter中元素插入到newSet中 b.push_back(mIter->second);//将集合SIter中元素插入到newSet中 } for (int x = 0; x < a.size(); x++) { t = que[i][a[x]].find("."); status.push_back(swap(que[i][a[x]], t, t + 1));//将第一条产生式入栈 } closure(status); if (common(que, status))//如果这是个新状态 { que.push_back(status); stateMap[i][inSignInt[sign[x]]] = zhuanhuan(que.size() - 1,sign[x]); } //若不是新状态 else { stateMap[i][inSignInt[sign[x]]] = zhuanhuan(order,sign[x]); } } status.erase(status.begin(), status.end()); a.erase(a.begin(), a.end()); } for (int j = 0; j < que[i].size(); j++) { if (usedj(j,b)) { status.erase(status.begin(), status.end()); int temp = que[i][j].find(".");//找到当前产生式.的位置 if (temp != que[i][j].length() - 1)//如果当前产生式可以拓展 { status.push_back(swap(que[i][j], temp, temp + 1));//将第一条产生式入栈 closure(status); cout << endl; //cout << common(que, status)<< endl; if (common(que, status))//如果这是个新状态 { //cout << que.size() << " "; que.push_back(status); //cout<
上一篇 大人,时代变了 | Ubuntu18.04 Openpose-GPU 极简安装手册
下一篇 C语言二维数组传参
版权所有 (c)2021-2022 MSHXW.COM
ICP备案号:晋ICP备2021003244-6号