一、实验题目
根据给定文法编写调试预测分析程序,对任意输入串用预测分析法进行语法分析。
二、实验目的
加深对预测分析法的理解。
三、实验内容
四、实验代码
#include <iostream>
#include <stdio.h>
#include <string>
#include <stack>
using namespace std;
char Vn[] = { 'E','e','T','t','F' }; //定义文法的非终结符,小写字母e表示E’
char Vt[] = { 'i','+','*','(',')','#' };//定义文法的终结符
int LENVt = sizeof(Vt);
void showstack(stack<char> st) //从栈底开始显示栈中的内容
{
int i, j;
char ch[100];
j = st.size();
for (i = 0; i < j; i++)
{
ch[i] = st.top(); //依次获取栈顶元素并赋值给ch数组
st.pop(); //栈顶元素出栈
}
for (i = j - 1; i >= 0; i--)
{
cout << ch[i]; //逆序打印ch数组里的的元素
st.push(ch[i]);//元素逆序入栈
}
}
int find(char c, char array[], int n)//在array数组中查找字符c
{
int i;
int flag = 0;
for (i = 0; i < n; i++)
{
if (c == array[i])
flag = 1;
}
return flag;
}
int location(char c, char array[])//在array数组中查找字符c,若查找成功返回字
//符c的下标
{
int i;
for (i = 0; c != array[i]; i++);
return i;
}
void error()//打印程序出错信息
{
cout << " error!" << endl;
}
void analyse(char Vn[], char Vt[], string M[5][6], string str)
{
int i, j, p, q, h, flag = 1;
char a, X;
stack<char> st;
st.push('#');//‘#’入栈。
st.push(Vn[0]);//Vn[0]入栈
j = 0;
//j指向输入串的指针
h = 1;
a = str[j];
cout << "步骤 " << "分析栈 " << "剩余输入串 " << "所用产生式" << endl;
while (flag == 1)
{
cout << h << " ";//显示步骤
h++;
showstack(st); //显示分析栈中内容
cout << " ";
for (i = j; i < str.size(); i++)
cout << str[i]; //显示剩余字符串
X = st.top();
if (find(X, Vt, LENVt) == 1)
if (X == a) //分析栈的栈顶元素和剩余输入串的第一个元素相较
if (X != '#')
{
cout << " " << X << "匹配" << endl;
st.pop();
a = str[++j];
//读入输入串的下一个字符
}
else
{
cout << " " << "接受!" << endl << endl;
flag = 0;
}
else
{
error();
break;
}
else{
for (p = 0; p < sizeof(Vn); p++){
if(X == Vn[p]){
break;
}
}
//实现下标的转化(非终结符转换为行下标)
for(q = 0; q < LENVt; q++){
if(a == Vt[q]){
break;
}
}
//实现下标的转化(终结符转换为列下标)
string S1("NULL"), S2("null");
if (M[p][q] == S1 || M[p][q] == S2)
//查找二维数组中的产生式
{
error();
break; //对应项为空,则出错
}
else
{
string str0 = M[p][q];
cout << " " << X << "-->" << str0 << endl; //显示相应生式
st.pop();
if (str0 != "$") //$代表“空”字符
for (i = str0.size() - 1; i >= 0; i--){
st.push(str0[i]);
}
//产生式右端逆序进栈
}
}
}
}
int main()
{
string M[5][6] = { "Te","NULL","NULL","Te","NULL","NULL",
"NULL","+Te","NULL","NULL","$","$",
"Ft","NULL","NULL","Ft","NULL","NULL",
"NULL","$","*Ft","NULL","$","$",
"i","NULL","NULL","(E)","NULL","NULL"
};//预测分析表
string str;
int errflag, i;
cout << "文法:E->E+T|T T->T*F|F F->(E)|i" << endl;
cout << "请输入分析串(以#结束):" << endl;
do
{
errflag = 0;
cin >> str;
for (i = 0; i < str.size(); i++)if (!find(str[i], Vt, LENVt))
{
cout << "输入串中包含非终结符" << str[i] << "(输入错误)!" << endl;
errflag = 1;
}
} while (errflag == 1);
analyse(Vn, Vt, M, str);
return 0;
}
五、实验结果
正确识别:
错误识别: