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编译原理—翻译方案属性栈代码