// 语法生成器
#ifndef GRAMMAR_H
#define GRAMMAR_H


#include <string>
#include <vector>
#include <map>
#include <unordered_set>
#include <unordered_map>

using namespace std;

class Grammar
{
public:
	const string grammar_file = "./tests/grammar.txt";
	
	Grammar();
	~Grammar();
	void read_grammar();									// 读取语法规则
	void print_grammar();									// 打印语法规则
	void expand_grammar();									// 拓展语法规则
	void init_grammar_set();								// 初始化语法相关集合
	void print_grammar_set();								// 打印语法相关集合
	void get_token_strings(vector<string> &);				// 获取 token_stirngs
	void print_token_strings();

protected:
	vector<pair<string, vector<string>>> grammar_rules;		// 产生式规则
	string start;											// 起始字符
	vector<string> symbols;									// 符号
	vector<string> VTs;										// 终结符								
	vector<string> VNs;										// 非终结符
	unordered_map<string, vector<string>> first;			// FIRST 集
	unordered_map<string, vector<string>> follow;			// FOLLOW 集
	unordered_map<string, bool> infer_empty;				// 是否可以推导出 $ 空字符
	vector<string> token_strings;


private:
	unordered_map<string, vector<int>> left_appears;		// 该符号出现在哪些产生式左侧
	unordered_map<string, vector<int>> right_appears;		// 该符号出现在哪些产生式右侧
	unordered_map<string, vector<string>> depend;			// FOLLOW 集的依赖关系
	

	void init_appears_depend();								// 获取 appear depend 集合
	bool symbol_infer_empty(const string& symbol);			// 判断符号是否可以推导出 $ 空字符
	vector<string> symbol_infer_first(const string& symbol);// 推导符号的 FIRST 集
	vector<string> symbol_infer_follow(const string& symbol);// 推导符号的 FOLLOW 集

};


#endif // !GRAMMAR_H