精华内容
下载资源
问答
  • 给定文法,构造FIRST集、FOLLOW集的构造的C代码和我个人的实验报告
  • 输入任意的上下文无关文法,输出所输入的上下文无关文法一切非终结符的first集合和follow集合 输入任意的上下文无关文法,输出所输入的上下文无关文法一切非终结符的first集合和follow集合
  • 代码链接:https://pan.baidu.com/s/1VNdrSMXaKu3HI0UQ_TInUQ 提取码:b1qz 使用教程 解压后打开文件夹,直接用Dev c++运行LL1,如图: 即可实现。 一分钱都不要啊, 比那些要C币的都好,点个赞呗亲们!!! ...

    DEV C++ 项目实现 不会建项目的看这个——>如何创建项目


    代码链接:https://pan.baidu.com/s/1VNdrSMXaKu3HI0UQ_TInUQ

    提取码:b1qz


    使用教程

    解压后打开文件夹,直接用Dev c++运行LL1,如图:
    在这里插入图片描述

    即可实现。


    一分钱都不要呀, 比需要C币下载的资源都好,点个赞呗!

    展开全文
  • ( 编译原理JAVA求First集Follow集
  • 编译原理用C语言求first集sellect集follow集,最后,判断给出的文法是否是LL(1)文
  • C++实现first集follow集

    千次阅读 2019-11-10 18:54:38
    代码存在很多问题,大量“非正常”情况都未考虑,谨慎参考 #include<iostream> #include<vector> #include<string> #include<fstream> using namespace std; str...

    1.“@”代替字符“ε”
    2.同一非终结符如有多条产生式必须写成一行,中间用“|”分隔,不允许有空格
    代码存在很多问题,大量“非正常”情况都未考虑,谨慎参考

    #include<iostream>
    #include<vector>
    #include<string>
    #include<fstream>
    
    using namespace std;
    
    struct exp{
    	char ter;	//终结符 
    	bool e = false;	//是否能产生空转(用@表示) 
    	vector<string> nonter;	//非终结符 
    };
    vector<exp> v;	//产生式集合 
    
    string T = "";	//终结符集合 
    string first[20];	//所有非终结符的first集 
    string f ="";	//follow集 
    
    //将文件中的文法转换成产生式 
    void fun1(string str){
    	exp e;
    	e.ter = str[0];
    	int i = 3;
    	for(int k = i;k <str.length();k++){
    		if(str[k] == '|'){
    			e.nonter.push_back(str.substr(i,k-i));
    			i = k + 1;
    		} else if(str[k] == '@'){
    			e.e = true;		//存在@(即空转) 
    			i = k + 2;
    			k++;
    		}
    	}
    	if(i < str.length()){
    		e.nonter.push_back(str.substr(i));
    	}
    	
    	v.push_back(e);
    	T = T + str[0];
    }
    
    //求first集 
    void fun3(int p,exp e,int index){
    	for(int k = 0;k < e.nonter.size();k++){
    		for(int i = index;i < e.nonter[k].length();i++){
    			if(e.nonter[k][i] >= 'a'&&e.nonter[k][i] <= 'z'){
    				first[p] += e.nonter[k][i];
    				break;
    			} else if(e.nonter[k][i] >= 'A'&&e.nonter[k][i] <= 'Z'){
    				int j = T.find(e.nonter[k][i]);
    				if(v[j].e){
    					fun3(p,v[j],0);
    					first[p] += '@';
    				}else{
    					fun3(p,v[j],0);
    					break;
    				}
    			}
    		}
    	}
    	
    }
    void fun2(){
    	for(int i = 0;i < v.size();i++){
    		exp e = v[i];
    		fun3(i,e,0);
    	}
    }
    
    //求follow集 
    void follow(char a){
    	for(int i = 0;i < T.length();i++){
    		for(int k = 0;k < v[i].nonter.size();k++){
    			if(v[i].nonter[k].find(a) != string::npos){
    				int j = v[i].nonter[k].find(a);
    				if(j == v[i].nonter[k].length()-1){
    					follow(T[i]);
    				} else if(j < v[i].nonter[k].length()-1){
    					char p = v[i].nonter[k][j+1];
    					if(p >= 'a' && p <= 'z'){
    						f += p;
    					} else{
    						int m = 0;
    						for(;m < T.length();m++){
    							if(T[m] == p){
    								f = first[m];
    							}
    						}	
    						if(first[m].find('@') != string::npos){
    							follow(T[i]);
    						}
    					}	
    				}
    			}
    		}
    	}
    }
    
    int main(){
    	ifstream open("D:\\1.txt");
    	string str;
    	if(!open.is_open())
    		cout<<"open file failed"<<endl;
    	while(getline(open,str)){
    		fun1(str);
    	}
    	open.close();
    	fun2();
    	cout<<"first集如下:"<<endl;
    	for(int len = 0;len < T.length();len++){
    		if(v[len].e){
    			first[len] += '@';
    		}
    		cout<<T[len]<<": "<<first[len]<<endl;
    	}
    	cout<<"输入非终结符:"<<endl;
    	char a;
    	cin>>a;
    	follow(a);
    	if(T.find(a) != string::npos){
    		f += '$';
    	}
    	string::iterator it;
    	//除去@,因为follow集中不能有@(空转) 
        for (it = f.begin(); it < f.end(); it++)
        {
            if (*it == '@')
            {
                str.erase(it);
                it--;
            }
        }
    	cout<<a<<"的follow集:"<<f<<endl;
    	return 0;
    }
    

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 编译原理------C++实现求First集和Follow集

    千次阅读 多人点赞 2019-12-06 20:39:54
    First集算法描述 1.若X->a…,则将终结符a放入First(X)中 2.若X->ε,则将ε放入First(X)中 3.若有X->Y1Y2Y3…Yk,则 (1)把First(Y1)去掉 ε后加入First(X) (2)如果First(Y1)包含ε,则...

    First集算法描述

    1.若X->a…,则将终结符a放入First(X)中
    2.若X->ε,则将ε放入First(X)中
    3.若有X->Y1Y2Y3…Yk,则
    (1)把First(Y1)去掉 ε后加入First(X)
    (2)如果First(Y1)包含ε,则把First(Y2)也加入到First(X)中,以此类推,直到某一个非终结符Yn的First集中不包含ε
    (3)如果First(Yk)中包含ε,即Y1~Yn都有ε产生式,就把ε加入到First(X)中

    Follow集算法描述

    1.对于文法开始符号S,把$加入到Follow(S)中
    2.若有A->aBC,则将First(C)中除了ε之外的元素加入到Follow(B)(此处a可以为空)
    3.若有A->aB或者A->aBC且ε属于first(C),则将Follow(A)加入到follow(B)中(此处a可以为空)
    4.若有A->Bc,则直接将c加入follow(B)中
    follow集中不含有空串ε

    代码

    代码说明

    1.原产生式存于文件中
    2.终结符只能用一个小写字母表示
    3.产生式内不可以有空格
    4.ε用#代替
    5.代码没有实现消除左递归和二义性,所以产生式必须为消除左递归和二义性的
    6.暂时看来代码没什么问题(可以准确求出first集和follow集),有问题请指正。

    #include<iostream>
    #include<string>
    #include<set>
    #include<map>
    #include <Windows.h>
    #include <fstream>
    
    using namespace std;
    
    /*
    所有非终结符均为单个字符,#代表空串
    E->TE'
    E'->+TE'|#
    T->FT'
    T'->*FT'|#
    F->(E)|i
    */
    
    class FF {
    public:
    	string fileName = "productions.txt";
    	set<string> productions;//产生式集合
    	map<string, set<string>> split_productions;//分解后的产生式集合
    	set<string> Vt;//终结符集合
    	set<string> Vn;//非终结符集合
    	map<string, set<string>> first;//First集
    	map<string, set<string>> follow;//Follow集
    
    	void init();//从文件读取产生式
    	void splitProductions();//分解产生式
    	void findVtAndVn();//获得终结符和非终结符
    	bool isVn(string s);
    	bool isVt(string s);
    	set<string> getOneFirst(string s);//获得单个非终结符first集
    	void getFirst();//获得所有非终结符first集
    	void getFollow();//获得所有非终结符follow集
    	void SSS();//求folloe集的步骤3
    };
    
    void FF::init() {
    	string line;
    	ifstream in(fileName);
    	if (in) {
    		//文法开始符号的follow集中放入$
    		getline(in, line);
    		productions.insert(line);
    		follow[line.substr(0, 1)].insert("$");
    		cout << line << endl;
    		while (getline(in, line)) {
    			productions.insert(line);
    			cout << line << endl;
    		}
    	}
    }
    void FF::splitProductions() {
    	int position = 0;
    	for (set<string>::iterator it = productions.begin(); it != productions.end(); it++) {
    		string temp = *it;
    		for (int i = 0; i < temp.length(); i++) {
    			position = temp.find("->");
    			string s = temp.substr(0, position);
    			string ss = temp.substr(position + 2);
    			set<string>sss;
    			string t;
    			for (int j = 0; j < ss.length(); j++) {
    				if (ss[j] == '|') {
    					sss.insert(t);
    					t = "";
    				}
    				else
    				{
    					t.append(ss.substr(j,1));
    				}
    				
    			}
    			sss.insert(t);
    			split_productions.insert(pair<string, set<string>>(s, sss));
    		}
    	}
    	for (map<string, set<string>>::iterator it = split_productions.begin(); it != split_productions.end(); it++) {
    		cout << it->first << "    ";
    		for (set<string>::iterator ii = it->second.begin(); ii != it->second.end(); ii++) {
    			cout << *ii << "    ";
    		}
    		cout << endl;
    	}
    
    
    }
    void FF::findVtAndVn() {
    	for (set<string>::iterator it = productions.begin(); it != productions.end(); it++) {
    		string temp = *it;
    		for (int i = 0; i < temp.length(); i++) {
    			if (temp[i] == '-' || temp[i] == '>' || temp[i] == '|')
    				continue;
    			//是大写字母
    			if (temp[i] >= 'A' && temp[i] <= 'Z') {
    				//后面带'
    				if (temp[i + 1] == '\'') {
    					Vn.insert(temp.substr(i, 2));
    					i++;
    				}
    				else {
    					Vn.insert(temp.substr(i, 1));
    				}
    			}
    			//是终结符
    			else
    			{
    				Vt.insert(temp.substr(i, 1));
    			}
    		}
    	}
    
    	cout << "非终结符" << endl;
    	for (set<string>::iterator it = Vn.begin(); it != Vn.end(); it++) {
    		cout << *it << endl;
    	}
    
    	cout << "终结符" << endl;
    	for (set<string>::iterator it = Vt.begin(); it != Vt.end(); it++) {
    		cout << *it << endl;
    	}
    }
    bool FF::isVn(string s) {
    	if (Vn.find(s) != Vn.end()) {
    		return true;
    	}
    	return false;
    }
    bool FF::isVt(string s) {
    	if (Vt.find(s) != Vt.end()) {
    		return true;
    	}
    	return false;
    }
    set<string> FF::getOneFirst(string s) {
    	if (split_productions.count(s)>0) {
    		set<string>temp = split_productions[s];
    		for (set<string>::iterator it = temp.begin(); it != temp.end(); it++) {
    			string stemp = *it;
    			if (stemp == "#") {
    				first[s].insert("#");
    			}
    			else {
    				int flagAll = 0;//所有的非终结符的first集都有#;
    				for (int i = 0; i < stemp.length(); i++) {
    					int flag = 0;//当前的非终结符的first集有#;
    					if (stemp[i+1] == '\'') {//带'的非终结符
    						set<string>t1 = getOneFirst(stemp.substr(i, 2));
    						for (set<string>::iterator ii = t1.begin(); ii !=  t1.end(); ii++) {
    							if (*ii == "#") {//此时空串不可插入
    								flag = 1;
    							}
    							else {
    								first[s].insert(*ii);
    							}
    						}
    						i++;
    					}
    					else if(isVn(stemp.substr(i,1)))//单个非终结符
    					{
    						set<string>t2 = getOneFirst(stemp.substr(i, 1));
    						for (set<string>::iterator ii = t2.begin(); ii != t2.end(); ii++) {
    							if (*ii == "#") {//此时空串不可插入
    								flag = 1;
    							}
    							else {
    								first[s].insert(*ii);
    							}
    						}
    					}
    					else {//终结符
    						first[s].insert(stemp.substr(i, 1));
    					}
    					if (i == stemp.length() - 1 && flag==1) {
    						flagAll = 1;
    					}
    					if (flag == 0)
    						break;
    
    				}
    				if (flagAll == 1) {
    					first[s].insert("#");
    				}
    			}
    		}
    	}
    	return first[s];
    }
    void FF::getFirst() {
    	for (map<string, set<string>>::iterator it = split_productions.begin(); it != split_productions.end(); it++) {
    		getOneFirst(it->first);
    	}
    	cout << "First集" << endl;
    	for (map<string, set<string>>::iterator it = first.begin(); it != first.end(); it++) {
    		cout << it->first << "  :  "  ;
    		for (set<string>::iterator ii = it->second.begin(); ii != it->second.end(); ii++)
    		{
    			cout << *ii << "    ";
    		}
    		cout << endl;
    	}
    
    }
    void FF::getFollow() {
    	for (map<string, set<string>>::iterator it = split_productions.begin(); it != split_productions.end(); it++) {
    		string left = it->first;
    		set<string>right = it->second;
    		for (set<string>::iterator ii = right.begin(); ii != right.end(); ii++) {
    			string temp = *ii;
    			
    			for (int i = 0; i < temp.length(); i++) {
    				if (isVt(temp.substr(i, 1))) {//终结符
    					continue;
    				}
    				else if (i+1<temp.length()&&temp[i + 1] == '\'') {//带有’的非终结符
    					if (isVt(temp.substr(i + 2, 1))) {//非终结符后面是终结符
    						follow[temp.substr(i, 2)].insert(temp.substr(i + 2, 1));
    						i++;
    					}
    					else {//非终结符后面是非终结符s
    						//把后面非终结符的first集ff加入follow集中
    						string s;
    						if (i+3<temp.length()&& temp[i + 3] == '\'') {
    							s = temp.substr(i + 2, 2);
    						}
    						else {
    							s = temp.substr(i + 2, 1);
    						}
    						set<string> ff = first[s];
    						for (set<string>::iterator nn = ff.begin(); nn != ff.end(); nn++) {
    							if (*nn != "#")
    								follow[temp.substr(i, 2)].insert(*nn);
    						}
    					}
    				}
    				else {//不带’的非终结符
    					
    					if (i+1<temp.length() && isVt(temp.substr(i + 1, 1))) {//非终结符后面是终结符
    						follow[temp.substr(i, 1)].insert(temp.substr(i + 1, 1));
    						i++;
    					}
    					else {//非终结符后面是非终结符s
    						//把后面非终结符的first集ff加入follow集中
    						string s;
    						if (i+2<temp.length() && temp[i + 2] == '\'') {
    							s = temp.substr(i + 1, 2);
    						}
    						else {
    							s = temp.substr(i + 1, 1);
    						}
    						set<string> ff = first[s];
    						for (set<string>::iterator nn = ff.begin(); nn != ff.end(); nn++) {
    							if (*nn != "#")
    								follow[temp.substr(i, 1)].insert(*nn);
    						}
    					}
    				}
    			}
    		}
    	}
    	//这一个需要多进行几次,因为follow是不断增长的
    	SSS();
    	SSS();
    
    	cout << "Follow集" << endl;
    	for (map<string, set<string>>::iterator it = follow.begin(); it != follow.end(); it++) {
    		cout << it->first << "  :  ";
    		for (set<string>::iterator ii = it->second.begin(); ii != it->second.end(); ii++)
    		{
    			cout << *ii << "    ";
    		}
    		cout << endl;
    	}
    }
    void FF::SSS() {
    	for (map<string, set<string>>::iterator it = split_productions.begin(); it != split_productions.end(); it++) {
    		string left = it->first;
    		set<string>right = it->second;
    		for (set<string>::iterator ii = right.begin(); ii != right.end(); ii++) {
    			string temp = *ii;
    			for (int j = temp.length() - 1; j > 0; j--) {
    				string now;
    				if (temp[j] == '\'') {
    					now = temp.substr(j - 1, 2);
    					j--;
    				}
    				else now = temp.substr(j, 1);
    				if (isVt(now)) {//产生式最后是终结符
    					break;
    				}
    				else {//产生式最后是非终结符
    					set<string>aa = follow[left];
    					for (set<string>::iterator pp = aa.begin(); pp != aa.end(); pp++) {
    						follow[now].insert(*pp);
    					}
    				}
    				if (first[now].find("#") == first[now].end())
    					break;
    			}
    		}
    	}
    }
    int main() {
    	FF ff;
    	ff.init();
    	ff.splitProductions();
    	ff.findVtAndVn();
    	ff.getFirst();
    	ff.getFollow();
    }
    展开全文
  • 用来求First集合的代码 C语言写的,呵呵~
  • 之前学习的时候只是知道first和follow集合怎么计算,但是没有很明白背后的原理。想起轮子哥的一句话:要理解一个东西最好的办法就是实现它。所以就心血来潮,写了C++的实现 代码 思路什么的就不说了,都写在代码的...

    前言

    最近在学习微机原理,里面涉及到编译优化的问题,又去重新看了看龙书的语法分析部分。之前学习的时候只是知道first和follow集合怎么计算,但是没有很明白背后的原理。想起轮子哥的一句话:要理解一个东西最好的办法就是实现它。所以就心血来潮,写了C++的实现

    代码

    思路什么的就不说了,都写在代码的注释里面。

    #include<string>
    #include<iostream>
    #include<vector>
    #include <map>
    #include <set>
    #include <regex>
    using namespace std;
    const int MAX_N = 5000;
    //记录总数
    int cnt = 0;
    pair<string,vector<string> > exps[MAX_N];
    set<string> Vns,Vts;//Vns表示非终结符的集合,Vts表示终结符的集合
    //使用set的好处就是可以去掉手工判断重复元素
    map<string,set<string> > first;//计算得到的first集合,同时也包含终结符的(也就是它本身。为了方便起见,往这里加入了)
    map<string,set<string> > follow;//计算得到的follow集合
    
    //判断是否属于终结符
    bool is_terminal_char(const string & s){
        //只要不是大写的我们就认为它属于终结符
        regex nt("[A-Z]*");
        if(regex_match(s,nt)){
            return false;
        }
        return true;
    }
    
    void readExps(){
        string str;
        cout<<"input information (end with #):\n";
    
        while (getline(cin,str)){
            if(str.find("#") != -1) break;//结束的条件,如果是#就直接跳出循环
            //输入的表达式以 -> 作为左右方向的分隔符。所以直接去找这个->的位置
            int mid_pos = str.find("->");
            if(mid_pos == -1){
                cout<<"输入的表达式格式有误,已忽略该表达式\n";
                continue;
            }
            int ls = 0,le = mid_pos;//表示左边的字符串起始位置和结束位置
            while (str[ls] == ' ') ls++;
    
            for(int i = ls;i<mid_pos;i++){
                if(str[i] == ' '){
                    le = i;
                    break;
                }
            }
            //确定表达式左边的非终结符的具体内容
            exps[cnt].first = str.substr(ls,le-ls);
            Vns.insert(exps[cnt].first);//加入到终结符的集合中
            //cout<<"--"<<exps[cnt].first<<"--"<<endl;
            //继续往后读取,把表达式右边的字符全都加入进来
            for(int i = mid_pos + 2; i<(int)str.length();i++){
                //表达式右边把所有的单字符都读入到vector里面
                if(str[i] == ' ') continue;
                exps[cnt].second.push_back(str.substr(i,1));
                string exp_elem = str.substr(i,1);
                if(is_terminal_char(exp_elem)){
                    Vts.insert(exp_elem);
                    first[exp_elem].insert(exp_elem);
                }
            }
            //读取完毕后,把cnt+1
            cnt++;
    //        for(string s : exps[cnt].second){ // 读取测试完成
    //            cout<<s<<" ";
    //        }
        }
    }
    
    
    //计算first集合
    void cal_first(){
        int pre_size = -1,now_size = 0;
        //设置更新的条件
        while(pre_size != now_size){
            pre_size = now_size;
            for(int i = 0;i<cnt;i++){
                string str = exps[i].first;
                vector<string> elements = exps[i].second;
                //如果说表达式右边的第一个字符属于终结符,那么就直接把它加入到first(str)中(规则1)
                if(is_terminal_char(elements[0])){
                    first[str].insert(elements[0]);
                }
                    //规则2
                else {
                    for (int j = 0; j < (int) elements.size(); j++) {
                        if (is_terminal_char(elements[j])) {//用于循环体判断。如果发现已经到达了终结符的位置,就退出
                            break;
                        }
                        //将两个集合进行合并
                        for(string tmp : first[elements[j]]){
                            //注意,空字符不能够加入到str的first集合中
                            if(tmp != "~"){
                                first[str].insert(tmp);
                            }
                            //但是如果发现所有的非终结符都可能推导出空字符,那么就把空字符加进去
                            else if(j == elements.size() - 1){
                                first[str].insert(tmp);
                            }
                        }
                        //如果发现没有空字符集,就直接退出去
                        if (first[elements[j]].find("~") == first[elements[j]].end()) {
                            break;
                        }
                    }
                }
                now_size = 0;
                for(string tmp : Vns){//重新计算now_size的大小
                    now_size += (int)first[tmp].size();
                }
            }
        }
    }
    
    void cal_follow(){
        //使用规则1
        follow["S"].insert("#");//默认S为文法的起始字符
        //这两个标志只用于判断是否已经生成了完全的follow集合
        int pre_size = -1,now_size = 0;
        while (pre_size !=  now_size){
            pre_size = now_size;
            for(int i = 0;i<cnt;i++){
                string str = exps[i].first;
                vector<string> elements = exps[i].second;
                //使用规则2
                for(int j = 0;j<(int)elements.size()-1;j++){
                    if(!is_terminal_char(elements[j])){//如果当前的是非终结符
                        //并且后面的那个单元也是非终结符
                        //就把后面的那个非终结符除~以外的所有first元素都加入进去
                        follow[elements[j]].insert(first[elements[j + 1]].begin(), first[elements[j + 1]].end());
                        //去掉空字符
                        follow[elements[j]].erase("~");
                        //否则就把后面的单个终结符加入进去
                    }
                }
                //如果当前的是终结符,那么规则2就不用了.
                //使用规则3,为了方便起见,从后往向前遍历
                for(int j = elements.size() - 1;j>=0;j--){
                    //如果是非终结符,就把推导式中的follow元素都加入到它对应的follow集合里面
                    if(!is_terminal_char(elements[j])){
                        follow[elements[j]].insert(follow[str].begin(),follow[str].end());
                    }
                    else break;//如果是终结符,就直接退出
    
                    //表明在first集合中没有空字符,这样的话就直接退出
                    if(first[elements[j]].find("~") == first[elements[j]].end()){
                        break;
                    }
                }
            }
            now_size = 0;
            for(string tmp : Vns){//重新计算now_size的大小
                now_size += (int)follow[tmp].size();
            }
        }
    }
    
    /**
     * testData is in test_data.txt
     * @return
     */
    int main(){
        Vts.insert("#");
    
        readExps();
        cal_first();
        cout<<"---first---\n";
        for(string n : Vns){
            cout<<n<<":";
            for(string tmp : first[n]){
                cout<<tmp<<" ";
            }
            cout<<endl;
        }
        cal_follow();
        cout<<"---follow---\n";
        for(string n : Vns){
            cout<<n<<":";
            for(string tmp : follow[n]){
                cout<<tmp<<" ";
            }
            cout<<endl;
        }
        return 0;
    }
    
    

    测试数据:
    输入:

    S->AB
    S->bC
    A->~
    A->b
    B->~
    B->aD
    C->AD
    C->b
    D->aS
    D->c
    

    预计输出:

    ---first---
    A:b ~
    B:a ~
    C:a b c
    D:a c
    S:a b ~
    ---follow---
    A:# a c
    B:#
    C:#
    D:#
    S:#
    
    

    当然设计的还有很多不完善的地方,后续自己优化吧。

    展开全文
  • C语音代码。实现功能:1....2.求每个非终结符FIRST FOLLOW和SELECT模块。3.预测分析表的构建模块。4.文法的检验及消除左公因子和左递归模块。5.对输入终结符串的判断,是否为LL1文法,并进一步分析。
  • 下面是这部分的代码,我贴一部分,剩下的等我把求follow实现再写一篇博文来给大家看! 请给我点赞谢谢~!!! 实现得非常简洁明了(自夸) 你可以看下注释,写的非常清楚啦!!! package parse2; import java.u...
  • 编译原理 —— FIRST集

    千次阅读 2019-02-05 18:24:41
    给定一个文法符号串α,α的串首终结符 FIRST(a) 被定义为可以从a推导出的所有串首终结符构成的集合。 如果 α=&amp;amp;amp;amp;amp;amp;amp;amp;gt;∗εα=&amp;amp;amp;amp;amp;amp;amp;amp;gt;^*ε...
  • 编译原理之NULLfirst、followC语言实现,实现中句子的转换符号由‘#’代替,数组默认由‘*’作为结束符
  • 构造预测分析表 源程序 #include<stdlib.h> #include<stdio.h> #include<string.h> /*/ int count=0; /* 分解的产生式的个数 */ int number; /* 所有终结符和非终结符的总数 */ char start; /* 开始符号 */ char ...
  • 当前目录下有这三个文件 houxuanshi_processed .txt houxuanshi ...*实现编译原理语法分析中计算非终结...这样处理了候选式之后,就便于程序进一步分析每一个候选式的特征,从而计算非终结符的FIRST集和FOLLOW集。
  • 当Y1,Y2,…..,Yi-1都 能推出ε, (1), 而Yi推不出ε,则FIRST(Y1)--{ε},FIRST(Y2)--{ε},……,FIRST(Yi-1)--{ ε}, FIRST(Yi) 都属于 FIRST(X)。 5. 当4中所有的 Yi都能推出ε,(i=1,2,….n),则 FIRST(X)=FIRST(Y1)...
  • 编译原理的FIRST集和FOLLOW集~~有兴趣的可以看一下,有漏了一个条件,不过注明出来了~~
  • 编译原理之first集,follow集,select集解析

    万次阅读 多人点赞 2018-04-30 19:30:32
    为了方便自顶向下语法分析,需要求文法对应的first集,follow集,以及select集。本文主要分为两部分,一个是求法解析,还有一个例子详解:第一部分是求法解析将对first集,follow集,select集分为三种讲解方法①定义...
  • 编译原理 求first集与follow集 c++ 题目: 输入任意的上下文无关文法,输出所输入的上下文无关文法一切非终结符的first集合和follow集合
  • first集 编译原理 c++版本first集 编译原理 c++版本
  • FIRST集和FOLLOW集的计算

    千次阅读 2019-04-26 17:05:58
    文章目录`FIRST`集的计算计算`FIRST(x)`...FIRST集的计算 计算FIRST(x) FIRST(X):可以从X中推导出的所有串首终结符构成的结合。 若$X\Rightarrow^*{\epsilon}$,那么$\epsilon \in FIRST(X)$。 推导过程: (2)...
  • FIRST集合求法

    千次阅读 2020-06-07 13:50:48
    FIRST集求法 FIRST集的定义 FIRST集的作用 First(A)集的作用是标示在替换非终结符A的时候,替换后的文法的首字母集合,语法分析程序根据这个来判断给定的语言是否是合法的,是符合规则的。 FIRST 集求法 ...
  • 编译原理:求First集和Follow集

    千次阅读 2018-10-25 22:16:04
    #输入文法求First集和Follow集 #要求大写字母表示非终结符,小写字母表示终结符 #最后一个产生式以$结尾或者输入$表示输入结束 #默认第一个产生式的→左边为起始符号 def inputGrammer(): #接收文法输入的函数 ...
  • 如何求First集与Follow集(超详细)

    千次阅读 多人点赞 2020-12-23 18:16:37
    如何求First集与Follow集 已知文法如下,求First集与Follow集 G[E]:E→TE′E′→+TE′∣εT→FT′T′→∗FT′∣εF→(E)∣i G[E]: E{\rightarrow} TE' \\ {\quad\quad\quad\quad\quad}E'{\rightarrow}+TE'|\var...
  • 编译原理实验 first、follow、select集合的求解,经测试正确,c语言编写
  • 对文法中的非终结符,求first集和follow集
  • 具体的可运行代码移步这里进行下载(免费的):【编译原理实验】Java实现完整自顶向下语法分析——First、Follow、Select、判断LL(1)、提取公因子、消除左递归、自顶向下分析输入串 代码运行效果放在文末,可直接...
  • 编译原理FIRST集和FOLLOW集的求法以及构建LL(1)分析表

    万次阅读 多人点赞 2019-07-01 10:57:57
    文章目录FIRST集的求法FOLLOW集的计算生成预期分析表算法例题 FIRST集的求法 FIRST集是一个文法符号串所可能推导出的符号串的第一个终结符的集合 对于文法G的任一符号串α\alphaα = x1x2…xnx_{1}x_{2} \ldots x_{n...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 154,348
精华内容 61,739
关键字:

first集代码