- 实验目的
理解LR(1)语法分析方法的原理,掌握LR(1)分析表的构造,设计相关数据结构和程序结构,加深对自下而上语法分析方法的理解。
- 实验内容
需要实现的功能:
1)使用LR(1)分析方法构造识别活前缀的DFA;
2)构造文法的分析表(Action表和Goto表);
3)输入文法:文法描述存储在文本文件中,文件名作为命令行参数输入;
4)输出文法的项目集簇(标准输出设备);
5)输出识别活前缀的DFA(标准输出设备);
6)输出文法的Action表和Goto表(输出到创建的指定LR分析表文件,文件名与文法描述文件同名,扩展名为lrtbl);
7)输出文法是否是LR(1)文法的判断结果(标准输出设备)。
- 代码实现
#include<iostream>
#include<stack>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include <fstream>
using namespace std;
typedef char* symbol;
symbol empty = (symbol)"0";
symbol ed = (symbol)"#";
symbol dot = (symbol)".";
symbol acc = (symbol)"acc";
symbol shift = (symbol)"s";
symbol reduction = (symbol)"r";
int vnNum;
int vtNum;
int productionNum;
//非终结符
typedef struct vnSymbol{
symbol VnSymbol;
int idx;
vector<symbol> first;
vector<symbol> follow;
vnSymbol(): idx(0) {
VnSymbol = new char;
first.clear();
follow.clear();
}
~vnSymbol()
{
delete VnSymbol;
VnSymbol = nullptr;
}
}VnSymbol;
//终结符
typedef struct vtSymbol{
symbol VtSymbol;
int idx;
vtSymbol() :idx(0) {
VtSymbol = new char;
}
~vtSymbol()
{
delete VtSymbol;
VtSymbol = nullptr;
}
}VtSymbol;
typedef struct production{
symbol left; //产生式左部
vector<symbol> right; //产生式右部
vector<symbol> select;
vector<symbol> first;
int idx;
production() :idx(0) {
right.clear();
select.clear();
first.clear();
left = new char;
}
~production()
{
delete left;
left = nullptr;
}
}Production;
//文法四元组
typedef struct cfg{
vector<VnSymbol*> VNSet; //非终结符集
vector<VtSymbol*> VTSet; //终结符集
symbol S; //开始符号
vector<Production*> ProductionSet; //产生式集
cfg(){
VNSet.clear();
VTSet.clear();
ProductionSet.clear();
S = new char;
}
~cfg()
{
delete S;
S = nullptr;
}
} CFG;
CFG *cfg = new CFG();
void print_cfg(CFG *cfg); //打印文法相关信息
void create_first1(CFG *cfg); //构造每个非终结符的first集
void create_first2(CFG *cfg); //构造每个候选式的first集
void create_follow(CFG *cfg); //构造每个非终结符的follow集
void create_select(CFG *cfg); //构造每个产生式的select集
int isVnSymbol(CFG *cfg, symbol x); //判断x是否是非终结符,若是,是第几个
int isVtSymbol(CFG *cfg, symbol x); //判断x是否是终结符,若是,是第几个
bool haveEpsilon(CFG *cfg, int x); //判断空串ε是否在第x个非终结符的first集合中
bool haveEpsilon1(CFG *cfg, int x); //判断空串是否在第x个产生式右部的first集里面
void print_cfg(CFG *cfg)
{
cout << "CFG=(VN,VT,P,S)" << endl;
cout << "VN : " ;
for(int i = 0; i < vnNum; i++)
{
cout << cfg->VNSet[i]->VnSymbol << ' ';
}
cout << endl;
cout << "VT : ";
for(int i = 0; i < vtNum; i ++)
{
cout << cfg->VTSet[i]->VtSymbol << ' ';
}
cout << endl;
cout << "Production : " << endl;
for(int i = 0; i < productionNum; i++)
{
cout << '\t' << cfg->ProductionSet[i]->idx << " : " << cfg->ProductionSet[i]->left
<< " -> ";
for(int j = 0; j < cfg->ProductionSet[i]->right.size(); j ++)
{
cout << cfg->ProductionSet[i]->right[j] << ' ';
}
cout << endl;
}
cout << "StartSymbol : " << cfg->S << endl;
cout << endl;
}
void create_first1(CFG *cfg)
{
bool flag = true;
while(true)
{
if(!flag) break;
flag = false;
for(int i = 0; i < productionNum; i++)
{
symbol x = cfg->ProductionSet[i]->left;
// cout << "第" << i << "个产生式的左部是: " << x << endl;
int j = isVnSymbol(cfg, x);
// cout << "产生式左部" << x << "在非终结符集中是第" << j << "个" << endl;
if(j != -1)
{
symbol y = cfg->ProductionSet[i]->right[0];
// cout << "第" << i << "个产生式的右部第一个符号串是: " << y << endl;
if(!strcmp(y, empty)) {
vector<symbol>::iterator it;
it = find(cfg->VNSet[j]->first.begin(), cfg->VNSet[j]->first.end(), empty);
if(it == cfg->VNSet[j]->first.end())
{
cfg->VNSet[j]->first.push_back(y);
// cout << "右部是空串,添加成功" << endl;
flag = true;
}
}
else
{
int k = isVtSymbol(cfg, y);
//第一个符号串是终结符,直接加入到first集合里面去
if(k != -1) {
vector<symbol>::iterator it;
it = find(cfg->VNSet[j]->first.begin(), cfg->VNSet[j]->first.end(),y);
if(it == cfg->VNSet[j]->first.end())
{
cfg->VNSet[j]->first.push_back(y);
// cout << "右部第一个符号串是终结符,添加成功" << endl;
flag = true;
}
}
//第一个字符是非终结符
else
{
//从产生式右部的第一个元素开始遍历
int n;
for(n = 0; n < cfg->ProductionSet[i]->right.size(); n++)
{
y = cfg->ProductionSet[i]->right[n];
// m 表示非终结符y(如果是非终结符的话)在非终结符集中是第几个
int m = isVnSymbol(cfg, y);
//y是非终结符且y中含有空串
if(m != -1 && haveEpsilon(cfg, m))
{
for(int n = 0; n < cfg->VNSet[m]->first.size(); n++)
{
vector<symbol>::iterator it;
it = find(cfg->VNSet[j]->first.begin(), cfg->VNSet[j]->first.end(),cfg->VNSet[m]->first[n]);
if(strcmp(cfg->VNSet[m]->first[n],empty) && it ==cfg->VNSet[j]->first.end()){
cfg->VNSet[j]->first.push_back(cfg->VNSet[m]->first[n]);
// cout << "右部是Y1Y2...Yn类型, 添加成功" << endl;
flag = true;
}
}
}
if(m == -1) {
//说明y是终结符
vector<symbol>::iterator it;
it = find(cfg->VNSet[j]->first.begin(), cfg->VNSet[j]->first.end(),y);
if(it == cfg->VNSet[j]->first.end())
{
cfg->VNSet[j]->first.push_back(y);
// cout << "中间碰上终结符,添加成功" << endl;
flag = true;
}
break;
}
if(!haveEpsilon(cfg, m)) {
//说明y之前的串的first集都含有空串
for(int q = 0; q < cfg->VNSet[m]->first.size(); q++)
{
vector<symbol>::iterator it;
it = find(cfg->VNSet[j]->first.begin(), cfg->VNSet[j]->first.end(),cfg->VNSet[m]->first[q]);
if(it == cfg->VNSet[j]->first.end()){
cfg->VNSet[j]->first.push_back(cfg->VNSet[m]->first[q]);
// cout << "这一个非终结符的first集合里面没有空串, 添加成功" << endl;
flag = true;
}
}
break;
}
}
if(n == cfg->ProductionSet[i]->right.size())
{
vector<symbol>::iterator it;
it = find(cfg->VNSet[j]->first.begin(), cfg->VNSet[j]->first.end(),empty);
if(it == cfg->VNSet[j]->first.end())
{
cfg->VNSet[j]->first.push_back(empty);
// cout << "产生式右部能够推出空串,添加成功" << endl;
}
}
}
}
}
}
}
}
//文法任意候选式的首符集
void create_first2(CFG *cfg)
{
for(int i = 0; i < productionNum; i++)
{
//该产生式右部的第一个符号
symbol x = cfg->ProductionSet[i]->right[0];
if(!strcmp(x, empty)) cfg->ProductionSet[i]->first.push_back(empty);
else {
int k = isVtSymbol(cfg, x);
//这个候选式的第一个符号是终结符
if(k != -1) cfg->ProductionSet[i]->first.push_back(x);
//第一个符号是非终结符
else
{
int j;
for(j = 0; j < cfg->ProductionSet[i]->right.size(); j ++)
{
symbol y = cfg->ProductionSet[i]->right[j];
int m = isVnSymbol(cfg, y);
if(m != -1 && haveEpsilon(cfg, m))
{
for(int n = 0; n < cfg->VNSet[m]->first.size(); n ++)
{
vector<symbol>::iterator it;
it = find(cfg->ProductionSet[i]->first.begin(), cfg->ProductionSet[i]->first.end(), cfg->VNSet[m]->first[n]);
if(strcmp(cfg->VNSet[m]->first[n],empty) && it == cfg->ProductionSet[i]->first.end())
{
cfg->ProductionSet[i]->first.push_back(cfg->VNSet[m]->first[n]);
}
}
}
if(m==-1)
{
vector<symbol>::iterator it;
it = find(cfg->ProductionSet[i]->first.begin(), cfg->ProductionSet[i]->first.end(),y);
if(it == cfg->ProductionSet[i]->first.end())
{
cfg->ProductionSet[i]->first.push_back(y);
}
break;
}
if(!haveEpsilon(cfg, m))
{
for(int q = 0; q < cfg->VNSet[m]->first.size(); q++)
{
vector<symbol>::iterator it;
it = find(cfg->ProductionSet[i]->first.begin(), cfg->ProductionSet[i]->first.end(),cfg->VNSet[m]->first[q]);
if(it == cfg->ProductionSet[i]->first.end()){
cfg->ProductionSet[i]->first.push_back(cfg->VNSet[m]->first[q]);
}
}
break;
}
}
if(j == cfg->ProductionSet[i]->right.size())
{
vector<symbol>::iterator it;
it = find(cfg->ProductionSet[i]->first.begin(), cfg->ProductionSet[i]->first.end(),empty);
if(it == cfg->ProductionSet[i]->first.end())
{
cfg->ProductionSet[i]->first.push_back(empty);
}
}
}
}
}
}
void create_follow(CFG *cfg)
{
int x = isVnSymbol(cfg, cfg->S);
cfg->VNSet[x]->follow.push_back(ed);
// cout << "将结束符号" << ed << "加入到开始符号" << cfg->S << "的follow集中,添加成功" << endl;
bool flag = true;
while(true){
if(!flag) break;
flag = false;
for(int i = 0; i < productionNum; i ++)
{
for(int j = 0; j < cfg->ProductionSet[i]->right.size(); j ++)
{
symbol y = cfg->ProductionSet[i]->right[j];
// cout << "第" << i << "个产生式的右部的第" << j << "个符号是" << y << endl;
int m = isVnSymbol(cfg, y);
//是非终结符
if(m != -1) {
// cout << y << "是一个非终结符" << endl;
int k;
for(k = j + 1; k < cfg->ProductionSet[i]->right.size(); k++)
{
//是终结符
int n = isVtSymbol(cfg, cfg->ProductionSet[i]->right[k]);
if( n != -1)
{
// cout << y << "后面的符号" << cfg->ProductionSet[i]->right[k] << "是一个终结符" << endl;
vector<symbol>::iterator it;
it = find(cfg->VNSet[m]->follow.begin(),cfg->VNSet[m]->follow.end(),cfg->ProductionSet[i]->right[k]);
if(strcmp(cfg->ProductionSet[i]->right[k], empty) && it == cfg->VNSet[m]->follow.end()){
cfg->VNSet[m]->follow.push_back(cfg->ProductionSet[i]->right[k]);
// cout << "终结符" << cfg->ProductionSet[i]->right[k] << "要加到" << y << "的follow集中去,添加成功" << endl;
flag = true;
}
break;
}
//是非终结符
else
{
// cout << y << "后面的符号是非终结符" << cfg->ProductionSet[i]->right[k] << endl;
n = isVnSymbol(cfg, cfg->ProductionSet[i]->right[k]);
for(int p = 0; p < cfg->VNSet[n]->first.size(); p++)
{
vector<symbol>::iterator it;
it = find(cfg->VNSet[m]->follow.begin(), cfg->VNSet[m]->follow.end(),cfg->VNSet[n]->first[p]);
if(strcmp(cfg->VNSet[n]->first[p], empty) && it == cfg->VNSet[m]->follow.end())
{
cfg->VNSet[m]->follow.push_back(cfg->VNSet[n]->first[p]);
// cout << "把非终结符" << cfg->ProductionSet[i]->right[k] << " first集里的符号" << cfg->VNSet[n]->first[p] << "加入到" << y << "的follow集合中去,添加成功"<< endl;
flag = true;
}
}
if(!haveEpsilon(cfg, n)) {
// cout << "符号" << cfg->ProductionSet[i]->right[k] << "的first集中没有空串,要结束此次循环" << endl;
break;
}
}
}
// A -> αBβ first(β) 里面有 ε
if( k == cfg->ProductionSet[i]->right.size())
{
int n = isVnSymbol(cfg, cfg->ProductionSet[i]->left);
for(int p = 0; p < cfg->VNSet[n]->follow.size(); p ++)
{
vector<symbol>::iterator it;
it = find(cfg->VNSet[m]->follow.begin(), cfg->VNSet[m]->follow.end(), cfg->VNSet[n]->follow[p]);
if(it == cfg->VNSet[m]->follow.end())
{
cfg->VNSet[m]->follow.push_back(cfg->VNSet[n]->follow[p]);
// cout << cfg->ProductionSet[i]->left << "的follow集添加到符号" << y << "的follow集中,添加成功" << endl;
flag = true;
}
}
}
}
//A -> αB
if(j == cfg->ProductionSet[i]->right.size() - 1)
{
//最后一个字符是非终结符
if(m != -1)
{
int n = isVnSymbol(cfg, cfg->ProductionSet[i]->left);
for(int p = 0; p < cfg->VNSet[n]->follow.size(); p ++)
{
vector<symbol>::iterator it;
it = find(cfg->VNSet[m]->follow.begin(), cfg->VNSet[m]->follow.end(), cfg->VNSet[n]->follow[p]);
if(it == cfg->VNSet[m]->follow.end())
{
cfg->VNSet[m]->follow.push_back(cfg->VNSet[n]->follow[p]);
// cout << cfg->ProductionSet[i]->left << "的follow集添加到" << y << "的follow集中" << endl;
flag = true;
}
}
}
}
}
}
}
}
void create_select(CFG *cfg)
{
for(int i = 0; i < productionNum; i ++)
{
if(!haveEpsilon1(cfg, i))
{
for(int j = 0; j < cfg->ProductionSet[i]->first.size(); j++)
{
cfg->ProductionSet[i]->select.push_back(cfg->ProductionSet[i]->first[j]);
}
}
else {
for(int j = 0; j < cfg->ProductionSet[i]->first.size(); j++)
{
if(strcmp(cfg->ProductionSet[i]->first[j], empty))
{
cfg->ProductionSet[i]->select.push_back(cfg->ProductionSet[i]->first[j]);
}
}
int x = isVnSymbol(cfg, cfg->ProductionSet[i]->left);
for(int j = 0; j < cfg->VNSet[x]->follow.size(); j ++)
{
vector<symbol>::iterator it;
it = find(cfg->ProductionSet[i]->select.begin(), cfg->ProductionSet[i]->select.end(), cfg->VNSet[x]->follow[j]);
if(it == cfg->ProductionSet[i]->select.end())
{
cfg->ProductionSet[i]->select.push_back(cfg->VNSet[x]->follow[j]);
}
}
}
}
}
//判断某符号串在非终结符里面是第几个
int isVnSymbol(CFG *cfg, symbol x)
{
for(int i = 0; i < vnNum; i++)
{
if(!strcmp(x, cfg->VNSet[i]->VnSymbol)) return i;
}
return -1;
}
//判断某符号串在终结符集里面是第几个
int isVtSymbol(CFG *cfg, symbol x)
{
for(int i = 0; i < vtNum; i ++)
{
if(!strcmp(x, cfg->VTSet[i]->VtSymbol)) return i;
}
return -1;
}
//判断空串ε是否在第x个非终结符的first集合中
bool haveEpsilon(CFG * cfg, int x)
{
for(int i = 0; i < cfg->VNSet[x]->first.size(); i++)
{
if(!strcmp(cfg->VNSet[x]->first[i],empty)) return true;
}
return false;
}
//判断空串是否在第x个产生式右部的first集里面
bool haveEpsilon1(CFG *cfg, int x)
{
for(int i = 0; i < cfg->ProductionSet[x]->first.size(); i ++)
{
if(!strcmp(cfg->ProductionSet[x]->first[i], empty)) return true;
}
return false;
}
//项目
typedef struct item{
Production *p;
int position;
//展望串
vector<symbol> look_ahead;
//这个项目dot后面部分的first集合
vector<symbol> first;
item()
{
p = new Production;
look_ahead.clear();
first.clear();
}
~item()
{
delete p;
p = nullptr;
}
}Item;
typedef pair<int,symbol> PII;
typedef map<PII,int> DFA;
typedef pair<char *, int> PII2;
typedef map<PII, PII2> ACTION;
typedef map<PII,int> GOTO;
vector<symbol> symbols; //文法符号集
vector<vector<Item *> > itemSets; //项目集簇
int inIset(Item *I, vector<Item *> &itemSet); //判断某一个项目是否已经存在于项目集中
void create_first(Item *I, CFG *cfg); //构造dot后面串的first集合
void create_closure(CFG *cfg, vector<Item *> &itemSet); //构造项目集的闭包
int inISets(vector<item*> &itemSet); //判断某一个项目集是否已经存在于项目集簇(项目集簇是全局变量)
void create_dfa(CFG *cfg, DFA &dfa); //构造项目集簇和识别或前缀的DFA
void create_tables(DFA &dfa, ACTION &action, GOTO &go2); //构造action表和goto表
int main(int argc, char *argv[])
{
/*
* 处理文法
*/
if(!freopen(argv[1], "r", stdin))
{
printf("文件打开失败\n");
return 0;
}
//读入非终结符
scanf("%d",&vnNum);
for(int i = 0; i < vnNum; i ++)
{
VnSymbol *vn = new VnSymbol;
scanf("%s",vn->VnSymbol);
vn->idx = i;
cfg->VNSet.push_back(vn);
}
//读入终结符
scanf("%d",&vtNum);
for(int i = 0; i < vtNum; i ++)
{
VtSymbol *vt = new VtSymbol;
vt->idx = i;
scanf("%s",vt->VtSymbol);
cfg->VTSet.push_back(vt);
}
//读入产生式
scanf("%d",&productionNum);
for(int i = 0; i < productionNum; i++)
{
Production *p = new Production;
char *r = new char;
p->idx = i;
scanf("%s -> %s",p->left, r);
if(!strcmp(r,empty)) p->right.push_back(empty);
else p->right.push_back(r);
while(getchar() != '\n')
{
char *r1 = new char;
scanf("%s",r1);
if(!strcmp(r1,empty)) p->right.push_back(empty);
else p->right.push_back(r1);
}
cfg->ProductionSet.push_back(p);
}
scanf("%s",cfg->S);
fclose(stdin);
//输出文法相关信息
print_cfg(cfg);
//把文法符号拿出来存储
symbols.push_back(ed);
for(int i = 0; i < vtNum; i ++)
{
symbols.push_back(cfg->VTSet[i]->VtSymbol);
}
for(int i = 0; i < vnNum; i ++)
{
symbols.push_back(cfg->VNSet[i]->VnSymbol);
}
DFA dfa;
create_dfa(cfg, dfa);
//输出项目集簇
cout << "[LR(1) item set cluster]" << endl;
for(int i = 0; i < itemSets.size(); i++)
{
cout << "I" << i << ":" << endl;
for(int j = 0; j < itemSets[i].size(); j++)
{
int d = itemSets[i][j]->position;
cout << " " << itemSets[i][j]->p->left << "->" ;
for(int k = 0; k < itemSets[i][j]->p->right.size(); k++)
{
if(k == d) cout << ". ";
cout << itemSets[i][j]->p->right[k] << ' ';
}
if(d == itemSets[i][j]->p->right.size()) cout << "." ;
cout << ", ";
for(int k = 0; k < itemSets[i][j]->look_ahead.size(); k++)
{
cout << itemSets[i][j]->look_ahead[k] << ' ';
}
cout << endl;
}
cout << endl;
}
//输出识别活前缀的DFA
cout << "[LR(1) state tran function]" << endl;
for(auto it : dfa)
{
cout << it.first.first << " , " << it.first.second << " -> " << it.second << endl;
}
cout << "文法是LR(1)文法!" << endl;
ACTION action;
GOTO go2;
create_tables(dfa, action, go2);
//分析表文件输出
//freopen("tables.lrtbl", "w", stdout);
std::string fn(argv[1]);
fn.erase(fn.find("txt") , strlen("txt"));
fn.append("lrtbl");
//std::ifstream inputFile(fileName);
std::ofstream outputFile(fn);
outputFile<< "Action:\n"<< action.size() << endl;
for(auto it : action)
{
outputFile<< it.first.first << ' ' << it.first.second << ' ' << it.second.first << it.second.second << endl;
}
outputFile<< endl;
outputFile<< "Goto: " << go2.size() << endl;
for(auto it : go2)
{
outputFile<< it.first.first << ' ' << it.first.second << ' ' << it.second << endl;
}
fclose(stdout);
return 0;
}
//构造项目集簇和识别或前缀的DFA
void create_dfa(CFG *cfg, DFA &dfa)
{
Item *I = new Item;
vector<Item *> itemSet;
I->p = cfg->ProductionSet[0];
I->position = 0;
I->look_ahead.push_back(ed);
create_first(I, cfg);
itemSet.push_back(I);
create_closure(cfg, itemSet);
int idx = 0; //项目集的编号
itemSets.push_back(itemSet), idx ++;
for(int i = 0; i < itemSets.size(); i++)
{
for(int j = 0; j < symbols.size(); j ++)
{
// cout << endl;
// cout << "当文法符号是" << symbols[j] << "的时候" << endl;
vector<Item *> itemSet;
for(int k = 0; k < itemSets[i].size(); k ++)
{
int d = itemSets[i][k]->position;
// cout << "第" << i << "个项目集的第" << k << "项目, 点的位置在" << d << endl;
// cout << "项目右部的长度是 " << itemSets[i][k]->p->right.size() << endl;
if(d < itemSets[i][k]->p->right.size())
{
// cout << "点右边的文法符号是" << itemSets[i][k]->p->right[d] << endl;
if(!strcmp(symbols[j], itemSets[i][k]->p->right[d]))
{
item *I = new item;
I->p = itemSets[i][k]->p;
I->position = itemSets[i][k]->position + 1;
I->look_ahead = itemSets[i][k]->look_ahead;
create_first(I, cfg);
itemSet.push_back(I);
// cout << "-------将项目添加到项目集中-----------" << endl;
}
}
}
if(!itemSet.empty())
{
// cout << "构造项目集itemSet的项目集闭包" << endl;
create_closure(cfg, itemSet);
// cout << "构造成功" << endl;
PII p;
p.first = i, p.second = symbols[j];
int m = inISets(itemSet);
if(m == -1)
{
itemSets.push_back(itemSet);
// cout << "添加到项目集簇成功" << endl;
dfa.insert(pair<PII,int>(p, idx++));
// cout << "添加到DFA成功"<< endl;
}
else
{
dfa.insert(pair<PII,int>(p, m));
// cout << "添加到DFA成功"<< endl;
}
}
}
}
}
//判断某一个项目集是否已经存在于项目集簇(项目集簇是全局变量)
int inISets(vector<item*> &itemSet)
{
for(int i = 0 ; i < itemSets.size(); i ++)
{
if(itemSet. size() != itemSets[i].size()) continue;
//判断项目集和项目集簇中的第i个项目集是否相等
int j;
for(j = 0; j < itemSet.size(); j ++)
{
Production *p = itemSet[j]->p;
int d = itemSet[j]->position;
//判断两个项目是否相同
int k;
for(k = 0; k < itemSets[i].size(); k++)
{
bool flag = false;
if(itemSets[i][k]->p == p && itemSets[i][k]->position == d && itemSet[j]->look_ahead.size() == itemSets[i][k]->look_ahead.size())
{
int m;
for(m = 0; m < itemSet[j]->look_ahead.size(); m++)
{
auto it = find(itemSets[i][k]->look_ahead.begin(), itemSets[i][k]->look_ahead.end(), itemSet[j]->look_ahead[m]);
if(it == itemSets[i][k]->look_ahead.end())
{
break;
}
}
if(m == itemSet[j]->look_ahead.size())
{
flag = true;
}
}
if(flag) break;
}
if(k >= itemSets[i].size())
{
break;
}
}
//说明找着了
if(j >= itemSet.size())
{
return i;
}
}
return -1;
}
//构造项目集的闭包
void create_closure(CFG *cfg, vector<Item *> &itemSet)
{
for(int i = 0; i < itemSet.size(); i++)
{
int d = itemSet[i]->position;
if(d >= itemSet[i]->p->right.size()) return;
if(isVnSymbol(cfg, itemSet[i]->p->right[d]) != -1)
{
symbol vn = itemSet[i]->p->right[d];
for(int j = 0; j < productionNum; j++)
{
if(!strcmp(vn, cfg->ProductionSet[j]->left))
{
Item *I = new Item;
I->p = cfg->ProductionSet[j];
I->position = 0;
int m = inIset(I, itemSet);
//该项目在这个项目集中是否出现过
if(m != -1)
{
for(int k = 0; k < itemSet[i]->first.size(); k++)
{
symbol x = itemSet[i]->first[k];
for(int n = 0; n < itemSet[m]->look_ahead.size(); n ++)
{
if(strcmp(x, itemSet[m]->look_ahead[n]) != 0)
{
itemSet[m]->look_ahead.push_back(x);
}
}
}
create_first(itemSet[m], cfg);
}
else
{
for(int k = 0; k < itemSet[i]->first.size(); k++)
{
I->look_ahead.push_back(itemSet[i]->first[k]);
}
create_first(I, cfg);
itemSet.push_back(I);
}
}
}
}
}
}
//判断某一个项目是否已经存在于项目集中
int inIset(Item *I, vector<Item *> &itemSet)
{
for(int i = 0; i < itemSet.size(); i ++)
{
//同一个产生式并且dot的位置相同
if(I->p == itemSet[i]->p && I->position == itemSet[i]->position) return i;
}
return -1;
}
//构造dot后面串的first集合
void create_first(Item *I, CFG *cfg)
{
int d = I->position;
if(d < I->p->right.size())
{
if(isVtSymbol(cfg, I->p->right[d]) != -1) return;
}
if(d + 1 >= I->p->right.size())
{
for(int i = 0; i < I->look_ahead.size(); i ++)
{
auto it = find(I->first.begin(), I->first.end(), I->look_ahead[i]);
if(it == I->first.end())
{
I->first.push_back(I->look_ahead[i]);
}
}
}
else
{
symbol x = I->p->right[d+1];
int k = isVtSymbol(cfg, x);
if(k != -1)
{
auto it = find(I->first.begin(), I->first.end(), x);
if(it == I->first.end())
{
I->first.push_back(x);
}
}
else
{
int i;
for(i = d + 1; i < I->p->right.size(); i++)
{
symbol y = I->p->right[i];
int m = isVnSymbol(cfg, y);
if(m != -1 && haveEpsilon(cfg, m))
{
for(int j = 0; j < cfg->VNSet[m]->first.size(); j++)
{
auto it = find(I->first.begin(), I->first.end(), cfg->VNSet[m]->first[j]);
if(it == I->first.end())
{
if(strcmp(empty, cfg->VNSet[m]->first[j]))
{
I->first.push_back(cfg->VNSet[m]->first[j]);
}
}
}
}
if(m == -1)
{
auto it = find(I->first.begin(), I->first.end(), y);
if(it == I->first.end())
{
I->first.push_back(y);
}
break;
}
if(!haveEpsilon(cfg, m))
{
for(int n = 0; n < cfg->VNSet[m]->first.size(); n ++)
{
auto it = find(I->first.begin(), I->first.end(), cfg->VNSet[m]->first[n]);
if(it == I->first.end())
{
I->first.push_back(cfg->VNSet[m]->first[n]);
}
}
break;
}
}
if( i == I->p->right.size())
{
for(int j = 0; j < I->look_ahead.size(); j++)
{
auto it = find(I->first.begin(), I->first.end(), I->look_ahead[j]);
if(it == I->first.end())
{
I->first.push_back(I->look_ahead[j]);
}
}
}
}
}
}
//构造action表和goto表
void create_tables(DFA &dfa, ACTION &action, GOTO &go2)
{
for(int i = 0; i < itemSets.size(); i ++)
{
//移入处理
for(int j = 0; j < symbols.size(); j ++)
{
if(isVtSymbol(cfg, symbols[j]) != -1)
{
PII p1(i,symbols[j]);
if(dfa.find(p1) != dfa.end())
{
PII2 p2;
p2.first = (char *)"s";
p2.second = dfa[p1];
action.insert(pair<PII,PII2>(p1,p2));
}
}
else
{
PII p1(i, symbols[j]);
if(dfa.find(p1) != dfa.end())
{
int status = dfa[p1];
go2.insert(pair<PII,int>(p1,status));
}
}
}
//接收和归约处理
for(int j = 0; j < itemSets[i].size(); j ++)
{
if(!strcmp(itemSets[i][j]->p->left, cfg->S) && itemSets[i][j]->position == 1)
{
PII p1(i,ed);
PII2 p2;
p2.first = (char *)"acc";
p2.second = 0;
action.insert(pair<PII,PII2>(p1,p2));
}
if(itemSets[i][j]->position == itemSets[i][j]->p->right.size() && strcmp(itemSets[i][j]->p->left, cfg->S) != 0)
{
for(int k = 0; k < itemSets[i][j]->look_ahead.size(); k++)
{
PII p1(i, itemSets[i][j]->look_ahead[k]);
PII2 p2;
p2.first = (char *)"r";
p2.second = itemSets[i][j]->p->idx;
action.insert(pair<PII,PII2>(p1,p2));
}
}
}
}
}
运行结果