第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 【编译原理】LR语法分析器的设计与实现

【编译原理】LR语法分析器的设计与实现

时间:2019-10-11 05:21:08

相关推荐

【编译原理】LR语法分析器的设计与实现

LR语法分析器的设计与实现

本文为当时编译原理实验作业,要求用设计的思想完成,小题大做,仅供参考

文章目录

LR语法分析器的设计与实现实验要求实现功能输入输出样例 一、LR语法分析器问题定义1.1 语法分析器定义1.2 自上而下语法分析原理 二、LR语法分析器需求陈述三、LR语法分析器分析模型3.1 LR语法分析器领域模型3.1.1 确定LR法分析器类与对象3.1.2 绘制领域模型(对象模型)3.2.2绘制事件跟踪图3.2.3 绘制状态图 3.3 LR语法分析器功能模型3.3.1 绘制基本系统模型图3.3.2 绘制功能级数据流图3.3.3 用例建模 四、LR语法分析器设计模型4.1 LR法分析器对象模型4.1.1 完善对象模型4.1.2 绘制类图 4.2 主要算法4.2.1 LR(0)项目集的闭包算法4.2.2 LR(1)项目集的闭包算法4.2.3 计算GO函数和LR0项目集规范族4.2.4 计算GO函数和LR1项目集规范族4.2.5 分析输入串 五、LR语法分析器系统实现5.1 文法类及其子类的定义5.1.1上下文无关文法类(基类)5.1.2 LR0文法类(子类)5.1.3LR1文法类(子类) 5.2 分析类的定义5.2.1 文法分析类(父类)5.2.2 LR分析类(子类) 六、系统测试6.1测试主程序6.2 测试数据及测试结果6.2.1测试样例6.2.2 测试结果 附录(cpp源代码):

实验要求

实现功能

1)使用LR(1)分析方法构造识别活前缀的DFA;

2)构造文法的分析表(Action表和Goto表);

3)构造LR语法分析器的总控程序;

3)输入文法(语言语法结构的文法描述存储在文本文件中);

4)输出文法的项目集簇(标准输出设备);

5)输出识别活前缀的DFA(标准输出设备);

6)输出文法的Action表和Goto表(标准输出设备);

7)对给定的输入串(存储在文本文件中),输出其是否该文法正确句子的判断,并输出文本形式的分析过程。

输入输出

文件结构:

1)非终结符个数;

2)所有非终结符,空格分隔;

3)终结符个数;

4)所有终结符,空格分隔;

5)规则个数;

6)所有规则,每行一个规则,规则输入格式:左部,右部符号数,右部符号,空格分隔;

7)开始符号。

8)待分析的符号串。

样例

描述:

文法G =(VN,VT,P,S)其中:VN = { S', S }VT = { a, (, ) }P = { S' -> SS -> ( S )S -> a}S = S’

输入:

4S' S L R 3= * i6S' -> SS -> L = RS -> RL -> * R L -> iR -> LS'* i = i #

输出:

