前言:(时隔好久,我才终于想起来) 继前面所写的两次编译原理的两次实验,我开始写课程设计的博文啦,我们的编译原理课设的题目几乎每个人都不一样(实际情况还是看你萌的情况啦),所以大家可以有选择的参考蛤!
初始条件:
主要任务:
经过简单的分析,我们可以知道,其实本次课设的设计完成应该是在前面两次课程实验的基础上进行的,首先应该是对相应语句所设计的文法进行词法分析,接着对词法分析的结果进行相应的语法分析,最后进行四元式的输出,即为本次课设的设计全过程。
在此,词法分析就不做过多的赘述了,大家可以参看下面链接对应的博文进行分析。
编译原理实验一:单词的词法分析程序设计
语法分析的话和之前的实验二中有所不同,实验二中我使用的是递归下降的方法,而在本次课设中我需要使用的方法是简单优先法,简单优先法在几个语法分析的方法中属于较为简单的类型(就我个人而言),因此,下面我将介绍简单优先法的相关分析过程。
1、文法描述
其中,do、while、{、}、(、i、)、m、;、n和r均为终结符,S、E、A、T为非终结符,i表示合法标识符,r表示比较运算符,m表示算术运算符,n表示无符号数。
(相关的属性文法就不展示了,因为这点我自己也没学太明白)
2、简单优先法设计过程
首先设计HEAD、LIST表如下:
进而可得到各个符号的优先关系表如下:
四元式是一种普遍采用的中间代码形式,其四个组成成分分别为:算符op、第一个运算对象ARG1、第二个运算对象ARG2、运算结果RESULT,运算对象和运算结果有时指用户自己定义的变量、有时指编译程序引进的临时变量。
因为在简单优先法的设计实现中需要栈,因此,编写代码过程中需要有栈的基本操作的函数实现,在此相关函数省略(之前学习的数据结构中有相关知识)
对DO-WHILE循环语句的翻译过程的设计
在此就不展示该部分的代码实现了,因为在之前的博客中有写过。
前面已经提到很多次了,本次的设计中我使用的是简单优先法进行单词的语法分析,同时输出中间代码——四元式。具体代码如下:
优先关系处理过程:
int pritable[17][17] =
{
//S E A T d { } w ( ) i = m ; n r #
/*S*/ {
N,N,N,N,N,N,1,N,N,N,N,N,N,N,N,N,1},
/*E*/ {
N,N,N,N,N,N,0,N,N,N,N,N,N,N,N,N,N},
/*A*/ {
N,N,N,N,N,N,1,N,N,N,N,N,N,N,N,N,N},
/*T*/ {
N,N,N,N,N,N,N,N,N,0,N,N,N,N,N,N,N},
/*d*/ {
N,N,N,N,N,0,N,N,N,N,N,N,N,N,N,N,N},
/*{*/ {
-1,0,N,N,-1,N,N,N,N,N,-1,N,N,N,N,N,N},
/*}*/ {
N,N,N,N,N,N,N,0,N,N,N,N,N,N,N,N,N},
/*w*/ {
N,N,N,N,N,N,N,N,0,N,N,N,N,N,N,N,N},
/*(*/ {
N,N,N,0,N,N,N,N,N,N,-1,N,N,N,N,N,N},
/*)*/ {
N,N,N,N,N,N,1,N,N,N,N,N,N,N,N,N,1},
/*i*/ {
N,N,N,N,N,N,N,N,N,1,N,0,0,0,N,0,N},
/*=*/ {
N,N,0,N,N,N,N,N,N,N,-1,N,N,N,-1,N,N},
/*m*/ {
N,N,0,N,N,N,N,N,N,N,-1,N,N,N,-1,N,N},
/*;*/ {
N,N,N,N,N,N,1,N,N,N,N,N,N,N,N,N,N},
/*n*/ {
N,N,N,N,N,N,N,N,N,N,N,N,N,0,N,N,N},
/*r*/ {
N,N,N,N,N,N,N,N,N,N,0,N,N,N,N,N,N},
/*#*/ {
-1,N,N,N,-1,N,N,N,N,N,N,N,N,N,N,N,N}
};
int compare(char a, char b) {
int row;
int line;
switch (a) {
case 'S':row = 0; break;
case 'E':row = 1; break;
case 'A':row = 2; break;
case 'T':row = 3; break;
case 'd':row = 4; break;
case '{':row = 5; break;
case '}':row = 6; break;
case 'w':row = 7; break;
case '(':row = 8; break;
case ')':row = 9; break;
case 'i':row = 10; break;
case '=':row = 11; break;
case 'm':row = 12; break;
case ';':row = 13; break;
case 'n':row = 14; break;
case 'r':row = 15; break;
case '#':row = 16; break;
}
switch (b) {
case 'S':line = 0; break;
case 'E':line = 1; break;
case 'A':line = 2; break;
case 'T':line = 3; break;
case 'd':line = 4; break;
case '{':line = 5; break;
case '}':line = 6; break;
case 'w':line = 7; break;
case '(':line = 8; break;
case ')':line = 9; break;
case 'i':line = 10; break;
case '=':line = 11; break;
case 'm':line = 12; break;
case ';':line = 13; break;
case 'n':line = 14; break;
case 'r':line = 15; break;
case '#':line = 16; break;
}
return pritable[row][line];
}
char redefine(string a) {
if (a == "do") {
return 'd';
}
else if (a == "while") {
return 'w';
}
else if ((a == "plus") || (a == "minus") || (a == "mul") || (a == "div") ) {
return 'm';
}
else if ((a == "greater") || (a == "less") || (a == "eql") || (a == "neq") || (a == "leq") || (a == "geq")) {
return 'r';
}
else if (a == "number") {
return 'n';
}
else if (a == "ident") {
return 'i';
}
else {
return NULL;
}
}
语法分析过程:
int grammer(int i) {
char s;
char a1 = '0', a2;//用于规约时进行判断
an.initStack();
int j;
for (j = 0; j < i; j++) {
str[j] = redefine(Anode[j].name);
if (!str[j]) {
str[j] = Anode[j].word1[0];
}
}
j = 0;
str[i] = '#';
while (true) {
s = an.gettop();
if (s == 'S'&&str[j] == '#') {
cout << "语法分析成功!" << endl;
return 1;
}
else {
int m = compare(s, str[j]);
if (m == 0 || m == -1) {
an.push(&str[j++]);//移进
process(i, j, m);
}
else if (m == 1) {
an.pop(&s);
do {
a2 = a1;
a1 = s;
an.pop(&s);
} while (compare(s, a1) == 0);
an.push(&s);
if (a1 = statute(a1, a2,j)) {
an.push(&a1);//规约
process(i, j, m);
}
else {
cout << "规约出错!" << endl;
cout << a1 << "位置规约出错" << endl;
return 0;
}
}
else {
cout << "语法分析出错!" << endl;
cout << s << "与" << str[j] << "之间不存在优先关系" << endl;
return 0;
}
}
}
return 0;
}
语法分析过程中规约条件以及相关四元式存储:
char statute(char a, char b,int j) {
int d = snum * 2 + 2;
if (a == 'd') {
return 'S';
}
else if (a == 'S') {
return 'E';
}
else if (((a == 'i') && (b == '='))) {
Sy[snum].op = Anode[j - d - 1].word1;
Sy[snum].c2 = Anode[j - d].word1;
Sy[snum].c1 = Anode[j - d - 2].word1;
snum++;
return 'E';
}
else if (a == 'n' || (a == 'i'&&b == ';')) {
return 'A';
}
else if (a == 'i'&&b == 'm') {
Sy[snum].op = Anode[j - d - 1].word1;
Sy[snum].c2 = Anode[j - d].word1;
Sy[snum].c1 = Anode[j - d - 2].word1;
snum++;
return 'A';
}
else if (a == 'i'&&b == 'r') {
Sy[snum].op = Anode[j - 2].word1;
Sy[snum].c2 = Anode[j - 1].word1;
Sy[snum].c1 = Anode[j - 3].word1;
snum++;
cnum++;
return 'T';
}
else {
cout << "规约不匹配!" << endl;
return NULL;
}
}
四元式的输出以及语法分析过程的展示输出:
void outquarter1() {
if ((snum - cnum) == 2) {
int i = 1;
cout << i++ << " " << "(" << Sy[0].op << "," << Sy[0].c1 << "," << Sy[0].c2 << "," << Sy[1].c1 << ")" << endl;
for (int t = 0; t < cnum; t++) {
cout << i++ << " " << "(" << Sy[snum-cnum+t].op << "," << Sy[snum - cnum + t].c1 << "," << Sy[snum - cnum + t].c2 << "," << "T" << t << ")" << endl;
cout << i++ << " " << "(" << "=" << "," << "T" << t << "," << "true" << "," << "1" << ")" << endl;
}
}
else {
int z = 1;
cout << z << " " << "(" << Sy[snum-cnum-2].op << "," << Sy[snum - cnum - 2].c1 << "," << Sy[snum - cnum - 2].c2 << "," << "T" << (z - 1) << ")" << endl;
z++;
for (int i = snum - cnum - 3; i--;i>0) {
cout << z << " " << "(" << Sy[i].op << "," << "T" << z - 2 << "," << Sy[i].c2 << "," << "T" << (z - 1) << ")" << endl;
}
cout << z << " " << "(" << Sy[0].op << "," << "T" << z - 2 << "," << Sy[0].c2 << "," << Sy[snum-cnum-1].c1 << ")" << endl;
int p = snum - cnum;
for (int t = 0; t < cnum; t++) {
//cout << ++z << " " << "(" << Sy[p+t].op << "," << Sy[p + t].c1 << "," << Sy[p + t].c2 << "," << "S" << t << ")" << endl;
//cout << ++z << " " << "(" << "=" << "," << "S" << t << "," << "true" << "," << "1" << ")" << endl;
cout << ++z << " " << "if" << " " << Sy[p + t].c1 << Sy[p + t].op << Sy[p + t].c2 << " " << "goto" << " " << t << endl;
}
}
}
void process(int i, int j, int m) {
cout << std::left << setw(5) << seq;
seq++;
an.printStack();
cout << " ";
for (int n = j; n <= i; n++) {
cout << str[n];
}
cout << std::right << setw(5) << m;
if (m == 1) {
cout << " " << "规约" << endl;
}
else {
cout << " " << "移进" << endl;
}
}
值得一提的是,在本次课程设计过程中,我实现了DO-WHILE语句嵌套的实现,在文法中可以体现出来。
具体的结果我就不展示了,还是那句话,大家有什么不清楚或者觉得本人写的不妥的地方可以留言指出或者私信我,谢谢大家。