LR分析表的程序构建

Posted KalznAsawind

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LR分析表的程序构建相关的知识,希望对你有一定的参考价值。

此程序可以从一组文法中构造出LR(0)分析表,并求出非终结符FIRST和FOLLOW集。程序将从同目录下的0.in文件中读取信息。
下面是一组0.in示例:

E -> E+T
E -> T
T -> T*F
T -> F
F -> (E)
F -> a
END

()*+a
ETF

E

a*a+a
a+(a*a)+a
a+a+a*a
a*a*a+(a*a+a)+(a)
aa+aa

在文件中,前6行表述文法,用END表示结束。然后输入一行所有终结符,一行所有非终结符。然后是开始的非终结符。然后是几组样例。
这里要注意的是:
1、非终结符必须是一个大写字母,终结符不能是大写字母。
2、非终结符不能包含S,因为S被程序用于扩展文法的开始非终结符。
3、终结符不能包含 !, @, #, $。因为这四种符合已被程序占用作为特殊用途。其中@表示项目的点,#表示字符串的结束, $表示空串。
4、文法必须是LR(0)文法。

程序读入程序后,会在同目录下写入文件0.out。输出包含1、所有项目。2、项目规范族。3、FIRST和FOLLOW集。4、规约过程。
下面是输出示例:

ITEM :: 
E -> @E+T
E -> @T
E -> E+@T
E -> E+T@
E -> E@+T
E -> T@
F -> (@E)
F -> (E)@
F -> (E@)
F -> @(E)
F -> @a
F -> a@
S -> @E
S -> E@
T -> @F
T -> @T*F
T -> F@
T -> T*@F
T -> T*F@
T -> T@*F

ITEM_SET ::
The number : 12
I0-------------------
E -> @E+T
E -> @T
F -> @(E)
F -> @a
S -> @E
T -> @F
T -> @T*F

I1-------------------
E -> @E+T
E -> @T
F -> (@E)
F -> @(E)
F -> @a
T -> @F
T -> @T*F

I2-------------------
F -> a@

I3-------------------
E -> E@+T
S -> E@

I4-------------------
E -> T@
T -> T@*F

I5-------------------
T -> F@

I6-------------------
E -> E@+T
F -> (E@)

I7-------------------
F -> (E)@

I8-------------------
E -> E+@T
F -> @(E)
F -> @a
T -> @F
T -> @T*F

I9-------------------
E -> E+T@
T -> T@*F

I10-------------------
F -> @(E)
F -> @a
T -> T*@F

I11-------------------
T -> T*F@