CFG=(VN,VT,P,S)VN: S' S L RVT: = * iProduction:0: S' -> S1: S -> L = R2: S -> R3: L -> * R4: L -> i5: R -> LStartSymbol: S'[LR(1) item set cluster]I0 :S' -> . S, #S -> . L = R, #S -> . R, #L -> . * R, #L -> . * R, =L -> . i, #L -> . i, =R -> . L, #I1 :S' -> S ., #I2 :S -> L . = R, #R -> L ., #I3 :S -> R ., #I4 :L -> . * R, #L -> . * R, =L -> * . R, #L -> * . R, =L -> . i, #L -> . i, =R -> . L, #R -> . L, =I5 :L -> i ., #L -> i ., =I6 :L -> * R ., #L -> * R ., =I7 :R -> L ., #R -> L ., =I8 :S -> L = . R, #L -> . * R, #L -> . i, #R -> . L, #I9 :S -> L = R ., #I10:L -> . * R, #L -> * . R, #L -> . i, #R -> . L, #I11:L -> i ., #I12:R -> L ., #I13:L -> * R ., #[LR(0) analytical table]Action:# = * i0 s4 s51 acc2 r5 s83 r24 s4 s55 r4 r46 r3 r37 r5 r58 s10 s119 r110 s10 s1111 r412 r513 r3Goto:S L R0 1 2 31 2 3 4 7 65 6 7 812 99 1012 1311 12 13 文法是 LR(1) 文法![parsing]栈顶 输入查表 动作 注------------+--------+----+-------------------------------------+-----------0 # * s4 进栈 4 *4 * i s5 进栈 5 i5 i = r4 出栈 1 个符号和状态 进栈 7 L L -> i7 L = r5 出栈 1 个符号和状态 进栈 6 R R -> L6 R = r3 出栈 2 个符号和状态 进栈 2 L L -> * R2 L = s8 进栈 8 =8 = i s11 进栈 11 i11 i # r4 出栈 1 个符号和状态 进栈 12 L L -> i12 L # r5 出栈 1 个符号和状态 进栈 9 R R -> L9 R # r1 出栈 3 个符号和状态 进栈 1 S S -> L = R1 S # acc 成功接收!------------+--------+----+-------------------------------------+-----------end!

一、LR语法分析器问题定义

1.1 语法分析器定义

语法分析器(Parser)通常是作为编译器或解释器的组件出现的,它的作用是进行语法检查、并构建由输入的单词组成的数据结构(一般是语法分析树、抽象语法树等层次化的数据结构)。语法分析器通常使用一个独立的词法分析器从输入字符流中分离出一个个的“单词”,并将单词流作为其输入。实际开发中,语法分析器可以手工编写,也可以使用工具(半)自动生成。

1.2 自上而下语法分析原理

(1)自上而下语法分析基本思想

将输入符号按从左到右顺序依次移入文法符号的栈栈中,边移入边分析;当栈顶符号串形成某条规则右部时就进行一次归约,即用该规则左部非终结符替换相应规则右部符号串。重复这一过程直到整个输入串分析完毕。最终若栈中剩下句子右界符“#”和文法的开始符号,则所分析的输入符号串是文法的正确句子。否则,就不是的正确句子,报告错误。

(2)自上而下语法分析常用方法

LR(0)、LR(1)、SLR、LALR等。

二、LR语法分析器需求陈述

使用LR(0)、LR(1)分析方法构造识别活前缀的DFA;构造文法的分析表(Action表和Goto表);构造LR语法分析器的总控程序;输入文法(语言语法结构的文法描述存储在文本文件中);输出文法的项目集簇(标准输出设备);输出识别活前缀的DFA(标准输出设备);输出文法的Action表和Goto表(标准输出设备);对给定的输入串(存储在文本文件中),输出其是否该文法正确句子的判断,并输出文本形式的分析过程。

三、LR语法分析器分析模型

3.1 LR语法分析器领域模型

3.1.1 确定LR法分析器类与对象

从语法分析器的问题定义中筛选出可能作为对象的候选对象。

根据编译程序使用的基本概念,将所有概念实体作为候选对象,下图是根据概念之间的组成关系总结出的所有候选对象。

3.1.2 绘制领域模型(对象模型)

生成对象模型的方法:

对候选对象确定初步关联,筛选出必要关联和必要的类;确定各个对象的属性;绘制出各个类之间的联系。

初步的对象模型(领域模型):

3.2 LR语法分析器动态模型

3.2.1 编写系统状态脚本

以下给出了文法分析系统的正常和异常情况脚本

(1)文法分析系统正常情况脚本:

(2)文法分析系统异常情况脚本:

3.2.2绘制事件跟踪图

文法分析系统的主要事件有两个:

(1)文法处理事件:

用户通过文件或中端输入文法,文法系统接收后初始化文法进行文法分析,分析后生成预测分析表,最后将文法的组成信息和分析信息打印在终端上或输出在文件中。

(2)文法分析事件:

用户通过文件或中端输入待分析串,文法系统接收后初对照预测分析表进行文法分析,分析后生成移进归约序列,最后将字符串的文法分析信息打印在终端上或输出在文件中。

