语义分析及中间代码生成程序设计原理与实现技术--实验报告及源代码北京交通大学
- 格式:doc
- 大小:149.50 KB
- 文档页数:24
实验报告封面课程名称:编译原理课程代码:SS2027任课老师:彭小娟实验指导老师: 彭小娟实验报告名称:实验十四:语义分析与中间代码生成1学生姓名:学号:教学班:递交日期:签收人:我申明,本报告内的实验已按要求完成,报告完全是由我个人完成,并没有抄袭行为。
我已经保留了这份实验报告的副本。
申明人(签名):实验报告评语与评分:评阅老师签名:彭小娟一、实验名称:语义分析与中间代码生成1二、实验日期: 年 月 日三、实验目的:1. 理解相关概念:中间代码、三地址码,各种语句的目标代码结构2. 掌握三地址码(三元式、四元式、DAG 图),3. 理解赋值语句三地址代码的翻译模式四、实验用的仪器和材料:(操作系统:CPU :内存:硬盘:软件:)硬件:PC 人手一台软件:office五、实验的步骤和方法:1. 给出下面中缀式的逆波兰表示(后缀式),后缀式的中缀式表示/*)(*)/(*++-+-+-++e d c ab d c b a e d c b anot A or not (C or not D)2. 请将表达式-(a+b)*(c+d)-(a+b+c)分别表示成三元式、四元式序列。
3. 按7.3节所说的方法,写出下面赋值句)A+=的自下而上语法制导B-(*:DC翻译过程。
给出所产生的三地址代码。
六、数据记录和计算:七、实验结果或结论:(总结)八、备注或说明:可写上实验成功或失败的原因,实验后的心得体会、建议等。
九、引用参考文献:即在本实验中所引用的之資料。
算符优先语法分析设计原理与实现技术XXX 1028XXX 计科1XXX 班功能描述能够有效识别以下算符优先文法E T E+T | E-TT T T*F | T/F | FF T (E) | i所描述算术表达式.主要数据结构描述程序结构描述设计方法2. 根据算符优先矩阵算数表达式的词法分析结果进行语法分析,分析算法为:数据结构:符号栈S ---存放所有读进的符号(计数i)K ---符号栈使用深度a ---工作单元R, Q ---变量分析算法:先找最左素短语的尾部(>)再找最左素短语的头部(<)以分析表达式i+i*i为例,详细过程如下:■算符优先关系矩阵例:舖入串i+i*i 的界苻优先分析过程(査界替优先关系矩体)1#N + N**<i■11# N + N*'■ 1#1#N + N J* N+<*># 接受# N + N#<+>## N结论:汁详iJt 文法的命法句子函数原型功能描述void in it()各种初始化操作,主要是建立符号与整 数、整数与行列号、整数与符号之间的映 射,也包括各全局变量的初始化void isVt(i nt )判断某整数所代表的符号是否是终结符##<i# i#<i>-l- #N#<+# N + +<i# N + i +<i>* # N+ N+<*分析栈优先关系号或’#'void comp(i nt a, int b) r比较两整数所代表的字符的优先关系—void adva nce() 从输入文件中读入一个词bool parser() 算符优先分析函数,根据算符优先矩阵进行语法分析int main (i nt argc, char *argv[]) 主函数,参数argv[1]代表输入文件函数调用关系程序执行图S(l)=#;i=l;k=Q;k~k+1: R=siiLrQ=SG); j=j-ij=j-i l| t=i 11i=讦丄;S(i)=R程序测试测试用例一:(a+b*c)+d+e+a*c/b 首先调用实验一的词法分析程序,得到如下分析结果:(19, '(')(12, 'a')(14, '+')(12, 'b')(16, '*')(12, 'c')(20, ')')(14, '+')(12, 'd')(14, '+')(12, 'e')(14, '+')(12, 'a')(16, '*')(12, 'c')(17, '/')(12, 'b')在以此分析结果作为本程序实验结果的输入,得到如下分析结果:taw Cf'v/indov^5\system32\cmd.exe该结果显示了详细的分析过程,且表明该表达式是一个符合该文法的表达式测试用例二:(a+b*c)+d*-a*c+(a+b同样调用实验--的词法分析程序,得到如下结果:(19, '(')(12, 'a')(14, '+')(12, 'b')(16, '*')(12, 'c')(20, ')')(14, '+') (12, 'd') (16, '*') (15, '-') (12, 'a') (16, '*') (12, 'c') (14, '+') (19, '(') (12, 'a') (14, '+') (12, 'b')以此分析结果作为本实验程序的输入,得到如下语法分析结果:实验结果表明,在分析过程中出现了错误,分析过程未完成,该样例是一个非法的表达式.学习总结按算符优先关系所确定的应被规约的子串恰好是当前举行的最左素短语.尽管算符优先分析也属于自底向上语法分析的范畴,但却不是严格的从左至右的规范分析,每步所得的句型自然也不是一个规范句型.采用上述策略进行算符优先分析时,尽管我们也指出了每一最左素短语应规约到的非终结符号,然而每次在查找最左素短语时,起主导作用的是终结符号间的优先关系,两终结符号之间究竟是哪个非终结符号无关宏旨.// operator_prior.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <stdio.h>#include <ctype.h>#include <map>#include <vector>#include <string>#define ID 12#define ADD 14#define SUB 15#define MUL 16#define DIV 17#define LP 19#define RP 20#define EOI 31#define SHARP 32#define EQ 0#define BT 1#define LT 2#define UD 3#define N_Base 1000 using namespace std;FILE *fp;int lookahead, yylineno;bool success;map<int, int> intToint; map<char, int> charToint; map<int, char> intTochar; string grammer[8] = {"E+T", "E-T", "T","T*F", "T/F", "F","(E)", n:n};int prior_matrix[9][9] = {{BT, BT, LT, LT, LT, BT, LT, BT},{BT, BT, LT, LT, LT, BT, LT, BT},{BT, BT, BT, BT, LT, BT, LT, BT},{BT, BT, BT, BT, LT, BT, LT, BT},{LT, LT, LT, LT, LT, EQ, LT, UD},{BT, BT, BT, BT, UD, BT, UD, BT},{BT, BT, BT, BT, UD, BT, UD, BT},{LT, LT, LT, LT, LT, UD, LT, EQ}};void init() {success = true;yylineno = 0;intToint[ADD] = 0; intToint[SUB] = 1;intToint[MUL] = 2; intToint[DIV] = 3;intToint[LP] = 4; intToint[RP] = 5;intToint[ID] = 6; intToint[SHARP] = 7;charToint['+'] = ADD; charToint['-'] = SUB;charToint['*'] = MUL; charToint['/'] = DIV;charToint['('] = LP; charToint[')'] = RP;charToint['i'] = ID;intTochar[ADD] = '+'; intTochar[SUB] = '-';intTochar[MUL] = '*'; intTochar[DIV] = '/';intTochar[LP] = '('; intTochar[RP] = ')';intTochar[ID] = 'i'; intTochar[SHARP] = '#';intTochar[N_Base] = 'N';}bool isVt(int a) {if (a >= N_Base) return false;else return true;}int comp(int a, int b) { int x = intToint[a];int y = intToint[b]; return prior_matrix[x][y]; }void advance() {if (fscanf(fp, "(%d", &lookahead) == EOF) { lookahead = SHARP;} else {char ch;do {ch = fgetc(fp);if (ch == '\n' || ch == EOF) break; } while (true);} yylineno++;}void parser() {int stack[100], top = 0;int i, j, k, ii, jj;stack[top++] = SHARP;advance();do {for (i = 0; i < top; i++) {printf("%c", intTochar[stack[i]]);}printf("\t%c\n", intTochar[lookahead]);for (i = top - 1; i >= 0; i--) { if (isVt(stack[i])) break;}int res = comp(stack[i], lookahead);if (res == LT || res == EQ) { stack[top++] = lookahead; advance();} else if (res == BT) {int temp = stack[i]; for (j = i - 1; j >= 0; j--) {if (isVt(stack[j])) {if (comp(stack[j], temp) == LT) {break;} else {temp = stack[j];}}}for (k = 0; k < 8; k++) {if ((int)grammer[k].length() == top - 1 - j) {ii = j + 1;jj = 0;do {if (grammer[k].at(jj) >= 'A' && grammer[k].at(jj) <= 'Z'){ if (isVt(stack[ii])) break;} else {if (charToint[grammer[k].at(jj)] != stack[ii]) break;}ii++;jj++;} while (ii < top && jj < (int)grammer[k].length());if (ii >= top) break;}}if (k >= 8) {success = false;return ;}top = j + 1;stack[top++] = N_Base;} else {success = false;return ;}if (stack[0] == SHARP && stack[1] == N_Base&& stack[2] == SHARP) { printf("#N#\n"); break;}} while (true);success = true;}int main(int argc, char *argv[]) {if (argc == 2) {fp = fopen(argv[1], "r");init();parser();if (success) printf("This is a legal expression."); else printf("Thisis a illegal expression.");} else {printf(" 参数错误!\n");}return 0;。
LL(1)语法分析设计原理与实现技术实验计科100X班 10284XXX程序设计功能实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的LL(1)文法的LL(1)分析程序。
G[E]: E→TE′E′→ATE′|εT→FT′T′→MFT′|εF→(E)|iA→+|-M→*|/说明:终结符号i 为用户定义的简单变量,即标识符的定义。
主要数据结构描述由文法可得:对于E:FIRST( E )= {(, i }对于E’: FIRST( E’ ) ={+,−,ε}对于T: FIRST( T )= ={(, i }对于T’: FIRST( T’)= ={*,∕,ε}对于F: FIRST( F )= ={(, i }对于A: FIRST( A )= ={+, - }对于M: FIRST(M)= ={*, / }由此我们容易得出各非终结符的FOLLOW集合如下:FOLLOW( E )= { ),#}FOLLOW(E’) ={ ),#}FOLLOW( T ) ={+,−,),#}FOLLOW( T’ ) = FOLLOW( T ) ={+,−,),#}FOLLOW( F )=FIRST(T’)\ε∪FOLLOW(T’)={*,∕,+,−,),#}FOLLOW( A )= { (, i }FOLLOW( M )= { (, i}文法LL(1)的预测分析表(表1):表1. LL(1)预测分析表注:为编程方便,在程序中,将E’、T’改为G、S程序结构描述1.设计方法:程序通过从文本文档读入数据,将所读数据以空格、回车或者退格为标示符,分为字符串,对字符串进行词法分析,最后将所有字符串按序输出到结果文档中,并在结果文档中标明每个字符串的类别序号。
2、程序中主要函数定义和调用关系如下:函数:void print()作用:输出分析栈void print1();作用:输出剩余串int main();作用:主要逻辑功能程序执行图如下:实验结果测试用例1:i+i*i#测试用例2:i-i++#实验总结相对于递归下降分析法,LL(1)分析法更为有效.采用此种方法的分析器由一张预测分析表(LL(1)分析表)、一个控制程序(表驱动程序)和一个分析栈组成,预测分析表中个元素的含义是:或者指出当前推到所应使用过的产生式,或者指出输入符号串中存在语法错误.LL(1)分析法的局限在于:只能分析LL(1)文法或者某些非LL(1)文法,但需先将其改造成LL(1)文法。
语义分析及中间代码生成程序设计原理与实现技术XXX 1028XXX2 计科1XXX班1.程序功能描述完成以下描述赋值语句和算术表达式文法的语法制导生成中间代码四元式的过程。
G[A]:A→V:=EE→E+T∣E-T∣T→T*F∣T/F∣FF→(E)∣iV→i说明:终结符号i 为用户定义的简单变量,即标识符的定义。
2. 设计要求(1)给出每一产生式对应的语义动作;(2)设计中间代码四元式的结构(暂不与符号表有关)。
(3)输入串应是词法分析的输出二元式序列,即某算术表达式“实验项目一”的输出结果。
输出为输入串的四元式序列中间文件。
(4)设计两个测试用例(尽可能完备),并给出程序执行结果四元式序列。
3.主要数据结构描述:本程序采用的是算符优先文法,文法以及算符优先矩阵是根据第四次实验来修改的,所以主要的数据结构也跟第四次差不多,主要为文法的表示,FirstVT集和LastVT集以及算符优先矩阵:算符优先矩阵采用二维字符数组表示的:char mtr[9][9]; //算符优先矩阵4.程序结构描述:本程序一共有8功能函数:void get(); //获取文法void print(); //打印文法void fun(); //求FirstVT 和 LastVTvoid matrix(); //求算符优先矩阵void test(); //测试文法int cmp(char a,char b); 比较两个运算符的优先级 1 0 -1void out(char now,int avg1,int avg2); //打印四元式int ope(char op,int a,int b); //定义四元式计算方法5.实验代码详见附件6.程序测试6.1 功能测试程序运行显示如下功能菜单:选择打印文法:选择构造FirstVt集和LastVT集:选择构造算符优先矩阵:6.2 文法测试测试1:1+2*3测试2:2+3+4*5+(6/2)7.学习总结本次实验完成了语义及中间代码生成的设计原理与实现,所采用的方法为算符优先分析方法,首先根据文法求出此文法的FirstVT集和LastVT集,然后根据他们求出此文法的算符优先矩阵。
语义分析及中间代码生成程序设计原理与实现技术--实验报告及源代码北京交通大学语义分析及中间代码生成程序设计原理与实现技术XXX 1028XXX2 计科1XXX班1. 程序功能描述完成以下描述赋值语句和算术表达式文法的语法制导生成中间代码四元式的过程。
G[A]:A?V:=EE?E+T?E-T?T?T*F?T/F?FF?(E)?iV?i说明:终结符号i 为用户定义的简单变量,即标识符的定义。
2. 设计要求(1)给出每一产生式对应的语义动作;(2)设计中间代码四元式的结构(暂不与符号表有关)。
(3)输入串应是词法分析的输出二元式序列,即某算术表达式“实验项目一”的输出结果。
输出为输入串的四元式序列中间文件。
(4)设计两个测试用例(尽可能完备),并给出程序执行结果四元式序列。
3. 主要数据结构描述:本程序采用的是算符优先文法,文法以及算符优先矩阵是根据第四次实验来修改的,所以主要的数据结构也跟第四次差不多,主要为文法的表示,FirstVT集和LastVT集以及算符优先矩阵:struct info{char left;vector<string> right;vector<char> first;vector<char> last;};算符优先矩阵采用二维字符数组表示的:char mtr[9][9]; //算符优先矩阵4. 程序结构描述:本程序一共有8功能函数:void get(); //获取文法void print(); //打印文法void fun(); //求FirstVT 和 LastVTvoid matrix(); //求算符优先矩阵void test(); //测试文法int cmp(char a,char b); 比较两个运算符的优先级 1 0 -1void out(char now,int avg1,int avg2); //打印四元式a,int b); //定义四元式计算方法 int ope(char op,int 5. 实验代码详见附件6. 程序测试6.1 功能测试程序运行显示如下功能菜单:选择打印文法:选择构造FirstVt集和LastVT集:选择构造算符优先矩阵:6.2 文法测试测试1:1+2*3测试2:2+3+4*5+(6/2)7. 学习总结本次实验完成了语义及中间代码生成的设计原理与实现,所采用的方法为算符优先分析方法,首先根据文法求出此文法的FirstVT集和LastVT集,然后根据他们求出此文法的算符优先矩阵。
由于此文法和第四次文法基本相同,只是多了一条赋值语句,所以采用的规则和第四次基本相同。
在分析阶段,每当遇到有规约的项目,判断一下,打印出此部运算的四元式,这样一步一步分析,知道输入的算术表达式计算分析完毕。
由于本次实验部分代码和第四次实验的代码比较相似,只需增加一点四元式的分析计算打印过程,就能够顺利完成本次实验。
通过这次实验,我对语义分析以及中间代码部分有了一定的提高,对以后的学习有了一定程度上的帮助。
// lb6.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h" #include <iostream> #include <string> #include <VECTOR> #include <stack>using namespace std;struct info{char left;vector<string> right; vector<char> first; vector<char> last; };vector<info> lang; char mtr[9][9]; //算符优先矩阵stack<char> sta;void get(); //获取文法void print(); //打印文法void fun(); //求FirstVT 和 LastVT void matrix(); //求算符优先矩阵void test(); //测试文法int cmp(char a,char b); //比较两个运算符的优先级 10 -1void out(char now,int avg1,int avg2); //打印四元式int ope(char op,int a,int b); //定义四元式计算方法int main(){int choose;while(1){cout << "****************************************" << endl;cout << " 获取文法请按 1" << endl;cout << " 打印文法请按 2" << endl;cout << " 构造FirstVT集和LastVT集请按 3" << endl;cout << " 构造优先关系矩阵请按 4" << endl;cout << " 文法测试请按 5" << endl;cout << " 结束请按 0" << endl;cout << "****************************************" << endl; cout << endl;cin >> choose;if(choose == 0)break;switch(choose){case 1: get(); break;case 2: print(); break;case 3: fun(); break;case 4: matrix(); break;case 5: test(); break;default:break;}}return 0;}void get(){info temp,temp1,temp2;temp.left = 'E';temp.right.push_back("E+T");temp.right.push_back("E-T");temp.right.push_back("T");temp.right.push_back("i");temp1.left = 'T';temp1.right.push_back("T*F");temp1.right.push_back("T/F");temp1.right.push_back("F");temp2.left = 'F';temp2.right.push_back("(E)");temp2.right.push_back("i");lang.push_back(temp);lang.push_back(temp1);lang.push_back(temp2);cout << "****************************************" << endl; cout << " 文法获取完成" << endl;cout << "****************************************" << endl; cout << endl;}void print(){cout << "****************************************" << endl; for(int i = 0;i < lang.size();i ++){for(int j = 0;j < lang[i].right.size();j ++){cout << lang[i].left << " --> ";cout << lang[i].right[j] << endl;}}cout << "****************************************" << endl; cout << endl;}void fun(){int i,j,sign = 0,sign1 = 0;for(i = 0;i < lang.size();i ++){for(j = 0;j < lang[i].right.size();j ++){string temp = lang[i].right[j]; //获取右部if(temp[0] > 'Z' || temp[0] < 'A'){ //终结符lang[i].first.push_back(temp[0]);}else if(temp.length() >= 2){ //终结符if(temp[1] > 'Z' || temp[1] < 'A'){lang[i].first.push_back(temp[1]);}}}}for(i = 0;i < lang.size();i ++){for(j = 0;j < lang[i].right.size();j ++){string temp = lang[i].right[j]; //获取右部if((temp[0] > 'Z' || temp[0] < 'A') && temp.length() == 1){ // 终结符lang[i].last.push_back(temp[0]);}else if(temp.length() >= 3){ //终结符if(temp[1] > 'Z' || temp[1] < 'A')lang[i].last.push_back(temp[1]);else if(temp[2] > 'Z' || temp[2] < 'A') //终结符lang[i].last.push_back(temp[2]);}}}while(sign == 0){ //迭代FirstVTsign = 1;for(i = 0;i < lang.size();i ++){for(j = 0;j < lang[i].right.size();j ++){string temp = lang[i].right[j]; //获取右部if(temp.length() == 1 && (temp[0] <= 'Z' && temp[0] >= 'A')){//可以迭代for(int k = 0;k < lang.size();k ++){if(lang[k].left == temp[0]){ //找到了,添加元素for(int p = 0;p < lang[k].first.size();p ++){sign1 = 0;char ch = lang[k].first[p];for(int q = 0;q < lang[i].first.size();q++){if(lang[i].first[q] == ch){ //包含了sign1 = 1;}}if(sign1 == 0){lang[i].first.push_back(ch);sign = 0;}}}}}}}}sign = 0;while(sign == 0){ //迭代LastVTsign = 1;for(i = 0;i < lang.size();i ++){for(j = 0;j < lang[i].right.size();j ++){string temp = lang[i].right[j]; //获取右部if(temp.length() == 1 && (temp[0] <= 'Z' && temp[0] >= 'A')){//可以迭代for(int k = 0;k < lang.size();k ++){if(lang[k].left == temp[0]){ //找到了,添加元素for(int p = 0;p < lang[k].last.size();p ++){sign1 = 0;char ch = lang[k].last[p];for(int q = 0;q < lang[i].last.size();q++){if(lang[i].last[q] == ch){ //包含了sign1 = 1;}}if(sign1 == 0){lang[i].last.push_back(ch);sign = 0;}}}}}}}}cout << "****************************************" << endl; cout << "FirstVT:" << endl;for(i = 0;i < lang.size();i ++){cout << lang[i].left << " : ";for(j = 0;j < lang[i].first.size();j ++){cout << lang[i].first[j] << " ";}cout << endl;}cout << endl;cout << "LasttVT:" << endl;for(i = 0;i < lang.size();i ++){cout << lang[i].left << " : ";for(j = 0;j < lang[i].last.size();j ++){cout << lang[i].last[j] << " ";}cout << endl;}cout << "****************************************" << endl; cout << endl;}void matrix(){int i,j;for(i = 0;i < 9;i ++){ //初始化for(j = 0;j < 9;j ++){mtr[i][j] = 'n';}}string temp = "+-*/()i#";for(i = 1;i < 9;i ++){mtr[i][0] = temp[i - 1];mtr[0][i] = temp[i - 1]; }vector<string> str;for(i = 0;i < lang.size();i ++){ //aU a < FirstVT(U)for(j = 0;j < lang[i].right.size();j ++){string ss = lang[i].right[j];string ok = "";if(ss.length() > 2){if((ss[0] > 'Z' || ss[0] < 'A') && (ss[1] <= 'Z' && ss[1] >= 'A')){ //aUok = "";ok += ss[0];ok += ss[1];str.push_back(ok);}if((ss[1] > 'Z' || ss[1] < 'A') && (ss[2] <= 'Z' && ss[2] >= 'A')){ //aUok = "";ok += ss[1];ok += ss[2];str.push_back(ok);}}}}for(i = 0;i < str.size();i ++){for(j = 1;j < 9;j ++){if(mtr[j][0] == str[i][0]){ //Find a Then Find FirstVt(U) for(int k = 0;k < lang.size();k ++){if(lang[k].left == str[i][1]){ //Find Ufor(int p = 0;p < lang[k].first.size();p ++){for(int q = 1;q < 9;q ++){if(mtr[q][0] == lang[k].first[p]){mtr[j][q] = '<';}}}}}}}}str.clear();for(i = 0;i < lang.size();i ++){ //Ua LastVT(U) > afor(j = 0;j < lang[i].right.size();j ++){string ss = lang[i].right[j];string ok = "";if(ss.length() > 2){if((ss[1] > 'Z' || ss[1] < 'A') && (ss[0] <= 'Z' && ss[0] >= 'A')){ //Uaok = "";ok += ss[0];ok += ss[1];str.push_back(ok);}if((ss[2] > 'Z' || ss[2] < 'A') && (ss[1] <= 'Z' && ss[1] >= 'A')){ //Uaok = "";ok += ss[1];ok += ss[2];str.push_back(ok);}}}}for(i = 0;i < str.size();i ++){for(j = 1;j < 9;j ++){if(mtr[0][j] == str[i][1]){ //Find a Then Find LastVt(U)for(int k = 0;k < lang.size();k ++){if(lang[k].left == str[i][0]){ //Find Ufor(int p = 0;p < lang[k].last.size();p ++){for(int q = 1;q < 9;q ++){if(mtr[0][q] == lang[k].last[p]){mtr[q][j] = '>';}}}}}}}}str.clear();for(i = 0;i < lang.size();i ++){ //ab aUb a = bfor(j = 0;j < lang[i].right.size();j ++){string ss = lang[i].right[j];string ok = "";if(ss.length() > 2){if((ss[1] > 'Z' || ss[1] < 'A') && (ss[0] > 'Z' || ss[0] < 'A')){ //aaok = "";ok += ss[0];ok += ss[1];str.push_back(ok);}if((ss[2] > 'Z' || ss[2] < 'A') && (ss[1] > 'Z' || ss[1] < 'A')){ //aaok = "";ok += ss[1];ok += ss[2];str.push_back(ok);}if((ss[2] > 'Z' || ss[2] < 'A') && (ss[0] > 'Z' || ss[0] < 'A')){ //aUaok = "";ok += ss[0];ok += ss[2];str.push_back(ok);}}}}for(i = 0;i < str.size();i ++){for(j = 1;j < 9;j ++){if(str[i][0] == mtr[j][0]){for(int k = 1;k < 9;k ++){if(mtr[0][k] == str[i][1]){mtr[j][k] = '=';}}}}}for(i = 0;i < lang[0].first.size();i ++){ //#for(j = 1;j < 9;j ++){if(lang[0].first[i] == mtr[0][j]){mtr[8][j] = '<';}}}for(i = 0;i < lang[0].first.size();i ++){ //#for(j = 1;j < 9;j ++){if(lang[0].first[i] == mtr[j][0]){mtr[j][8] = '>';}}}mtr[8][8] = '=';cout << "****************************************" << endl; for(i = 0;i < 9;i ++){for(j = 0;j < 9;j ++){if(mtr[i][j] != 'n')cout << mtr[i][j] << " ";elsecout << " ";}cout << endl;}cout << "****************************************" << endl; cout << endl;}void test(){cout << "****************************************" << endl; cout << "请输入算术表达式:" << endl;string str;cin >> str;str += '#';int i,j,k;stack<int> data;stack<char> op;op.push('#');char now = 'n'; //记录当前栈顶操作符int sign = 0;for(i = 0;i < str.length();i ++){sign = 0;if(str[i] >= '0' && str[i] <= '9'){ //操作数int temp = str[i] - '0';data.push(temp);}else{ //运算符op.push(str[i]);sign = 1;}if(now != 'n' && sign == 1){ //有可比性,并且操作符栈有更新if(!op.empty()){char top = op.top(); //栈顶元素while(cmp(now,top) == 1){ //需要规约int avg1 = data.top();data.pop();int avg2 = data.top();data.pop();out(now,avg2,avg1); //打印四元式data.push(ope(now,avg2,avg1));op.pop();op.pop();if(!op.empty()){now = op.top();}else{now = 'n';}op.push(top);}if(cmp(now,top) == 0){ op.pop();op.pop();if(!op.empty()){now = op.top();}else{char temp = '=';if(!data.empty()){int da = data.top(); out(temp,da,0);}}}}}else{ //不需要比较if(!op.empty()){now = op.top();}}}}int cmp(char a,char b){int i,j;for(i = 1;i < 9;i ++){if(mtr[i][0] == a){for(j = 1;j < 9;j ++){if(mtr[0][j] == b){if(mtr[i][j] == '>'){ return 1;}else if(mtr[i][j] == '='){ return 0;}else if(mtr[i][j] == '<'){ return -1;}}}}}return 2;}void out(char now,int avg1,int avg2){cout << "****************************************" << endl;cout << now << " ," << avg1 << " ," << avg2 << " ," <<ope(now,avg1,avg2)<< endl;cout << "****************************************" << endl;cout << endl; }int ope(char op,int a,int b){if(op == '+'){return a + b; }if(op == '-'){return a - b;}if(op == '*'){return a * b; }if(op == '/'){return a / b; }if(op == '='){return a;}return 0;}。