#pragma once
#include
#include "head.h"
#include "auxiliary.h"
// 初始化First集合,生成终结符的集合,非终结符初始化为空
vector Initialize(vector gra) {
vector ini_set;
int len = gra.size();
// 遍历所有产生式
for (int i = 0; i < len; i++) {
// 判断左部的标识符是否已经有了初始化的First集
if (!have_set(gra[i].left, ini_set)) {
// 产生式左部一定是非终结符
ini_set.push_back(Set(Symbol(gra[i].left, 0))); // 将非终结符的First集初始化放入集合中
}
// 对于右部
int len2 = gra[i].rigth.size();
// 判断右部每一个标识符是否有初始化的First集
for (int j = 0; j < len2; j++) {
if (!have_set(gra[i].rigth[j].name, ini_set)) {
// 判断是否为终结符
if (gra[i].rigth[j].is_terminal == 1) {
// 如果是终结符,First集合为它自己
ini_set.push_back(Set(gra[i].rigth[j], gra[i].rigth[j]));
}
else if (gra[i].rigth[j].is_terminal == 0) {
// 如果是非终结符,First集合初始化为空
ini_set.push_back(Set(Symbol(gra[i].rigth[j].name, 0)));
}
else {
if (gra[i].rigth[j].is_terminal != 2) {
// 为2是空
if (gra[i].rigth[j].is_terminal == 3) {
// 3未初始化
cout << "产生式输入有未初始化的标识符,请检查后再尝试!" << endl;
}
else {
// 其他为错误
cout << "产生式输入有误,请检查后再尝试!" << endl;
}
}
}
}
}
}
return ini_set;
}
// 生成First集
vector GenerateFirst(vector gra) {
vector First = Initialize(gra); // 生成所有标识符初始化的First集
while (true) {
int start_num = getLength(First); // 开始集合总长度
// 对于每一个First集
int first_len = First.size();
for (int i = 0; i < first_len; i++) {
// 遍历每一条产生式
int gra_len = gra.size();
for (int j = 0; j < gra_len; j++) {
// 如果是非终结符并且左部和当前标识符相同
if (gra[j].left == First[i].name.name && First[i].name.is_terminal == 0) {
// 如果产生式右边第一个标识符为终结符或空
if (gra[j].rigth[0].is_terminal == 1 || gra[j].rigth[0].is_terminal == 2) {
// 如果集合中没有这个元素在当前First集中加上这个终结符或空
if (!haveElement(First[i], gra[j].rigth[0].name)) {
First[i].content.push_back(gra[j].rigth[0]);
}
}
// 如果是非终结符
else if (gra[j].rigth[0].is_terminal == 0) {
bool flag = false; // 标记
// 遍历右部元素
int right_length = gra[j].rigth.size();
for (int k = 0; k < right_length; k++) {
// 如果是非终结符
if (gra[j].rigth[k].is_terminal == 0) {
// 如果这个非终结符的First中有空,falg设置为真,否则为假
if (haveElement(findFirst(First, gra[j].rigth[k].name),"#")) { flag = true; }
else { flag = false; }
// 去空加到first集中
First[i].Append(removeEmpty(findFirst(First, gra[j].rigth[k].name).content));
}
// 如果有没有空的first,跳出循环
if (!flag) {
break;
}
// 如果遇到终结符,看flag
if (gra[j].rigth[k].is_terminal == 1) {
if (flag) {
if (!haveElement(First[i], gra[j].rigth[k].name)) {
// 如果遇到flag为真,并且first集中没有这个元素
First[i].content.push_back(gra[j].rigth[k]);
}
}
break;
}
}
// 如果遍历所有结果都符合,加入#
if (flag) {
if (!haveElement(First[i], "#")) {
First[i].content.push_back(Symbol("#", 2));
}
}
}
else {
cout << "产生式未初始化,或产生式输入有误" << endl;
}
}
}
}
int end_num = getLength(First); // 结束集合总长度
if (end_num <= start_num) {
break; // 如果集合长度停止增长,说明可以结束了
}
}
return First;
}
// 生成Follow集
vector GenerateFollow(vector gra, vector First) {
vector Follow;
// 初始化所有非终结符的Follow集
int f_len = First.size();
for (int i = 0; i < f_len; i++) {
if (First[i].name.is_terminal == 0) {
// 如果是开始的非终结符,初始化加上$
if (First[i].name.name == gra[0].left) {
Follow.push_back(Set(First[i].name, Symbol("$", 4)));
}
// 其他的非终结符初始化为空
else {
Follow.push_back(Set(First[i].name));
}
}
}
while (true) {
int start_num = getLength(Follow); // 开始集合总长度
// 对于每一个非终结符
int fo_len = Follow.size();
for (int i = 0; i < fo_len; i++) {
// 遍历每一个产生式
int gr_len = gra.size();
for (int j = 0; j < gr_len; j++) {
// 如果右部有这个元素
if (isIn(gra[j], Follow[i].name)) {
// 获取这个元素在集合中的
int ele_start = leftNum(gra[j], Follow[i].name).start;
int left_num = leftNum(gra[j], Follow[i].name).len;
// 如果后面没有,将产生式左部的Follow加到当前Follow中
if (left_num == 0) {
Follow[i].Append(findFollow(Follow, gra[j].left).content);
}
// 如果后面是终结符,将这个终结符加到当前Follow中
else if (gra[j].rigth[ele_start+1].is_terminal == 1) {
// 如果没有这个终结符,添加
if (!haveElement(Follow[i], gra[j].rigth[ele_start + 1].name)) {
Follow[i].content.push_back(gra[j].rigth[ele_start + 1]);
}
}
// 如果后面是非终结符
else if (gra[j].rigth[ele_start + 1].is_terminal == 0) {
bool flag = false; // 标记
// 遍历右部剩余的元素
int right_length = gra[j].rigth.size();
for (int k = ele_start + 1; k < right_length; k++) {
// 如果是非终结符
if (gra[j].rigth[k].is_terminal == 0) {
// 如果这个非终结符的First中有空,falg设置为真,否则为假
if (haveElement(findFirst(First, gra[j].rigth[k].name), "#")) { flag = true; }
else { flag = false; }
// 去空加到Follow集中
Follow[i].Append(removeEmpty(findFirst(First, gra[j].rigth[k].name).content));
}
// 如果有没有空的First,跳出循环
if (!flag) {
break;
}
// 如果遇到终结符,看flag
if (gra[j].rigth[k].is_terminal == 1) {
if (flag) {
if (!haveElement(Follow[i], gra[j].rigth[k].name)) {
// 如果遇到flag为真,并且Follow集中没有这个元素
Follow[i].content.push_back(gra[j].rigth[k]);
}
}
break;
}
}
// 如果右边所有标识符的First中都有空,将文法左部元素的Follow加入
if (flag) {
Follow[i].Append(findFollow(Follow, gra[j].left).content);
}
}
else {
cout << "产生式未初始化,或产生式输入有误" << endl;
}
}
}
}
int end_num = getLength(Follow); // 结束集合总长度
if (end_num <= start_num) {
break; // 如果集合长度停止增长,说明可以结束了
}
}
return Follow;
}
// 构造ll(1)分析表
LlTable createTable(vector gra, vector First, vector Follow) {
vector> ll_table;
vector rows;
vector columns;
// 终结符为列,非终结符为行
int first_len = First.size();
for (int i = 0; i < first_len; i++) {
if (First[i].name.is_terminal == 0) {
rows.push_back(First[i].name.name);
}
else if (First[i].name.is_terminal == 1) {
columns.push_back(First[i].name.name);
}
}
// 表项初始化为 -
int row_len = rows.size();
int column_len = columns.size();
for (int i = 0; i < row_len; i++) {
vector temp;
for (int j = 0; j < column_len; j++) {
temp.push_back("-");
}
ll_table.push_back(temp);
}
for (int i = 0; i < row_len; i++) {
ll_table[i].push_back("-");
}
//对于所有First集
for (int i = 0; i < first_len; i++) {
if (First[i].name.is_terminal == 0) {
// 对于First中的每个元素
int con_len = First[i].content.size();
for (int j = 0; j < con_len; j++) {
// 如果是终结符
if (First[i].content[j].is_terminal == 1) {
int gra_len = gra.size();
// 如果只有一个产生式
if (is_unque(gra, First[i].name.name)) {
// 遍历每一个产生式
for (int k = 0; k < gra_len; k++) {
if (gra[k].left == First[i].name.name) {
ll_table[getIndex(First[i].name, rows, columns)][getIndex(First[i].content[j], rows, columns)] = to_string(k + 1);
}
}
}
else {
// 遍历每一个产生式
for (int k = 0; k < gra_len; k++) {
// 如果名称相等并且左部第一个元素相同
if (gra[k].left == First[i].name.name && gra[k].rigth[0].name == First[i].content[j].name) {
ll_table[getIndex(First[i].name, rows, columns)][getIndex(First[i].content[j], rows, columns)] = to_string(k + 1);
}
}
}
}
// 如果是空
else if (First[i].content[j].is_terminal == 2) {
// 找对应的Follow集
int fo_len = Follow.size();
for (int k = 0; k < fo_len; k++) {
// 如果找到了
if (First[i].name.name == Follow[k].name.name) {
// 遍历Follow中所有元素
int fcon_len = Follow[k].content.size();
for (int m = 0; m < fcon_len; m++) {
ll_table[getIndex(First[i].name, rows, columns)][getIndex(Follow[k].content[m], rows, columns)] = "#";
}
}
}
}
else {
cout << "Error!" << endl;
}
}
}
}
LlTable table = LlTable(rows, columns, ll_table);
return table;
}
bool Verification(vector gra, vector sen, LlTable table, Node &root) {
stack s1;
stack s2; // 输入
stack tree; // 树结构
tree.push(&root); // 压入根节点
s1.push(Symbol("$", 4)); // 先压入$
s1.push(Symbol(gra[0].left, 0)); // 压入开始符号
s2.push(Symbol("$", 4));
ReverseOrder(s2, sen); // 将输入语句反序入栈
while (true) {
Symbol temp1 = s1.top(); // 两个栈的栈顶
Symbol temp2 = s2.top();
// 如果temp1为非终结符
if (temp1.is_terminal == 0) {
//Grammar temp_gra= gra[atoi(table.ll_table[getIndex(temp1,table.rows,table.columns)][getIndex(temp2, table.rows, table.columns)].c_str())];
// 查询ll分析表得出当前操作
string func = table.ll_table[getIndex(temp1, table.rows, table.columns)][getIndex(temp2, table.rows, table.columns)];
// 如果遇到"-",说明错误
if (func == "-") {
return false;
}
// 遇到空
else if (func == "#") {
// s1弹出栈顶
s1.pop();
tree.pop();
}
// 如果是产生式
else {
// 获取对应的产生式,下标要减一
Grammar temp_gra = gra[atoi(func.c_str()) - 1];
// s1弹出栈顶
s1.pop();
Node* pre = new Node();
int r_len = temp_gra.rigth.size();
for (int m = 0; m < r_len; m++) {
pre->name = temp_gra.rigth[m];
vector vec;
pre->vec = vec;
tree.top() -> vec.push_back(pre);
}
tree.pop();
// s1反序入栈产生式的右部
ReverseOrder(s1, temp_gra.rigth);
ReverseOrder2(tree, temp_gra.rigth);
}
}
// 如果是终结符
else if (temp1.is_terminal == 1) {
// 如果两个栈的栈顶相等
if (temp2.is_terminal == 1 && temp1.name == temp2.name) {
// 弹出栈顶
s1.pop();
tree.pop();
s2.pop();
}
else {
return false;
}
}
// 如果是$
else if (temp1.is_terminal == 4) {
// 如果输入栈顶也为$
if (temp2.is_terminal == 4) {
return true;
}
// 不为$
else {
return false;
}
}
}
}
#pragma once
#include "head.h"
// 判断标识符在Set集合中是否存在
bool have_set(string name, vector my_set) {
int len = my_set.size();
for (int i = 0; i < len; i++) {
if (my_set[i].name.name == name) {
return true;
}
}
return false;
}
// 获取所有标识符First/Follow集的长度
int getLength(vector s) {
int len = s.size();
int num = 0;
for (int i = 0; i < len; i++) {
int temp = s[i].content.size();
num += temp;
}
return num;
}
// 去标识符集合中的空
vector removeEmpty(vector vec) {
int len = vec.size();
for (int i = 0; i < len; i++) {
if (vec[i].name == "#") {
vector::iterator empty = vec.begin() + i;
vec.erase(empty);
break;
}
}
return vec;
}
// 在所有标识符的First集中找name的First集
Set findFirst(vector First, string name) {
int len = First.size();
for (int i = 0; i < len; i++) {
if (First[i].name.name == name) {
return First[i];
}
}
return Set();
}
// 判断某个First集中是否有某个元素
bool haveElement(Set first, string name) {
int len = first.content.size();
for (int i = 0; i < len; i++) {
if (first.content[i].name == name) {
return true;
}
}
return false;
}
// 判断产生式右部是否有某个元素
bool isIn(Grammar gra, Symbol sym) {
int len = gra.rigth.size();
for (int i = 0; i < len; i++) {
if (gra.rigth[i].name == sym.name) {
return true;
}
}
return false;
}
// 如果产生式右部有这个元素,获取后面还有的元素个数
backNum leftNum(Grammar gra, Symbol sym) {
int len = gra.rigth.size();
int k = 0;
for (int i = 0; i < len; i++) {
if (gra.rigth[i].name == sym.name) {
k = i;
break;
}
}
return backNum(k, len - k - 1);
}
// 在所有标识符的Follow集中找name的Follow集(和找First一样,因为不好取名字所以写了两个函数)
Set findFollow(vector Follow, string name) {
int len = Follow.size();
for (int i = 0; i < len; i++) {
if (Follow[i].name.name == name) {
return Follow[i];
}
}
return Set();
}
// 生成分析表时获取对应符号的下标
int getIndex(Symbol sym, vector rows, vector columns) {
if (sym.is_terminal == 0) {
int row_len = rows.size();
for (int i = 0; i < row_len; i++) {
if (rows[i] == sym.name) {
return i;
}
}
return -1;
}
else if (sym.is_terminal == 1) {
int col_len = columns.size();
for (int i = 0; i < col_len; i++) {
if (columns[i] == sym.name) {
return i;
}
}
return -1;
}
else if (sym.is_terminal == 4) {
int col_len = columns.size();
return col_len;
}
else {
return -1;
}
}
// 判断非终结符在产生式中有一条还是多条产生式
bool is_unque(vector gra, string name) {
int num = 0;
int len = gra.size();
for (int i = 0; i < len; i++) {
if (gra[i].left == name) {
num++;
}
}
if (num > 1) {
return false;
}
else {
return true;
}
}
// 反序入栈
void ReverseOrder(stack &s1,vector vec) {
int len = vec.size();
for (int i = len - 1; i >= 0; i--) {
s1.push(vec[i]);
}
}
void ReverseOrder2(stack &tree, vector vec) {
int len = vec.size();
for (int i = len - 1; i >= 0; i--) {
Node* temp = new Node();
temp->name = vec[i];
tree.push(temp);
}
}
#include
#include"function.h"
using namespace std;
void inputGrammar(vector& gra) {
vector right;
right.push_back(Symbol("T", 0)); right.push_back(Symbol("X", 0));
gra.push_back(Grammar("E", right)); // E -> TX
right.clear();
right.push_back(Symbol("(", 1)); right.push_back(Symbol("E", 0)); right.push_back(Symbol(")", 1));
gra.push_back(Grammar("T", right)); // T -> ( E )
right.clear();
right.push_back(Symbol("int", 1)); right.push_back(Symbol("Y", 0));
gra.push_back(Grammar("T", right)); // T -> intY
right.clear();
right.push_back(Symbol("+", 1)); right.push_back(Symbol("E", 0));
gra.push_back(Grammar("X", right)); // X -> +E
right.clear();
right.push_back(Symbol("#", 2));
gra.push_back(Grammar("X", right)); // X -> #
right.clear();
right.push_back(Symbol("*", 1)); right.push_back(Symbol("T", 0));
gra.push_back(Grammar("Y", right)); // Y -> *T
right.clear();
right.push_back(Symbol("#", 2));
gra.push_back(Grammar("Y", right)); // Y -> #
}
void printGrammar(vector gra) {
int len = gra.size();
for (int i = 0; i < len; i++) {
cout << "(" << i + 1 << ") ";
cout << gra[i].left << " " << "-> ";
int num = gra[i].rigth.size();
for (int j = 0; j < num; j++) {
cout << gra[i].rigth[j].name;
}
cout << endl;
}
}
void pringSet(vector First) {
int len = First.size();
for (int i = 0; i < len; i++) {
cout << First[i].name.name << ":{ ";
int len2 = First[i].content.size();
for (int j = 0; j < len2; j++) {
cout << First[i].content[j].name << " ";
}
cout << "}" << endl;
}
}
void printTable(LlTable table) {
int co_len = table.columns.size();
cout << " ";
for (int i = 0; i < co_len; i++) {
cout << " " << table.columns[i];
}
cout << " " << "$";
cout << endl;
int len1 = table.ll_table.size();
for (int i = 0; i < len1; i++) {
cout << table.rows[i] << " ";
int len2 = table.ll_table[i].size();
for (int j = 0; j < len2; j++) {
cout << table.ll_table[i][j] << " ";
}
cout << endl;
}
}
int main() {
vector gra;
inputGrammar(gra);
cout << "输入的产生式是:" << endl;
printGrammar(gra);
cout << endl;
cout << "First集" << endl;
vector First = GenerateFirst(gra);
pringSet(First);
cout << endl;
cout << "Follow集" << endl;
vector Follow = GenerateFollow(gra, First);
pringSet(Follow);
cout << endl;
cout << "ll分析表" << endl;
LlTable table = createTable(gra, First, Follow);
printTable(table);
cout << endl;
vector sen;
sen.push_back(Symbol("int", 1));
sen.push_back(Symbol("*", 1));
sen.push_back(Symbol("int", 1));
sen.push_back(Symbol("+", 1));
sen.push_back(Symbol("int", 1));
// sen = int * int + int
int sen_len = sen.size();
cout << "要匹配的句子是:";
for (int i = 0; i < sen_len; i++) {
cout << sen[i].name << " ";
}
cout << endl;
Node root = Node(gra[0].left);
if (Verification(gra, sen, table, root)) {
cout << "匹配成功" << endl;
}
else {
cout << "匹配失败" << endl;
}
// 生成语法树的根节点为root
return 0;
}
#pragma once
#include
#include "head.h"
using namespace std;
// 构造文法
vector createGrammar() {
vector Grammar;
vector right;
right.push_back(Symbol("A", 0));
Grammar.push_back(Production(Symbol("S", 0), right)); // S -> A
right.clear();
right.push_back(Symbol("A", 0)); right.push_back(Symbol("+", 1)); right.push_back(Symbol("B", 0));
Grammar.push_back(Production(Symbol("A", 0), right)); // A -> A + B
right.clear();
right.push_back(Symbol("a", 1));
Grammar.push_back(Production(Symbol("A", 0), right)); // A -> a
right.clear();
right.push_back(Symbol("b", 1));
Grammar.push_back(Production(Symbol("B", 0), right)); // B -> b
right.clear();
return Grammar;
}
//int getStatesLength(vector states) {
// int num = 0;
// int sLength = states.size();
// for (int i = 0; i < sLength; i++) {
// int iLength = states[i].items.size();
// for (int j = 0; j < iLength; j++) {
// num++;
// }
// }
// return num;
//}
// 获取终止符
Symbol getLookahead(Item item, int index) {
unsigned int iSize = item.production.rigth.size();
// 如果后面没有了,返回item的终止符
if (index + 1 >= iSize) {
return item.lookahead;
}
// 否则返回后面的那一个终结符
else {
return item.production.rigth[index + 1];
}
}
// 判断某个状态中是否有某个项
bool haveElement(State state, Item item) {
for (unsigned int i = 0; i < state.items.size(); i++) {
if (state.items[i].production.left.name == item.production.left.name && state.items[i].production.rigth.size() == item.production.rigth.size() && state.items[i].lookahead.name == item.lookahead.name) {
return true;
}
}
return false;
}
// 打印状态
void printItem(Item i) {
cout << i.production.left.name << "->";
for (unsigned int k = 0; k < i.production.rigth.size(); k++) {
cout << i.production.rigth[k].name;
}
cout << " index=" << i.index << " 终结符为" << i.lookahead.name;
}
// 判断两个vector是否相同
bool judge(vector a, vector b) {
int al = a.size();
int bl = b.size();
if (al != bl) {
return false;
}
else {
for (int i = 0; i < al; i++) {
if (a[i].name != b[i].name) {
return false;
}
}
}
return true;
}
// 在文法中找对应的归约下标
int findReduce(vector Grammar, Item i) {
for (unsigned int k = 0; k < Grammar.size(); k++) {
if (Grammar[k].left.name == i.production.left.name && judge(Grammar[k].rigth, i.production.rigth)) {
return k;
}
}
return -1;
}
// 判断输入的string是终结符还是非终结符
bool isEnd(string a, vector Grammar) {
for (unsigned int i = 0; i < Grammar.size(); i++) {
if (Grammar[i].left.name == a) {
return false;
}
}
return true;
}
// 判断s是否在vec中
bool isIn(vector vec, string s) {
for (unsigned int i = 0; i < vec.size(); i++) {
if (vec[i] == s) {
return true;
}
}
return false;
}
// 构造分析表获取列名,所有标识符
vector getSymbols(vector Grammar) {
vector res;
for (unsigned int i = 0; i < Grammar.size(); i++) {
for (unsigned int j = 0; j < Grammar[i].rigth.size(); j++) {
if (Grammar[i].rigth[j].is_terminal == 1) {
if (!isIn(res, Grammar[i].rigth[j].name)) {
res.push_back(Grammar[i].rigth[j].name); // 获取所有终结符
}
}
}
}
res.push_back("$");
for (unsigned int i = 1; i < Grammar.size(); i++) {
if (!isIn(res, Grammar[i].left.name)) {
res.push_back(Grammar[i].left.name); // 获取所有非终结符
}
}
return res;
}
// 获取下标
int getIndex(vector res, string a) {
for (unsigned int i = 0; i < res.size(); i++) {
if (res[i] == a) {
return i;
}
}
return -1;
}
// 根据传入的操作判断表应该填写什么内容
string writeTable(Option op) {
if (op.option == 1) { // 移进
if (op.symbol.is_terminal == 0) { // s?
string res = "g";
res += to_string(op.todo);
return res;
}
else { // g?
string res = "s";
res += to_string(op.todo);
return res;
}
}
else { // 归约 r?
if (op.todo == 0) {
return "ac";
}
else {
string res = "r";
res += to_string(op.todo);
return res;
}
}
}
// 打印LRtable
void printTable(LRTable LRtable) {
int state_num = LRtable.table.size();
int symbols_num = LRtable.symbols_vec.size();
cout << " ";
for (int i = 0; i < symbols_num; i++) {
cout << LRtable.symbols_vec[i] << " ";
}
cout << endl;
for (int i = 0; i < state_num; i++) {
cout << i << " ";
for (int j = 0; j < symbols_num; j++) {
cout << LRtable.table[i][j] << " ";
}
cout << endl;
}
}
// 产生式右部是否有非终结符
bool haveUnEnd(Production pro) {
int len = pro.rigth.size();
for (int i = 0; i < len; i++) {
if (pro.rigth[i].is_terminal == 0) {
return true;
}
}
return false;
}
// 多叉树的遍历
void tranversal(Node* root) {
vector nodes = root->vec;
for (int i = 0; i < nodes.size(); ++i) {
if (nodes[i]->vec.size() > 0)
tranversal(nodes[i]);
else
cout << nodes[i]->name.name << ",";
}
cout << root->name.name << ",";
}