3.2.3 绘制状态图

状态图描绘事件与对象之间的关系。将事件跟踪图中两个事件整合绘制系统状态图如下:

3.3 LR语法分析器功能模型

3.3.1 绘制基本系统模型图

基本的系统模型图指明了目标系统的边界,绘制语法分析器基本系统模型图如下:

3.3.2 绘制功能级数据流图

把基本系统模型中单一的处理框分解成若干个处理框,以描述系统加工,变换数据的基本功能,得到以下LR文法分析系统的功能级数据流图:

3.3.3 用例建模

(1)用例文本

LR文法分析系统的使用者主要有两类:文法处理使用者、文法分析使用者;

文法处理分为LR0文法处理和LR1文法处理;

文法分析分为LR0文法分析和LR1文法处分析。

(2)LR文法分析用例图:

四、LR语法分析器设计模型

4.1 LR法分析器对象模型

4.1.1 完善对象模型

利用继承机制共享公共性质,对系统中的类加以组织:

终结符和非终结符继承符号类LR0文法类和LR1文法类及其相关的类继承LR文法及其相关的类。

4.1.2 绘制类图

4.2 主要算法

4.2.1 LR(0)项目集的闭包算法

LR0项目集闭包算法:

输入:LR0项目集。输出:LR0项目集的闭包。

function CLOSURE (I)beginJ:= I;repeat for J 中的每个项目A →α·Bβ和规则 B→γ若 B→·γ不在 J 中 Do{将 B→·γ加到J中} until 再没有项目加到 J 中return Jend;

4.2.2 LR(1)项目集的闭包算法

LR1项目集闭包算法:

输入:LR1项目集。输出:LR1项目集的闭包。

function CLOSURE (I)beginJ:= I;repeat for J 中的每个项目 A→α·Bβ,a和产生式 B→γ;α,β,γ∈V*;b∈FIRST(βa),若 B→·γ, b 不在 J 中Do {将 B→·γ, b 加到 J 中} until 再没有项目加到J中return Jend.

4.2.3 计算GO函数和LR0项目集规范族

计算GO函数和LR0项目集规范族算法:

输入:LR0项目集。输出:GO函数和LR0项目集规范族。

C={I0 ,I1 , ... ,In }procedure itemsets(G’);begin C := { CLOSURE ({S’→·S})}repeatfor C 中每一项目集 I 和每一文法符号 x do{if GO(I,x) 非空且不属于Cthen 把 GO(I,x) 放入 C 中}until C 不再增大end;

4.2.4 计算GO函数和LR1项目集规范族

计算GO函数和LR1项目集规范族算法:

输入:LR1项目集。输出:GO函数和LR1项目集规范族。

