0 Experiment purpose
Design, compile, implement and debug SLR(1) parser to deepen understanding of parser.
1 Experimental Requirements
According to the arithmetic expression grammar learned in the compilation theory course and the LR analysis table of the grammar, use C language to write a grammar analyzer that accepts arithmetic expressions as input, and complete it with the console (or text file, or combined with the lexical analyzer) ) as input, the console (or file) outputs the analysis results in the form of production sequences.
2 Experimental content
Realize LR syntax analyzer, example of execution process: analyze id+id*id, input id+id*id# according to the predictive analysis table on PPT, and analyze the popped and output content.
Grammar:
E'->E
E->E+T
E->T
T->T*F
T->F
F->(E)
F->id
3 Experiment ideas
1. First, I defined 7 functions, namely: the most important SLRScanner() function (for SLR grammar analysis); statestack() function (output state stack); signstack() function (output symbol stack); print( ) function (remaining string output); Action() function (for analysis and output action description); xfind() function (for finding predictive analysis variables); yfind() function (for finding predictive analysis table columns variable). Next, a two-dimensional array of strings is defined to store the predictive analysis table, and a two-dimensional character array is defined to store the extended grammar; two stacks, symbol stack and state stack, are defined.
2. The most important thing in this experiment program is the SLRScanner() function. Next, a brief analysis of this is carried out: at the beginning, the flag variable flag It is equal to 0 (do the initial shift operation), and continuously update the row variable and column variable to facilitate the next table lookup, and then push 0, # into the state stack and symbol stack respectively. Then use the xfind and yfind functions to search and assign values to the row variables and column variables, and judge the data in the corresponding predictive analysis table: if it is equal to 0, it does not conform to the grammar, return. If not, the corresponding symbols and states are pushed into the symbol stack and the state stack respectively, and at the same time, the remaining character strings and corresponding action descriptions are output. If equal to 's', set flag to 0, otherwise equal to 1. If flag is equal to 1, perform the specification (compare SR(1) with the corresponding extended grammar and simultaneously operate on the symbol stack, state stack, remaining strings and action description, and output the corresponding production formula.) If flag is equal to 2, do the shift operation after goto, and then compare it with the predictive analysis table. If SR is equal to 0, it proves that the result of the table lookup is wrong; if SR is equal to acc, the program ends, and the output string conforms to the grammar.
3. Other functions are also more important. They are called in the SLR grammar analysis function. Through the operation of the stack, the output of symbols and states is realized, which greatly simplifies the program; the Action function helps output action descriptions; and xfind and yfind help find predictive analysis tables, both play an indispensable role.
4 Experiment code
#include <bits/stdc++.h>
using namespace std;
string SLRGrammer[12][9]{
"s5", "0", "0", "s4", "0", "0", "1", "2", "3",
"0", "s6", "0", "0", "0", "acc", "0", "0", "0",
"0", "r2", "s7", "0", "r2", "r2", "0", "0", "0",
"0", "r4", "r4", "0", "r4", "r4", "0", "0", "0",
"s5", "0", "0", "s4", "0", "0", "8", "2", "3",
"0", "r6", "r6", "0", "r6", "r6", "0", "0", "0",
"s5", "0", "0", "s4", "0", "0", "0", "9", "3",
"s5", "0", "0", "s4", "0", "0", "0", "0", "a",
"0", "s6", "0", "0", "s11", "0", "0", "0", "0",
"0", "r1", "s7", "0", "r1", "r1", "0", "0", "0",
"0", "r3", "r3", "0", "r3", "r3", "0", "0", "0",
"0", "r5", "r5", "0", "r5", "r5", "0", "0", "0"};
char Grammer[7][10] = {"E→E'", "E→E+T", "E→T", "T→T*F", "T→F", "F→(E)", "F→id"};
char x[12] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b'};
char y[9] = {'i', '+', '*', '(', ')', '#', 'E', 'T', 'F'};
int xfind(char a);
int yfind(char a);
int stri = 0;
int flag = 0;
int strlength;
string SR;
string strs;
string str;
stack<char> state;
stack<char> sign;
void SLRScanner(string str);
void statestack();
void signstack();
void print(string s, int n);
void VerbScanner(string str, int i);
void Action(int i, int flag2, int x, int y);
string Convert(char a, string b);
void SLRScanner(string str)
{
for (; stri < str.length();)
{
if (flag == 0)
{
stri++;
int x, y;
state.push(SR[1]);
sign.push(str[stri - 1]);
x = xfind(SR[1]);
y = yfind(str[stri]);
SR = SLRGrammer[x][y];
if (SR == "0")
{
cout << "\t输入的字符串不符合SLR文法" << endl;
break;
}
print(str, stri);
signstack();
cout << "\t\t";
statestack();
cout << "\t\t\t";
Action(stri, 0, x, y);
printf("\n");
if (SR[0] == 's')
flag = 0;
else
flag = 1;
}
if (flag == 1)
{
int x, y;
char r, c;
if (SR[1] == '1')
{
for (int i = 0; i < 3; i++)
{
state.pop();
sign.pop();
}
sign.push('E');
r = state.top();
c = sign.top();
x = xfind(r);
y = yfind(c);
print(str, stri);
signstack();
cout << "\t\t";
statestack();
cout << "\t\t" << Grammer[1];
Action(stri, 1, x, y);
printf("\n");
SR = SLRGrammer[x][y];
}
else if (SR[1] == '2')
{
for (int i = 0; i < 1; i++)
{
state.pop();
sign.pop();
}
sign.push('E');
r = state.top();
c = sign.top();
x = xfind(r);
y = yfind(c);
print(str, stri);
signstack();
cout << "\t\t";
statestack();
cout << "\t\t" << Grammer[2] << "\t";
;
Action(stri, 1, x, y);
printf("\n");
SR = SLRGrammer[x][y];
}
else if (SR[1] == '3')
{
for (int i = 0; i < 3; i++)
{
state.pop();
sign.pop();
}
sign.push('T');
r = state.top();
c = sign.top();
x = xfind(r);
y = yfind(c);
print(str, stri);
signstack();
cout << "\t\t";
statestack();
cout << "\t\t" << Grammer[3];
Action(stri, 1, x, y);
printf("\n");
SR = SLRGrammer[x][y];
}
else if (SR[1] == '4')
{
for (int i = 0; i < 1; i++)
{
state.pop();
sign.pop();
}
sign.push('T');
r = state.top();
c = sign.top();
x = xfind(r);
y = yfind(c);
print(str, stri);
signstack();
cout << "\t\t";
statestack();
cout << "\t\t" << Grammer[4] << "\t";
;
Action(stri, 1, x, y);
printf("\n");
SR = SLRGrammer[x][y];
}
else if (SR[1] == '5')
{
for (int i = 0; i < 3; i++)
{
state.pop();
sign.pop();
}
sign.push('F');
r = state.top();
c = sign.top();
x = xfind(r);
y = yfind(c);
print(str, stri);
signstack();
cout << "\t\t";
statestack();
cout << "\t\t" << Grammer[5] << "\t";
;
Action(stri, 1, x, y);
printf("\n");
SR = SLRGrammer[x][y];
}
else if (SR[1] == '6')
{
for (int i = 0; i < 1; i++)
{
state.pop();
sign.pop();
}
sign.push('F');
r = state.top();
c = sign.top();
x = xfind(r);
y = yfind(c);
print(str, stri);
signstack();
cout << "\t\t";
statestack();
cout << "\t\t" << Grammer[6] << "\t";
;
Action(stri, 1, x, y);
printf("\n");
SR = SLRGrammer[x][y];
}
flag = 2;
}
if (flag == 2)
{
int prow, pcol;
state.push(SR[0]);
prow = xfind(SR[0]);
pcol = yfind(str[stri]);
SR = SLRGrammer[prow][pcol];
if (SR == "0")
{
cout << "\t 输入的字符串不符合SLR文法" << endl;
break;
}
print(str, stri);
signstack();
cout << "\t\t";
statestack();
cout << "\t\t\t";
Action(stri, 0, prow, pcol);
cout << endl;
if (SR[0] == 's')
flag = 0;
else
flag = 1;
}
if (SR == "acc")
{
cout << "\n\t该字符串符合SLR文法。" << endl;
break;
}
}
}
void statestack()
{
stack<char> temp;
string b;
int l = state.size();
for (int i = 0; i < l; i++)
{
char a = state.top();
state.pop();
temp.push(a);
}
for (int i = 0; i < l; i++)
{
char a = temp.top();
b = Convert(a, b);
temp.pop();
state.push(a);
}
cout << std::left << setw(7) << b;
}
void VerbScanner(string str, int i)
{
if (isalpha(str[i]))
{
string lett;
while (isdigit(str[i]) || isalpha(str[i]) || str[i] == '_' || str[i] == '.')
{
lett += str[i];
i++;
}
i--;
if (lett == "id")
strs = strs + 'i';
}
else if (str[i] == '+')
strs = strs + '+';
else if (str[i] == '*')
strs = strs + '*';
else
strs = strs + '#';
}
int xfind(char a)
{
int n;
for (int i = 0; i < 12; i++)
{
if (a == x[i])
{
n = i;
return n;
}
}
return 0;
}
int yfind(char a)
{
int n;
for (int i = 0; i < 9; i++)
{
if (a == y[i])
{
n = i;
return n;
}
}
return 0;
}
string Convert(char a, string b)
{
if (a == 'i')
b = b + "id";
else
b = b + a;
return b;
}
void Action(int i, int flag2, int x, int y)
{
char G = sign.top();
if (flag2 == 0)
cout << "\t"
<< " Action(" << x << "," << str[i] << ")";
else
cout << "\t"
<< " Goto(" << x << "," << G << ")";
}
void signstack()
{
stack<char> temp;
string b;
int l = sign.size();
for (int i = 0; i < l; i++)
{
char a = sign.top();
sign.pop();
temp.push(a);
}
for (int i = 0; i < l; i++)
{
char a = temp.top();
b = Convert(a, b);
temp.pop();
sign.push(a);
}
cout << "\t" << std::left << setw(7) << b;
}
void print(string s, int n)
{
string a;
for (; n < s.length(); n++)
if (s[n] == 'i')
a = a + "i";
else
a = a + s[n];
cout << std::right << setw(10) << a;
}
int main()
{
cout << "请输入需要分析的符号串:";
cin >> str;
strlength = str.length();
for (int i = 0; i < strlength; i++)
{
if (str[i] == ' ' || str[i] == '\n')
continue;
else
VerbScanner(str, i);
}
cout << " 输入串"
<< "\t状态栈"
<< "\t\t符号栈"
<< "\t\t所用产生式"
<< "\t 所做动作" << endl;
cout << " " << str;
str = strs;
cout << " ";
sign.push('#');
state.push('0');
SR = "s5";
signstack();
cout << "\t\t";
statestack();
cout << "\t\t\t";
Action(0, 0, 0, 0);
printf("\n");
SLRScanner(str);
return 0;
}
5 Experimental results
6 Experiment summary
这个实验要求不尽相同,需要改一下,可以与我私信讨论。
7 实验程序以及实验报告下载链接
编译原理实验:包括实验一词法分析器,实验二进制分析,实验三语法分析器,实验四SLR语法分析器等其中含有实验报告,实验代码等等-C++文档类资源-CSDN文库