- 实验目的
1.掌握算符优先分析法的基本原理
2.掌握算符优先分析表的构造方法
3.掌握算符优先驱动程序的构造方法
4.加深对算符优先分析法的理解
- 实验内容及要求
已知某算符优先文法中相邻终结符间的优先关系如下表:
+ | - | * | / | i | ( | ) | # | |
+ | ·> | ·> | <· | <· | <· | <· | ·> | ·> |
- | ·> | ·> | <· | <· | <· | <· | ·> | ·> |
* | ·> | ·> | ·> | ·> | <· | <· | ·> | ·> |
/ | ·> | ·> | ·> | ·> | <· | <· | ·> | ·> |
i | ·> | ·> | ·> | ·> | ·> | ·> | ||
( | <· | <· | <· | <· | <· | <· | ≡ | |
) | ·> | ·> | ·> | ·> | ·> | ·> | ||
# | <· | <· | <· | <· | <· | <· | ≡ |
本次实验要求根据算符优先关系表编制一个算符优先分析程序,以便对任意输入的符号串进行分析。要求所编制的算符优先分析程序输出的格式如下:
- 算符优先分析程序,编制人:姓名,学号,班级
(2) 输入一以#结束的符号串(可包括+-*/()i#等符号,如i+i*i#):在此位置输入符号串
(3) 对该输入串的算符优先分析过程输出如下:
步骤 | 栈 | 剩余输入串 | 优先关系 | 动作 |
1 | # | i+i*i# | # <· i | 移进i |
2 | ... | ... | ... | ... |
- 判定结果:输入符号串为合法符号串(或者为非法符号串)。
注意:(1) 在“动作”一列中如果是规约则写明规约串;如果为移进则写明移进的终结符;如分析异常出错则写为“出错”;若成功结束则写为“成功”。
- 在此位置输入符号串为用户自行输入的符号串,其中允许使用运算符(+、-、*、\)、分割符(括号)、字符i,结束符#;如:i+i*i#。
- 如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好)。
注意:此代码为速成品,存在诸多问题,仅供参考
#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <iomanip>
using namespace std;
string inputStr;
stack<char> sta1;//全部字符
stack<char> sta2;//仅含终结符
int i;
int index=1;
string shengYuChuanPrint( string str,int flag ){
string newstr="";
for( int i=flag;i<str.length();i++ ){
newstr+=str[i];
}
return newstr;
}
string stackPrint(stack<char> p){
vector<char> vec;
while( !p.empty() ){
vec.push_back(p.top());
p.pop();
}
string str1="";
for( int i=vec.size()-1;i>=0;--i ){
str1+=vec[i];
}
return str1;
}
int panDuanYouXianJi(char leftChr,char rightChr){//0表示左=右,1表示左>右,-1左<右,2表示空
if( leftChr=='+' ){
if ( rightChr=='+' ){
return 1;
}
else if( rightChr=='-' ){
return 1;
}
else if( rightChr=='*' ){
return -1;
}
else if( rightChr=='/' ){
return -1;
}
else if( rightChr=='i' ){
return -1;
}
else if( rightChr=='(' ){
return -1;
}
else if( rightChr==')' ){
return 1;
}
else if( rightChr=='#' ){
return 1;
}
else{
cout << "error" <<endl;
}
}
else if( leftChr=='-' ){
if ( rightChr=='+' ){
return 1;
}
else if( rightChr=='-' ){
return 1;
}
else if( rightChr=='*' ){
return -1;
}
else if( rightChr=='/' ){
return -1;
}
else if( rightChr=='i' ){
return -1;
}
else if( rightChr=='(' ){
return -1;
}
else if( rightChr==')' ){
return 1;
}
else if( rightChr=='#' ){
return 1;
}
else{
cout << "error" <<endl;
}
}
else if( leftChr=='*' ){
if ( rightChr=='+' ){
return 1;
}
else if( rightChr=='-' ){
return 1;
}
else if( rightChr=='*' ){
return 1;
}
else if( rightChr=='/' ){
return 1;
}
else if( rightChr=='i' ){
return -1;
}
else if( rightChr=='(' ){
return -1;
}
else if( rightChr==')' ){
return 1;
}
else if( rightChr=='#' ){
return 1;
}
else{
cout << "error" <<endl;
}
}
else if( leftChr=='/' ){
if ( rightChr=='+' ){
return 1;
}
else if( rightChr=='-' ){
return 1;
}
else if( rightChr=='*' ){
return 1;
}
else if( rightChr=='/' ){
return 1;
}
else if( rightChr=='i' ){
return -1;
}
else if( rightChr=='(' ){
return -1;
}
else if( rightChr==')' ){
return 1;
}
else if( rightChr=='#' ){
return 1;
}
else{
cout << "error" <<endl;
}
}
else if( leftChr=='i' ){
if ( rightChr=='+' ){
return 1;
}
else if( rightChr=='-' ){
return 1;
}
else if( rightChr=='*' ){
return 1;
}
else if( rightChr=='/' ){
return 1;
}
else if( rightChr==')' ){
return 1;
}
else if( rightChr=='#' ){
return 1;
}
else{
cout << "error" <<endl;
}
}
else if( leftChr=='(' ){
if ( rightChr=='+' ){
return -1;
}
else if( rightChr=='-' ){
return -1;
}
else if( rightChr=='*' ){
return -1;
}
else if( rightChr=='/' ){
return -1;
}
else if( rightChr=='i' ){
return -1;
}
else if( rightChr=='(' ){
return -1;
}
else if( rightChr==')' ){
return 0;
}
else{
cout << "error" <<endl;
}
}
else if( leftChr==')' ){
if ( rightChr=='+' ){
return 1;
}
else if( rightChr=='-' ){
return 1;
}
else if( rightChr=='*' ){
return 1;
}
else if( rightChr=='/' ){
return 1;
}
else if( rightChr==')' ){
return 1;
}
else if( rightChr=='#' ){
return 1;
}
else{
cout << "error" <<endl;
}
}
else if( leftChr=='#' ){
if ( rightChr=='+' ){
return -1;
}
else if( rightChr=='-' ){
return -1;
}
else if( rightChr=='*' ){
return -1;
}
else if( rightChr=='/' ){
return -1;
}
else if( rightChr=='i' ){
return -1;
}
else if( rightChr=='(' ){
return -1;
}
else if( rightChr=='#' ){
return 0;
}
else{
cout << "error" <<endl;
}
}
else{
return 2;
}
}
void guiyue(){
while( panDuanYouXianJi(sta2.top(),inputStr[i])==1 ){
cout << setw(12) <<left<<index
<< setw(12) <<left<< stackPrint(sta1)
<< setw(12) <<left<< shengYuChuanPrint(inputStr,i)
<< sta2.top()<<">"<<inputStr[i]
<< " "
<< "归约"
<< endl;
index++;
if( sta2.top()=='i' ){
sta1.pop();
sta2.pop();
sta1.push('F');
while( panDuanYouXianJi(sta2.top(),inputStr[i])==-1 ){
cout << setw(12) <<left<<index
<< setw(12) <<left<< stackPrint(sta1)
<< setw(12) <<left<< shengYuChuanPrint(inputStr,i)
<< sta2.top()<<"<"<<inputStr[i]
<< " "
<< "移进"<<inputStr[i]
<< endl;
sta1.push(inputStr[i]);
sta2.push(inputStr[i]);
i++;
index++;
}
while( panDuanYouXianJi(sta2.top(),inputStr[i])==0 ){
if( inputStr[i]=='#'&& sta2.top()=='#'){
cout << setw(12) <<left<<index
<< setw(12) <<left<< stackPrint(sta1)
<< setw(12) <<left<< shengYuChuanPrint(inputStr,i)
<< sta2.top()<<"="<<inputStr[i]
<< " "
<< "接受"
<< endl;
sta1.push(inputStr[i]);
sta2.push(inputStr[i]);
i++;
index++;
exit(0);
}
else{
cout << setw(12) <<left<<index
<< setw(12) <<left<< stackPrint(sta1)
<< setw(12) <<left<< shengYuChuanPrint(inputStr,i)
<< sta2.top()<<"="<<inputStr[i]
<< " "
<< "移进"<<inputStr[i]
<< endl;
sta1.push(inputStr[i]);
sta2.push(inputStr[i]);
i++;
index++;
}
}
guiyue();
}
else if( sta2.top()=='+'||sta2.top()=='-'||sta2.top()=='*'||sta2.top()=='/'){
sta2.pop();
sta1.pop();
sta1.pop();
sta1.pop();
sta1.push('F');
while( panDuanYouXianJi(sta2.top(),inputStr[i])==-1 ){
cout << setw(12) <<left<<index
<< setw(12) <<left<< stackPrint(sta1)
<< setw(12) <<left<< shengYuChuanPrint(inputStr,i)
<< sta2.top()<<"<"<<inputStr[i]
<< " "
<< "移进"<<inputStr[i]
<< endl;
sta1.push(inputStr[i]);
sta2.push(inputStr[i]);
i++;
index++;
}
while( panDuanYouXianJi(sta2.top(),inputStr[i])==0 ){
if( inputStr[i]=='#'&& sta2.top()=='#'){
cout << setw(12) <<left<<index
<< setw(12) <<left<< stackPrint(sta1)
<< setw(12) <<left<< shengYuChuanPrint(inputStr,i)
<< sta2.top()<<"="<<inputStr[i]
<< " "
<< "接受"
<< endl;
sta1.push(inputStr[i]);
sta2.push(inputStr[i]);
i++;
index++;
exit(0);
}
else{
cout << setw(12) <<left<<index
<< setw(12) <<left<< stackPrint(sta1)
<< setw(12) <<left<< shengYuChuanPrint(inputStr,i)
<< sta2.top()<<"="<<inputStr[i]
<< " "
<< "移进"<<inputStr[i]
<< endl;
sta1.push(inputStr[i]);
sta2.push(inputStr[i]);
i++;
index++;
}
}
guiyue();
}
else if( sta2.top()=='#' ){
break;
}
}
}
void DFA( string str ){
inputStr=str;
sta1.push('#');
sta2.push('#');
for( i=0;i<inputStr.length(); ){
if( panDuanYouXianJi(sta2.top(),inputStr[i])==-1 ){
cout << setw(12) <<left<<index
<< setw(12) <<left<< stackPrint(sta1)
<< setw(12) <<left<< shengYuChuanPrint(inputStr,i)
<< sta2.top()<<"<"<<inputStr[i]
<< " "
<< "移进"<<inputStr[i]
<< endl;
sta1.push(inputStr[i]);
sta2.push(inputStr[i]);
++i;
index++;
}
else if( panDuanYouXianJi(sta2.top(),inputStr[i])==0 ){
if( inputStr[i]=='#'&& sta2.top()=='#'){
cout << setw(12) <<left<<index
<< setw(12) <<left<< stackPrint(sta1)
<< setw(12) <<left<< shengYuChuanPrint(inputStr,i)
<< sta2.top()<<"="<<inputStr[i]
<< " "
<< "接受"
<< endl;
sta1.push(inputStr[i]);
sta2.push(inputStr[i]);
i++;
index++;
exit(0);
}
else{
cout << setw(12) <<left<<index
<< setw(12) <<left<< stackPrint(sta1)
<< setw(12) <<left<< shengYuChuanPrint(inputStr,i)
<< sta2.top()<<"="<<inputStr[i]
<< " "
<< "移进"<<inputStr[i]
<< endl;
sta1.push(inputStr[i]);
sta2.push(inputStr[i]);
i++;
index++;
}
}
else{
guiyue();
}
}
}
int main()
{
string str;
cout << "编制人:***,软件**,21**********" <<endl;
cout << "请输入目标串" << endl;
cin >> str;
DFA(str);
return 0;
}