C={I0 ,I1 , ... ,In }procedure itemsets(G’);BegainC:={ Closure( {S′→·S,#}) };Repeat For C 中的每个项目集 I 和每个符号 X DoIf Go(I,X)非空且不属于 C Then 把 Go(I,X)加入 C 中Until C 不再增大End

4.2.5 分析输入串

LR分析程序算法:

输入:待分析符号串。输出:LR文法分析结果。

初始化,初始状态 S0 在分析栈栈顶;输入串 W# 的第一个符号读入 a 中。while (ACTION[S,a]!=acc) {if (ACTION[S,a]==Si){将 Si 和 a 进栈,将下一个输入符号读入 a ;}else if (ACTION[S,a]==rj) {用第 j 条规则 A→x 规约;将 |x|个状态和|a|个文法符号退栈;假设当前栈顶状态为 S’,将 A 和GOTO[S’,A]=S”进栈;}else if (ACTION[S,a]==ERROR) error();}

五、LR语法分析器系统实现

5.1 文法类及其子类的定义

5.1.1上下文无关文法类(基类)

5.1.2 LR0文法类(子类)

5.1.3LR1文法类(子类)

5.2 分析类的定义

5.2.1 文法分析类(父类)

5.2.2 LR分析类(子类)

六、系统测试

6.1测试主程序

6.2 测试数据及测试结果

6.2.1测试样例

测试样例一:

测试样例二:

6.2.2 测试结果

样例一分析结果如下:

*i=i# 分析过程:[parsing]栈顶 输入查表 动作 注------------+--------+----+-------------------------------------+------0 # *s2 进栈 2 *2 * is3 进栈 3 i3 i =r4 出栈 1 个符号和状态 进栈:7 L L -> i7 L =r5 出栈 1 个符号和状态 进栈:6 R R -> L6 R =r3 出栈 2 个符号和状态 进栈:5 L L -> * R5 L =s8 进栈 8 =8 = is10 进栈 10 i10 i #r4 出栈 1 个符号和状态 进栈:12 L L -> i12 L #r5 出栈 1 个符号和状态 进栈:11 R R -> L11 R #r1 出栈 3 个符号和状态 进栈:1 S S -> L = R1 S #acc 成功接收!------------+--------+----+-------------------------------------+------end!文法分析正确!

样例二分析结果如下:

abab# 分析过程:[parsing]栈顶 输入查表 动作 注------------+--------+----+-------------------------------------+------0 # as3 进栈 3 a3 a bs4 进栈 4 b4 b ar3 出栈 1 个符号和状态 进栈:8 B B -> b8 B ar2 出栈 2 个符号和状态 进栈:2 B B -> a B2 B as6 进栈 6 a6 a bs7 进栈 7 b7 b #r3 出栈 1 个符号和状态 进栈:9 B B -> b9 B #r2 出栈 2 个符号和状态 进栈:5 B B -> a B5 B #r1 出栈 2 个符号和状态 进栈:1 S S -> B B1 S #acc 成功接收!------------+--------+----+-------------------------------------+------end!文法分析正确!

附录(cpp源代码):

#include <bits/stdc++.h>using namespace std;// seta=seta U setb seta未改变返回值为false,否则为truebool insertSet(set<string> &seta, set<string> setb){int asize = seta.size();for (auto i : setb){seta.insert(i);}return seta.size() != asize;}struct Reflect{int first;string sign;int next;};struct Formula{string left;vector<string> right;Formula() {}Formula(string l, vector<string> r){left = l;right = r;}bool operator<(Formula it) const //重载<,放入map.key{if (left != it.left)return (left < it.left);else{if (right.size() != it.right.size())return right.size() < it.right.size();else{for (int i = 0; i < right.size(); i++){if (right[i] != it.right[i])return right[i] < it.right[i];}}}return false;}bool operator==(Formula f) const //重载==比较{return (left == f.left && right == f.right);}};struct item{Formula formula; //产生式int dot; //点的位置,-1表示到达最后set<string> symbol; //展望串item() {}item(Formula f, int d){formula = f;dot = d;}bool operator<(item it) const //重载<,放入set{if (symbol != it.symbol){return symbol < it.symbol;}if (dot != it.dot)return dot < it.dot;return formula < it.formula;}bool operator==(item it) const //重载==比较{return (formula == it.formula && dot == it.dot && symbol == it.symbol);}};class CFG{protected:unordered_set<string> VT;//终结符集unordered_set<string> VN;//非终结符集string startSymbol; //开始符号map<int, Formula> production; //产生式集public:CFG() {}~CFG() {}//是终结符bool isVT(string str){return VT.find(str) != VT.end();}//是非终结符bool isVN(string str){return VN.find(str) != VN.end();}string getStartSymbol(){return startSymbol;}void setStartSymbol(string str){startSymbol = str;}unordered_set<string> getVT(){return VT;}void setVT(unordered_set<string> vt){VT = vt;}unordered_set<string> getVN(){return VN;}void setVN(unordered_set<string> vn){VN = vn;}map<int, Formula> getProduction(){return production;}void setProduction(map<int, Formula> pr){production = pr;}//重载>>friend istream &operator>>(istream &in, CFG &cfg){int num;in >> num;for (int i = 0; i < num; i++){string s;in >> s;cfg.VN.insert(s);}in >> num;for (int i = 0; i < num; i++){string s;in >> s;cfg.VT.insert(s);}in >> num;getchar();for (int i = 0; i < num; i++){string str;string s;char ch;vector<string> vct;in >> s;in >> str;while (true){ch = in.get();if (ch != ' ')break;in >> str;vct.push_back(str);}Formula f(s, vct);cfg.production[i] = f;}string s;in >> s;cfg.setStartSymbol(s);return in;}//重载<<friend ostream &operator<<(ostream &os, CFG &cfg){os << " CFG=(VN,VT,P,S)";os << "\n VN:";for (auto i : cfg.VN){os << ' ' << i;}os << "\n VT:";for (auto i : cfg.VT){os << ' ' << i;}os << "\n Production:" << endl;for (auto pr : cfg.production){os << "" << pr.first << ':' << ' ' << pr.second.left << " ->";for (auto j : pr.second.right){os << ' ' << j;}os << endl;}os << " StartSymbol:";os << ' ' << cfg.startSymbol << endl;return os;}};class CFG_LR1 : public CFG{private:map<string, set<string>> firstSet; // first集map<int, set<item>> itemset; //项目集vector<Reflect> GOfuction; // GO映射public:CFG_LR1();~CFG_LR1();map<int, set<item>> getItemset();vector<Reflect> getGOfuction();//计算First集合void culculateFirstSet();//建立项目集void createItem();//输出项目集void outPutItem();//求闭包void Closure(set<item> &ist);};CFG_LR1::CFG_LR1() {}CFG_LR1::~CFG_LR1() {}vector<Reflect> CFG_LR1::getGOfuction(){return GOfuction;}map<int, set<item>> CFG_LR1::getItemset(){return itemset;}void CFG_LR1::culculateFirstSet(){//初始化空集合set<string> us;for (auto i : getVN()){firstSet[i] = us;}//遍历表达式while (true){bool changeFlag = false;for (auto pr : getProduction()){//如果X->ε,把ε加入first(X)if (pr.second.right[0] == "ε"){if (firstSet[pr.second.left].find("ε") != firstSet[pr.second.left].end())continue;firstSet[pr.second.left].insert("ε");changeFlag = true;}else // X->Y1Y2...{for (int i = 0; i < pr.second.right.size(); i++){string symbol = pr.second.right[i];if (getVT().find(symbol) != getVT().end()){if (firstSet[pr.second.left].find(symbol) != firstSet[pr.second.left].end())break;firstSet[pr.second.left].insert(symbol);changeFlag = true;break;}else{if (insertSet(firstSet[pr.second.left], firstSet[symbol]))changeFlag = true;if (firstSet[symbol].find("ε") == firstSet[symbol].end()){break;}else{if (i == pr.second.right.size() - 1) //最后一个非终结符含有ε{if (firstSet[pr.second.left].find("ε") != firstSet[pr.second.left].end())continue;firstSet[pr.second.left].insert("ε");changeFlag = true;}}}}}}if (changeFlag == false)break;}}void CFG_LR1::createItem(){//计算First集合culculateFirstSet();//项目编号int index = 0;//初始化符号集合unordered_set<string> sign = getVT();for (auto vn : getVN()){sign.insert(vn);}queue<int> deal; //项目集处理队列//开始项目入队列set<item> beginist;string start = getStartSymbol();for (auto pr : getProduction()){if (pr.second.left == start){item i(pr.second, 0);i.symbol.insert("#");beginist.insert(i);}}Closure(beginist);itemset[index] = beginist;deal.push(index); //初始项目集编号入队index++;while (!deal.empty()) //处理队列不空{int num = deal.front();set<item> ist = itemset[num];//遍历符号for (auto v : sign){set<item> st;for (auto it : ist){if (it.dot != -1) //未到末尾{if (it.formula.right[it.dot] == v) //下一个读入的符号是v{item i(it.formula, it.dot + 1);if (i.dot >= i.formula.right.size())i.dot = -1;i.symbol = it.symbol;st.insert(i);}}}Closure(st);if (!st.empty()){int flag = -1;for (auto it : itemset){if (st == it.second)flag = it.first;}if (flag == -1){itemset[index] = st;Reflect r;r.first = num;r.sign = v;r.next = index;GOfuction.push_back(r);deal.push(index);index++;}else{Reflect r;r.first = num;r.sign = v;r.next = flag;GOfuction.push_back(r);}}}deal.pop();}}void CFG_LR1::outPutItem(){cout << "\n[LR(1) item set cluster]" << endl;for (auto it0 : itemset){cout << " I" << it0.first << ':' << endl;for (auto it1 : it0.second){cout << " ";cout << it1.formula.left << ' ' << "->";for (int i = 0; i < it1.formula.right.size(); i++){if (i == it1.dot){cout << " .";}cout << ' ' << it1.formula.right[i];}if (it1.dot == -1)cout << " .";cout << " , ";for (auto s : it1.symbol){cout << s << ' ';}cout << endl;}}}void CFG_LR1::Closure(set<item> &ist){queue<item> que; //处理队列for (auto it : ist){que.push(it);}while (!que.empty()){item it = que.front();if (it.dot != -1){// dot后面是非终结符string str = it.formula.right[it.dot];if (isVN(str)){for (auto pr : getProduction()){if (pr.second.left == str){item i(pr.second, 0);//如果待归约符号后面为空if (it.dot == it.formula.right.size() - 1){i.symbol = it.symbol;}else //如果待归约符号后面不为空{string next = it.formula.right[it.dot + 1];if (isVN(next)){if (firstSet[next].find("ε") == firstSet[next].end()){i.symbol = firstSet[next];}else{for (auto a : firstSet[next]){if (a != "ε")i.symbol.insert(a);}}}else{i.symbol.insert(next);}}que.push(i);ist.insert(i);}}}}que.pop();}}enum ActionState{STATE,REVERSE,ACCEPT,ERROR,};struct action{ActionState state;int num = -1;};class PredictTable{private:map<int, Formula> production; //产生式集public:PredictTable(){};~PredictTable(){};map<int, Formula> getProduction(){return production;}void setProduction(map<int, Formula> pr){production = pr;}int getFormulaNum(Formula f){for (auto pr : production){if (pr.second == f)return pr.first;}return -1; //未找到返回-1}};class PredictTable_LR : public PredictTable{private:unordered_set<string> actionHeader; // action表头unordered_set<string> gotoheader; // goto表头map<int, map<string, action>> table;public:PredictTable_LR();PredictTable_LR(CFG_LR1 lr1);~PredictTable_LR();unordered_set<string> getActionHeader();unordered_set<string> getGotoHeader();//分析程序bool analyse(vector<string> l);//重载<<输出分析表friend ostream &operator<<(ostream &os, PredictTable_LR &lrtable);//分析串bool analyse();};PredictTable_LR::PredictTable_LR() {}PredictTable_LR::PredictTable_LR(CFG_LR1 lr1){//是否是LR1bool isLLR1 = true;//初始化产生式setProduction(lr1.getProduction());//初始化表头actionHeader = lr1.getVT();actionHeader.insert("#");for (auto vn : lr1.getVN()){if (vn != lr1.getStartSymbol()){gotoheader.insert(vn);}}// 初始化表格for (auto it : lr1.getItemset()){action a;a.state = ERROR;for (auto vt : actionHeader){table[it.first][vt] = a;}for (auto vn : gotoheader){table[it.first][vn] = a;}}// 赋值ACCETfor (auto it : lr1.getItemset()){for (auto it0 : it.second){if (it0.dot == -1 && it0.formula.left == lr1.getStartSymbol()){action i;i.state = ACCEPT;if (table[it.first]["#"].state != ERROR){isLLR1 = false;}table[it.first]["#"] = i;}}}//移进项for (auto g : lr1.getGOfuction()){action a;a.state = STATE;a.num = g.next;if (table[g.first][g.sign].state != ERROR){isLLR1 = false;}table[g.first][g.sign] = a;}//归约项for (auto its : lr1.getItemset()){for (auto it : its.second){if (it.dot == -1 && it.formula.left != lr1.getStartSymbol()){action a;a.state = REVERSE;a.num = getFormulaNum(it.formula);for (auto s : it.symbol){if (table[its.first][s].state != ERROR){isLLR1 = false;}table[its.first][s] = a;}}}}if (isLLR1){cout << "\n文法是 LR(1) 文法!\n";}else{cout << "\n文法不是 LR(1) 文法!\n";}}PredictTable_LR::~PredictTable_LR() {}unordered_set<string> PredictTable_LR::getActionHeader(){return actionHeader;}unordered_set<string> PredictTable_LR::getGotoHeader(){return gotoheader;}bool PredictTable_LR::analyse(){vector<string> l;string str;do{cin >> str;l.push_back(str);} while (str != "#");cout << endl;for (auto i : l){cout << i;}cout << " 分析过程:" << endl;stack<int> st_state;stack<string> st_str;st_str.push("#");st_state.push(0);cout << "[parsing]" << endl;cout << "栈顶 输入查表 动作";cout << " 注" << endl;cout << "------------+--------+----+";cout << "-------------------------------------+-----------" << endl;for (int i = 0; i < l.size(); i++){string s = l[i];int top = st_state.top();action a = table[top][s];string str_top = st_str.top();cout << right << setw(2) << top << " " << str_top << " ";cout << s << "";if (a.state == ERROR){cout << "错误,分析终止。" << endl;return false;}else if (a.state == STATE){cout << 's' << left << setw(2) << a.num << " ";st_str.push(s);st_state.push(a.num);cout << "进栈 " << left << setw(2) << a.num << ' ' << s << endl;continue;}else if (a.state == REVERSE){cout << 'r' << left << setw(2) << a.num << " ";Formula f = getProduction()[a.num];cout << "出栈 " << left << setw(2) << f.right.size() << "个符号和状态";for (int k = 0; k < f.right.size(); k++){st_str.pop();st_state.pop();}top = st_state.top();cout << " 进栈:";int x = table[top][f.left].num;if (x == -1){cout << "错误,分析终止。" << endl;return false;}st_state.push(x);cout << left << setw(2) << x << ' ';st_str.push(f.left);cout << f.left << " ";cout << f.left << " ->";for (auto i : f.right){cout << ' ' << i;}i--;cout << endl;}else if (a.state == ACCEPT){cout << "acc"<< " ";cout << "成功接收!" << endl;cout << "------------+--------+----+";cout << "-------------------------------------+-----------" << endl;cout << " end!" << endl;return true;}}return false;}ostream &operator<<(ostream &os, PredictTable_LR &lrtable){os << "\nLR(1)分析表" << endl;os << " Action:" << endl;os << "";for (auto vt : lrtable.actionHeader){os.setf(ios::left);os.width(6);os << vt;}os << endl;for (int i = 0; i < lrtable.table.size(); i++){os.setf(ios::left);os.width(5);os << i << ':';for (auto ah : lrtable.actionHeader){action a = lrtable.table[i][ah];if (a.state == ACCEPT){os.setf(ios::left);os.width(6);os << "acc";}else if (a.state == REVERSE){string s = "r" + to_string(a.num);os.setf(ios::left);os.width(6);os << s;}else if (a.state == STATE){string s = "s" + to_string(a.num);os.setf(ios::left);os.width(6);os << s;}else{os << "";}}os << endl;}os << "\n Goto:" << endl;os << "";for (auto gh : lrtable.gotoheader){os.setf(ios::left);os.width(6);os << gh;}os << endl;for (int i = 0; i < lrtable.table.size(); i++){os.setf(ios::left);os.width(5);os << i << ':';for (auto gh : lrtable.gotoheader){action a = lrtable.table[i][gh];if (a.num != -1){os.setf(ios::left);os.width(6);os << a.num;}else{os << "";}}os << endl;}return os;}int main(){CFG_LR1 lr1;cin >> lr1;cout << lr1;lr1.createItem();lr1.outPutItem();PredictTable_LR lr1table(lr1);cout << lr1table;if (lr1table.analyse())cout << "文法分析正确!" << endl;elsecout << "文法分析错误!" << endl;return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。