FIRST_SET and FOLLOW_SET :: 
FIRST(E) = {(,a,}
FIRST(F) = {(,a,}
FIRST(S) = {(,a,}
FIRST(T) = {(,a,}
----------------
FOLLOW(E) = {#,),+,}
FOLLOW(F) = {#,),*,+,}
FOLLOW(S) = {#,}
FOLLOW(T) = {#,),*,+,}

LR(0) TABLE ::
           (       )       *       +       a       #       E       T       F       S
------------------------------------------------------------------------------------
  0|       1                               2               3       4       5        
------------------------------------------------------------------------------------
  1|       1                               2               6       4       5        
------------------------------------------------------------------------------------
  2|       a       a       a       a       a       a                                
------------------------------------------------------------------------------------
  3|                               8             acc                                
------------------------------------------------------------------------------------
  4|       T       T       T       T       T       T                                
------------------------------------------------------------------------------------
  5|       F       F       F       F       F       F                                
------------------------------------------------------------------------------------
  6|               7               8                                                
------------------------------------------------------------------------------------
  7|     (E)     (E)     (E)     (E)     (E)     (E)                                
------------------------------------------------------------------------------------
  8|       1                               2                       9       5        
------------------------------------------------------------------------------------
  9|     E+T     E+T     E+T     E+T     E+T     E+T                                
------------------------------------------------------------------------------------
 10|       1                               2                              11        
------------------------------------------------------------------------------------
 11|     T*F     T*F     T*F     T*F     T*F     T*F                                
------------------------------------------------------------------------------------
Begin to match string whit LR(0): a*a+a ----------------
Result : Status = { 0, }  Op = {  }  String = { a*a+a# }
Status = { 0, 2, }  Op = { a }  String = { *a+a# }
Status = { 0, 5, }  Op = { F }  String = { *a+a# }
Status = { 0, 4, }  Op = { T }  String = { *a+a# }
Status = { 0, 4, 10, }  Op = { T* }  String = { a+a# }
Status = { 0, 4, 10, 2, }  Op = { T*a }  String = { +a# }
Status = { 0, 4, 10, 11, }  Op = { T*F }  String = { +a# }
Status = { 0, 4, }  Op = { T }  String = { +a# }
Status = { 0, 3, }  Op = { E }  String = { +a# }
Status = { 0, 3, 8, }  Op = { E+ }  String = { a# }
Status = { 0, 3, 8, 2, }  Op = { E+a }  String = { # }
Status = { 0, 3, 8, 5, }  Op = { E+F }  String = { # }
Status = { 0, 3, 8, 9, }  Op = { E+T }  String = { # }
Status = { 0, 3, }  Op = { E }  String = { # }
SUCCESS!
End to match string ----------------



Begin to match string whit LR(0): a+(a*a)+a ----------------
Result : Status = { 0, }  Op = {  }  String = { a+(a*a)+a# }
Status = { 0, 2, }  Op = { a }  String = { +(a*a)+a# }
Status = { 0, 5, }  Op = { F }  String = { +(a*a)+a# }
Status = { 0, 4, }  Op = { T }  String = { +(a*a)+a# }
Status = { 0, 3, }  Op = { E }  String = { +(a*a)+a# }
Status = { 0, 3, 8, }  Op = { E+ }  String = { (a*a)+a# }
Status = { 0, 3, 8, 1, }  Op = { E+( }  String = { a*a)+a# }
Status = { 0, 3, 8, 1, 2, }  Op = { E+(a }  String = { *a)+a# }
Status = { 0, 3, 8, 1, 5, }  Op = { E+(F }  String = { *a)+a# }
Status = { 0, 3, 8, 1, 4, }  Op = { E+(T }  String = { *a)+a# }
Status = { 0, 3, 8, 1, 4, 10, }  Op = { E+(T* }  String = { a)+a# }
Status = { 0, 3, 8, 1, 4, 10, 2, }  Op = { E+(T*a }  String = { )+a# }
Status = { 0, 3, 8, 1, 4, 10, 11, }  Op = { E+(T*F }  String = { )+a# }
Status = { 0, 3, 8, 1, 4, }  Op = { E+(T }  String = { )+a# }
Status = { 0, 3, 8, 1, 6, }  Op = { E+(E }  String = { )+a# }
Status = { 0, 3, 8, 1, 6, 7, }  Op = { E+(E) }  String = { +a# }
Status = { 0, 3, 8, 5, }  Op = { E+F }  String = { +a# }
Status = { 0, 3, 8, 9, }  Op = { E+T }  String = { +a# }
Status = { 0, 3, }  Op = { E }  String = { +a# }
Status = { 0, 3, 8, }  Op = { E+ }  String = { a# }
Status = { 0, 3, 8, 2, }  Op = { E+a }  String = { # }
Status = { 0, 3, 8, 5, }  Op = { E+F }  String = { # }
Status = { 0, 3, 8, 9, }  Op = { E+T }  String = { # }
Status = { 0, 3, }  Op = { E }  String = { # }
SUCCESS!
End to match string ----------------



Begin to match string whit LR(0): a+a+a*a ----------------
Result : Status = { 0, }  Op = {  }  String = { a+a+a*a# }
Status = { 0, 2, }  Op = { a }  String = { +a+a*a# }
Status = { 0, 5, }  Op = { F }  String = { +a+a*a# }
Status = { 0, 4, }  Op = { T }  String = { +a+a*a# }
Status = { 0, 3, }  Op = { E }  String = { +a+a*a# }
Status = { 0, 3, 8, }  Op = { E+ }  String = { a+a*a# }
Status = { 0, 3, 8, 2, }  Op = { E+a }  String = { +a*a# }
Status = { 0, 3, 8, 5, }  Op = { E+F }  String = { +a*a# }
Status = { 0, 3, 8, 9, }  Op = { E+T }  String = { +a*a# }
Status = { 0, 3, }  Op = { E }  String = { +a*a# }
Status = { 0, 3, 8, }  Op = { E+ }  String = { a*a# }
Status = { 0, 3, 8, 2, }  Op = { E+a }  String = { *a# }
Status = { 0, 3, 8, 5, }  Op = { E+F }  String = { *a# }
Status = { 0, 3, 8, 9, }  Op = { E+T }  String = { *a# }
Status = { 0, 3, 8, 9, 10, }  Op = { E+T* }  String = { a# }
Status = { 0, 3, 8, 9, 10, 2, }  Op = { E+T*a }  String = { # }
Status = { 0, 3, 8, 9, 10, 11, }  Op = { E+T*F }  String = { # }
Status = { 0, 3, 8, 9, }  Op = { E+T }  String = { # }
Status = { 0, 3, }  Op = { E }  String = { # }
SUCCESS!
End to match string ----------------



Begin to match string whit LR(0): a*a*a+(a*a+a)+(a) ----------------
Result : Status = { 0, }  Op = {  }  String = { a*a*a+(a*a+a)+(a)# }
Status = { 0, 2, }  Op = { a }  String = { *a*a+(a*a+a)+(a)# }
Status = { 0, 5, }  Op = { F }  String = { *a*a+(a*a+a)+(a)# }
Status = { 0, 4, }  Op = { T }  String = { *a*a+(a*a+a)+(a)# }
Status = { 0, 4, 10, }  Op = { T* }  String = { a*a+(a*a+a)+(a)# }
Status = { 0, 4, 10, 2, }  Op = { T*a }  String = { *a+(a*a+a)+(a)# }
Status = { 0, 4, 10, 11, }  Op = { T*F }  String = { *a+(a*a+a)+(a)# }
Status = { 0, 4, }  Op = { T }  String = { *a+(a*a+a)+(a)# }
Status = { 0, 4, 10, }  Op = { T* }  String = { a+(a*a+a)+(a)# }
Status = { 0, 4, 10, 2, }  Op = { T*a }  String = { +(a*a+a)+(a)# }
Status = { 0, 4, 10, 11, }  Op = { T*F }  String = { +(a*a+a)+(a)# }
Status = { 0, 4, }  Op = { T }  String = { +(a*a+a)+(a)# }
Status = { 0, 3, }  Op = { E }  String = { +(a*a+a)+(a)# }
Status = { 0, 3, 8, }  Op = { E+ }  String = { (a*a+a)+(a)# }
Status = { 0, 3, 8, 1, }  Op = { E+( }  String = { a*a+a)+(a)# }
Status = { 0, 3, 8, 1, 2, }  Op = { E+(a }  String = { *a+a)+(a)# }
Status = { 0, 3, 8, 1, 5, }  Op = { E+(F }  String = { *a+a)+(a)# }
Status = { 0, 3, 8, 1, 4, }  Op = { E+(T }  String = { *a+a)+(a)# }
Status = { 0, 3, 8, 1, 4, 10, }  Op = { E+(T* }  String = { a+a)+(a)# }
Status = { 0, 3, 8, 1, 4, 10, 2, }  Op = { E+(T*a }  String = { +a)+(a)# }
Status = { 0, 3, 8, 1, 4, 10, 11, }  Op = { E+(T*F }  String = { +a)+(a)# }
Status = { 0, 3, 8, 1, 4, }  Op = { E+(T }  String = { +a)+(a)# }
Status = { 0, 3, 8, 1, 6, }  Op = { E+(E }  String = { +a)+(a)# }
Status = { 0, 3, 8, 1, 6, 8, }  Op = { E+(E+ }  String = { a)+(a)# }
Status = { 0, 3, 8, 1, 6, 8, 2, }  Op = { E+(E+a }  String = { )+(a)# }
Status = { 0, 3, 8, 1, 6, 8, 5, }  Op = { E+(E+F }  String = { )+(a)# }
Status = { 0, 3, 8, 1, 6, 8, 9, }  Op = { E+(E+T }  String = { )+(a)# }
Status = { 0, 3, 8, 1, 6, }  Op = { E+(E }  String = { )+(a)# }
Status = { 0, 3, 8, 1, 6, 7, }  Op = { E+(E) }  String = { +(a)# }
Status = { 0, 3, 8, 5, }  Op = { E+F }  String = { +(a)# }
Status = { 0, 3, 8, 9, }  Op = { E+T }  String = { +(a)# }
Status = { 0, 3, }  Op = { E }  String = { +(a)# }
Status = { 0, 3, 8, }  Op = { E+ }  String = { (a)# }
Status = { 0, 3, 8, 1, }  Op = { E+( }  String = { a)# }
Status = { 0, 3, 8, 1, 2, }  Op = { E+(a }  String = { )# }
Status = { 0, 3, 8, 1, 5, }  Op = { E+(F }  String = { )# }
Status = { 0, 3, 8, 1, 4, }  Op = { E+(T }  String = { )# }
Status = { 0, 3, 8, 1, 6, }  Op = { E+(E }  String = { )# }
Status = { 0, 3, 8, 1, 6, 7, }  Op = { E+(E) }  String = { # }
Status = { 0, 3, 8, 5, }  Op = { E+F }  String = { # }
Status = { 0, 3, 8, 9, }  Op = { E+T }  String = { # }
Status = { 0, 3, }  Op = { E }  String = { # }
SUCCESS!
End to match string ----------------



Begin to match string whit LR(0): aa+aa ----------------
Result : Status = { 0, }  Op = {  }  String = { aa+aa# }
Status = { 0, 2, }  Op = { a }  String = { a+aa# }
Status = { 0, 5, }  Op = { F }  String = { a+aa# }
Status = { 0, 4, }  Op = { T }  String = { a+aa# }
Status = { 0, 3, }  Op = { E }  String = { a+aa# }
FAIL
End to match string ----------------




代码:

// % everyone
#include <cstdio>
#include<iostream>
#include<cstring>
#include <map>
#include <queue>
#include <set>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <cctype>
#include <time.h>

namespace IO {
    double start_time = 0.0;
    void ct() { start_time = clock(); return; }
    void fast_cin() { std::ios::sync_with_stdio(false); std::cin.tie(); }
    void read_f(int flag = 0) { freopen("0.in", "r", stdin); if(!flag) freopen("0.out", "w", stdout); }
    void run_time() { std::cout << "\\nESC in : " << ( clock() - start_time ) * 1000.0 / CLOCKS_PER_SEC << "ms" << std::endl; }
}
using namespace IO;
template <typename T>
bool bacmp(const T & a, const T & b) { return a > b; }
template <typename T>
bool pecmp(const T & a, const T & b) { return a < b; }

#define ll long long
#define ull unsigned ll
#define _min(x, y) ((x)>(y)?(y):(x))
#define _max(x, y) ((x)>(y)?(x):(y))
#define max3(x, y, z) ( max( (x), max( (y), (z) ) ) )
#define min3(x, y, z) ( min( (x), min( (y), (z) ) ) )
#define pr make_pair
#define pb push_back
using namespace std;
struct Node
{
    set<string> nt;
};
map<string, Node> wordRule;
set<pair<string, string> > item;

set< set<pair<string, string> > > pd;
map< set<pair<string, string> >, int> I;



string rot;
string endWord, noEndWord;
map< char, set<char> > firstSet, followSet;

bool add( set<char>& a, const set<char>& b, bool addEmpty = true) {
    bool flag = false;
    for (auto x : b) {
        if (a.find(x) == a.end()) {
            if (addEmpty == false && x == '$') continue;
            flag = true;
            a.insert(x);
        }
    }
    return flag;
}
void createSet(const map<string, Node> & word) {
    for (auto x : wordRule) {
        firstSet[x.first[0]]=set<char>();
        followSet[x.first[0]]=set<char>();
        followSet[x.first[0]].insert('#');
        for (auto y : x.second.nt) {
			for (auto z : y) {
				firstSet[z]=set<char>();
				if (!isupper(z)) {
					firstSet[z].insert(z);
				}
				followSet[z]=set<char>();
			}
        }
    }
}
void extendSet(const map<string, Node> & word) {
    while(true) {
        bool flag = false;
        for (auto x : wordRule) {
            for (auto y : x.second.nt) {
                flag |= add(firstSet[x.first[0]], firstSet[y[0]]);
            }
        }
        if (!flag) break;
    }
    while(true) {
        bool flag = false;
        for (auto x : wordRule) {
            for (auto y : x.second.nt) {
                for (int pos = 0; pos < y.size() - 1; pos++) {
                    char pre = y[pos], la = y[pos+1];
                    flag |= add(followSet[pre], firstSet[la], false);
                    for (int posp = pos+1; posp<y.size(); posp++) {
                        if (firstSet[y[posp]].find('$') == firstSet[y[posp]].end()) break;
                        if (posp == y.size() - 1) {
                            flag |= add(followSet[y[pos]], followSet[x.first[0]]);
                        } else {
                            flag |= add(followSet[y[pos]], firstSet[y[posp+1]]);
                        }
                    }

                }
                char g = *y.rbegin();
                flag |= add(followSet[g], followSet[x.first[0]]);
            }
        }
        if (!flag) break;
    }
}
void getItem(map<string, Node> wordRule) {
	item.clear();
	for (auto it : wordRule) {
		for (auto gt : it.second.nt) {
			string a = it.first;
			string b = gt;
			if (b != "$") {
				for (int i = 0; i < b.size(); i++) {
					item.insert(pr(a, b.substr(0, i) + "@" + b.substr(i, b.size() - i) ));
				}
				item.insert(pr(a, b+"@"));
			}
			else  item.insert(pr(a, "@"));
		}
	}
}
char getNext(string x) {
	for (int i = 0; i < x.size() - 1; i++) {
		if (x[i] == '@') return x[i+1];
	}
	return '!';
}
void addClose(char a, set<pair<string, string> >& adt) {
	for (auto x :item) {
		if (x.first[0] == a && x.second[0] == '@') {
			adt.insert(x);
		}
	}
}
void getCLose(set<pair<string, string> >& adset) {
	bool flag = 0;
	while(true) {
		flag = 0;
		set<pair<string, string> > adt = set<pair<string, string> >();
		for (auto x : adset) {
			char gt = getNext(x.second);
			if (isupper(gt)) {
				addClose(gt, adt);
			}
		}
		for (auto x : adt) {
			if (adset.find(x) == adset.end()) {
				flag = 1;
				adset.insert(x);
			}
		}
		if (!flag) break;
	}
}
pair<string, string> getMach(pair<string, string> s) {
	for (int i = 0; i < s.second.size() -1; i++) {
		if (s.second[i] == '@') {
			swap(s.second[i], s.second[i+1]);
			return s;
		}
	}
	return pair<string, string>();
}
map<pair<int, char>, int> lrActionS, lrGoto;
map<pair<int, char>, pair<string, string> > lrActionR;
void addEdge(int x, int y, char sta) {
    if (!isupper(sta)) lrActionS[pr(x, sta)] = y;
    else lrGoto[pr(x, sta)] = y;
}
void addEdge(int x, pair<string, string> y, char sta) {
    lrActionR[pr(x编译原理—翻译方案属性栈代码

S5-自底向上的语法分析

lr的测试结果怎么分析?

编译原理运行时环境—什么是活动记录 活动记录与汇编代码的关系

什么是LLLRLR文法LR分析表—编译原理

编译原理之语法分析-自下而上分析